Страница 4 из 4 ПерваяПервая 1234
Показано с 31 по 37 из 37

Тема: avr работа с энкодером

  1. #31
    Цитата Сообщение от rx3apf Посмотреть сообщение
    10 nF + ~50 кило встроенного pull-up это маловато (0.5 ms постоянная)
    При таком времени 2000 шагов в секунду. Этого мало с датчика 100 импульсов на оборот? Для ручки настройки трансивера или каких то регулировок в радио? Я не предлагал использовать трещётку в качестве датчиков ЧПУ станка.

    Цитата Сообщение от rx3apf Посмотреть сообщение
    Лично я использую опрос по таймеру
    А я не вижу в этом смысла. Зачем постоянно опрашивать если есть прерывания по ногам и заходить в них только по событию? Есть события по прерыванию- пойти и выполнить. По таймеру быстрее не будет.


  2. #32
    Цитата Сообщение от rx3apf Посмотреть сообщение
    Лично я использую опрос по таймеру (заодно обрабатывающий и прочие события, например, позволяя не вводить лишние ожидания для работы HD44780
    Именно так и я делаю, кроме того, никаких delay в библиотеке HD44780 у меня нет. Вместо delay - опрос валкодера и запись в его буфер. Вот, например фрагмент записи в индикатор:
    LDP=((ch&0b11110000) >>4);
    LCP|=1<<LCD_RS;
    LCP|=1<<LCD_E;
    pauze_1 (30);
    //_delay_ms(1);
    LCP&=~(1<<LCD_E);
    LCP&=~(1<<LCD_RS);
    pauze_1 (30);
    Как видно, delay_ms(1); закоментировано. Вместо него вызов функции pauze_1 (это функция опроса энкодера) c аргументом 30. То есть, задержка в индикаторе осуществляется в течение 30 циклов опроса энкодера.

  3. #33

    Регистрация
    10.09.2017
    Адрес
    Липецк
    Сообщений
    207
    Позывной
    R2GC*
    Почему происходит следующие
    при вращение на убывание отчет от 360 и до нуля и возвращается к 360, при вращении возрастания отчет от 360 и дальше

    #define F_CPU 8000000UL //Частота генерации
    #include <avr/io.h>
    #include <util/delay.h>
    #include "LCD.h" //Библиотека дисплея
    #include "LCD.c"
    #include <avr/interrupt.h>


    /* Дефайны */
    #define F_CPU 8000000UL // тактовая частота 1MHz
    #define PIND_MASK 0b00001100 // Маска для сравнения с PIND


    /* Переменные */
    uint8_t next_state, prev_state, up_state, down_state;
    volatile int angle_antena =0, angle_ang =0; // Передача


    char lcd_angle_antena[3],lcd_angle[3];






    void timer1_init()
    {
    TCCR1A = 0x00;
    TCCR1B |= (1<<CS11); // Тактировать с коэффициентом деления 8
    TCNT1H = 0x00; // Обнуляем счетный регистр старший байт
    TCNT1L = 0x00; // Обнуляем счетный регистр младший байт
    OCR1AH=0x03; // Настраиваем регистр сравнения старший байт
    OCR1AL=0xE8; // Настраиваем регистр сравнения младший байт

    // Разрешаем прерывание таймера по совпадению с OCR1A
    TIMSK |= (1<<OCIE1A);
    }




    static int graydecoder [4][4] =
    {
    {
    +0, /* 00 -> 00 stopped */
    -1, /* 00 -> 01 rotate left */
    +1, /* 00 -> 10 rotate right */
    +0, /* 00 -> 11 invalid combination */
    },
    {
    +1, /* 01 -> 00 rotate right */
    +0, /* 01 -> 01 stopped */
    +0, /* 01 -> 10 invalid combination */
    -1, /* 01 -> 11 rotate left */
    },
    {
    -1, /* 10 -> 00 rotate left */
    +0, /* 10 -> 01 invalid combination */
    +0, /* 10 -> 10 stopped */
    +1, /* 10 -> 11 rotate right */
    },
    {
    +0, /* 11 -> 00 invalid combination */
    +1, /* 11 -> 01 rotate right */
    -1, /* 11 -> 10 rotate left */
    +0, /* 11 -> 11 stopped */
    },
    };


    /* Прерывания */
    ISR (TIMER1_COMPA_vect)
    {
    next_state = (PIND & PIND_MASK) >> 2;
    angle_antena += graydecoder [prev_state] [next_state] * 10;
    prev_state = next_state; // Текущее состояние становится предыдущим
    if (angle_antena < 0)
    angle_antena += 360;
    if (angle_antena > 360)
    angle_antena -= 360;

    TCNT1H=0x00;
    TCNT1L=0x00;


    }


    int main(void)
    {
    int sum_ant = 0;


    DDRD = 0x11110011;
    PORTD = 0b00001110;
    prev_state = (PIND & PIND_MASK) >> 2;
    timer1_init(); // Инициализация таймера1

    LCDinit(); //Иницилизация дисплея



    sei(); // Разрешить глобальные прерывания
    while(1)
    {

    int a;
    cli();
    a = angle_antena;
    sei();

    itoa(a,lcd_angle_ant ena,10);
    itoa(angle_ang,lcd_a ngle,10);

    LCDstring("ANTENNA", 0,1);
    LCDstring("YCT ANTENNA",0,0);

    LCDstring("\xDFY",15 ,0);
    LCDstring("\xDFY",15 ,1);

    LCDstring(lcd_angle_ antena,12,0);
    LCDstring(lcd_angle, 12,1);
    }
    }
    P.S Не сразу, но понял

  4. #34
    Аватар для Genadi Zawidowski
    Регистрация
    22.07.2004
    Адрес
    Санкт-Петербург
    Сообщений
    10,308
    Записей в дневнике
    20
    Позывной
    UA1ARN
    Цитата Сообщение от Radio_Ham Посмотреть сообщение
    if (angle_antena > 360)
    Говорил заменить на
    angle_antena >= 360
    ... Я там глубину сам промерял!

  5. #35

    Регистрация
    10.09.2017
    Адрес
    Липецк
    Сообщений
    207
    Позывной
    R2GC*
    Это из сообщения, перепутал
    P.S Не сразу, но понял

  6. #36
    Цитата Сообщение от Владимир_К Посмотреть сообщение
    Именно так и я делаю
    У меня-то несколько иначе. Подготовленный буфер экрана выгружается по запросу вообще без каких-либо задержек и опросов, по тому же таймерному прерыванию (не по каждому, поскольку прерывания чаще). Т.е. просто заполняю буфер, взвожу флаг загрузки, и пошло=поехало. Энкодер аналогично, поллится непрерывно, счетчик туда-сюда, состояние просто считываем. Кнопки - аналогично. Ну, от задачи зависит, конечно, универсальных решений на все случаи не бывает.

    Цитата Сообщение от ur3ilf Посмотреть сообщение
    Есть события по прерыванию- пойти и выполнить. По таймеру быстрее не будет.
    Нет, конечно, по таймеру не быстрее. Зато таймер автоматически дает элементарные функции мультизадачки, туда и кнопки, и индикацию, и энкодер и все остальное. Я не люблю асинхронные прерывания с непредсказуемым периодом (из-за дребезга он может быть очень малым), и без особой нужды не пользуюсь. Ну, дело вкуса.

  7. #37

    Сообщение

    Цитата Сообщение от rx3apf Посмотреть сообщение
    Я не люблю асинхронные прерывания с непредсказуемым периодом
    Прерывания они разные бывают. Тот же UART. Ещё удобно кнопки на прерывание по АЦП повесить. Там я в прерывании сразу то что в ADC измерилось делю на коэффициент и получаю номер нажатой кнопки. Без всяких сравнений и таблиц. Простым делением. На дисплей причём любой я вывожу только то что изменить нужно. Прерывания существуют чтоб их использовать. С умом можно всё.

Страница 4 из 4 ПерваяПервая 1234

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Работа для радиолюбителей
    от 9cj в разделе Работа для радиолюбителя
    Ответов: 19
    Последнее сообщение: 16.02.2017, 12:32
  2. Работа в эфире
    от Irek в разделе Для начинающих
    Ответов: 604
    Последнее сообщение: 12.08.2016, 14:33
  3. Работа с удовольствием
    от Zoer в разделе Работа для радиолюбителя
    Ответов: 21
    Последнее сообщение: 19.11.2015, 13:51
  4. Работа в цифре IC-775
    от RX0TX в разделе IC-775, IC-775DSP, IC-775DX2
    Ответов: 15
    Последнее сообщение: 13.11.2012, 02:11
  5. работа для радиоинженера
    от ALEKSEY30 в разделе Работа для радиолюбителя
    Ответов: 0
    Последнее сообщение: 09.03.2010, 16:46

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •