Считать импульс поступающего из коленчатового вала

Тема в разделе "Микроконтроллеры AVR", создана пользователем Yerabdi, 8 мар 2023.

  1. Yerabdi

    Yerabdi Гик

    Добрый день всем,есть атмега64А на ножку PD1 туда поступает сигнал с датчика колена. через компаратор сделал дискретным, нужно расчитать частоту сигнала (1-3кГц).
    Если у кого то опыт или идеи
    Заранее спасибо
     
  2. Ariadna-on-Line

    Ariadna-on-Line Гуру

    А вы не ошибаетесь с диапазоном частот ? Три тысячи оборотов колен-вала в секунду - это что-то запредельное... Электродвигатель крутит в идеале всего-то 50 оборотов в секунду. Думаю даже самолетная турбина столько не дает. А по вопросу - гуглите например "атмега64А частотомер (ATmega64A frequency meter)". Получите миллион ссылок.
     
    Последнее редактирование: 8 мар 2023
    parovoZZ нравится это.
  3. parovoZZ

    parovoZZ Гуру

    Перевести таймер в режим счета внешних импульсов и он сам все посчитает. Останется только раз в секунду снимать показания, а все остальное время СПАТЬ.
     
  4. Yerabdi

    Yerabdi Гик

    спасибо за ответ, получается нужно настроит таймер на внешнее прерывание и при прерывании нужно увеличивать счетчик тем самом читаем каждый импульс а как тогда считать период импульса так как отсутствует два зуба а это влияет на время импульса.как показано на рисунке
    Заранее спасибо
     

    Вложения:

  5. parovoZZ

    parovoZZ Гуру

    не надо никаких прерываний и увеличения счётчика. Счётчик САМ считает импульсы.
     
  6. parovoZZ

    parovoZZ Гуру

    включаешь другой таймер, который считает микросекунды и по прерыванию со счётного входа снимаешь его показания. Это и будет период в микросекундах.
     
  7. Yerabdi

    Yerabdi Гик

    Запускаю таймер Т3 с тактом 4мкс, настроил внешнее прерывание при срабатовани прерывании записываю значения счетчика Т3 TCNT3 тем самом определяю время.можно ли в таком в виде делать расчет микросекундах
     
  8. parovoZZ

    parovoZZ Гуру

  9. parovoZZ

    parovoZZ Гуру

    Значение из буферного регистра (ты же из него читаешь значение счётчика, которое он туда записал по прерыванию?) сдвигаешь влево на два бита. Тем самым происходит умножение на 4 и получишь истинное значение микросекунд.
     
  10. parovoZZ

    parovoZZ Гуру

    upload_2023-3-9_7-12-4.png
     
  11. Yerabdi

    Yerabdi Гик

    atmega64A у меня уже подключен к входу PD1 а там есть внешнее прерывание, на таймера3 другой порт задействован на захват таймера а он уже занять
     
  12. Рокки1945

    Рокки1945 Гуру

    1. Настраиваете 16 битный таймер (если он не занят) на 1 секунду.
    2. Настраиваете прерывание по изменению логического уровня (вход) - в этом таймере (его обработчике) инкрементируете состояние переменной - допустим counter.
    3. Прошла секунда, в обработчике 16 битного таймера забираете значение counter это и будет Ваша частота (Вам же частоту необходимо получить). Там же сбрасываете переменную counter.
    4. И так по кругу.
     
    Последнее редактирование: 9 мар 2023
  13. Yerabdi

    Yerabdi Гик

    он уже занят
     
  14. Рокки1945

    Рокки1945 Гуру

    Заводите в обработчике 16 битного таймера (если заняты и 8 битные таймеры) ещё одну переменную и когда её значение равно 1 секунде (зависит от того на какое время таймер настроен) проводите операции описанные выше (мной). Настройка прерывания для D1 по фронту!
    upload_2023-3-9_9-27-58.png
     
    Последнее редактирование: 9 мар 2023
  15. Yerabdi

    Yerabdi Гик

    можно без внешнего прерывания использовать вот такой код например
    Код (C++):
    static uint8_t prev_in_state = 0xFF;
        static uint8_t Period;
        uint8_t in_state = PIND;              // фиксируем состояние всех входов
        static uint8_t currBit = 2;                  // бит вх PD1 порта
        if ((in_state & currBit) != currBit) { // если на канале низкий уровень
        if ((prev_in_state & currBit) == currBit) { // если в прошлый раз был высокий  
           
             PORTC &=~((1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2)|(1<<PC1)|(1<<PC0));
           
        }
        }
        else if ((prev_in_state & currBit) != currBit) { // вх. импульс закончился ?
        // вычисляем, при каком знач.счетчика micros надо гасить соотв. выход
        result_t3=TCNT3;
        result_t3<<=2;
        rpmcount=result_t3-pred_rpmcount;
        pred_rpmcount=result_t3;
        PORTC |=(1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2)|(1<<PC1)|(1<<PC0);
    }
     
  16. Yerabdi

    Yerabdi Гик

     
  17. parovoZZ

    parovoZZ Гуру

    переделывай
     
  18. parovoZZ

    parovoZZ Гуру

    тогда с точностью можешь попращаться
     
  19. Yerabdi

    Yerabdi Гик

    PD1 это int1 внешнее прерывание,так как таймер3 свободный его значения при прерывание буду записывать на точность как повлияет
     
  20. Yerabdi

    Yerabdi Гик

    Настроил внешнее прерывание на int1 что соответствует PD1.
    При входе на прерывание записываю значения tcnt таймера3 на переменную и делаю сдвиг на 2 как вы советовали.
    С текущего значения счетчика отнимаю сохраненный что соответствует периоду импульса.
    Полученное значения отправил в usart ,
    Подал 4.5кГц в usart показывает 222-226мкс
     
    Рокки1945 нравится это.