Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Захват длинных импульсов.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
AHTOXA
Есть Мега16, измеряю длительность импульсов. Использую модуль захвата на таймере1. Поскольку длительность импульсов может превышать период переполнения таймера1, в таймерном прерывании инкрементирую счётчик:
Код
SIGNAL(SIG_OVERFLOW1)
{
    long_time++;
}


А в прерывании по захвату делаю так:
Код
SIGNAL(SIG_INPUT_CAPTURE1)
{
    static u32 prev_ticks;            // previous edge ticks

    u16 icr = ICR1;
    u32 ticks;
    u32 len;

    // get new edge time (extended to 32 bits with long_time)
    LoWord(ticks) = icr;
    HiWord(ticks) = long_time;

    // calc new length (32 bit too)
    len = ticks - prev_ticks;
    prev_ticks = ticks;

...


Вроде всё должно быть нормально... Ан нет:-) Приоритет таймерного прерывания меньше, чем у прерывания захвата. Поэтому когда событие захвата совпадает с переполнением таймера, то сначала вызывается прерывание по захвату.
При этом ICR уже больше либо равен 0, а long_time - ещё не инкрементирован.
Это конечно случается редко, но случается. Пока частично вышел из положения так:
Код
    LoWord(ticks) = icr;
    HiWord(ticks) = long_time;

    if (ticks < prev_ticks && HiWord(ticks))
        HiWord(ticks)++;


Но это конечно не дело. Да и срабатывает не во всех случаях.

Как бы мне эту проблему победить? :-)
singlskv
Цитата(AHTOXA @ Feb 6 2008, 20:30) *
Как бы мне эту проблему победить? :-)

http://electronix.ru/forum/index.php?showtopic=16900&hl=
AHTOXA
Большое спасибо, как раз то, что нужно.

Вот что вышло в итоге (вдруг кому ещё пригодится):
Код
SIGNAL(SIG_INPUT_CAPTURE1)
{
    static u32 prev_ticks;            // previous edge ticks

    u16 icr = ICR1;
    u32 ticks;
    u32 len;

    // get new edge time (extended to 32 bits with long_time)
    LoWord(ticks) = icr;
    HiWord(ticks) = long_time;
    if (!HiByte(icr) && TIFR & _BV(TOV1))
        HiWord(ticks)++;

    // calc new length (32 bit too)
    len = ticks - prev_ticks;
    prev_ticks = ticks;

...


Флаг прерывания по переполнению таймера сбрасывать не могу, у меня в обработчике прерывания ещё что-то делается.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.