реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Захват длинных импульсов., Как победить "Гонки прерываний"?
AHTOXA
сообщение Feb 6 2008, 17:30
Сообщение #1


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Есть Мега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)++;


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

Как бы мне эту проблему победить? :-)


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
singlskv
сообщение Feb 6 2008, 17:43
Сообщение #2


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



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

http://electronix.ru/forum/index.php?showtopic=16900&hl=
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Feb 6 2008, 19:25
Сообщение #3


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Большое спасибо, как раз то, что нужно.

Вот что вышло в итоге (вдруг кому ещё пригодится):
Код
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;

...


Флаг прерывания по переполнению таймера сбрасывать не могу, у меня в обработчике прерывания ещё что-то делается.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 14th July 2025 - 17:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.01386 секунд с 7
ELECTRONIX ©2004-2016