Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Внешние прерывания ATmega128
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
fatalisk
Всем привет. У меня задача такая: есть меандр с изменяющейся частой и надо замерять время между фронтами. Надо сказать, что в МК я новичок так что прошу не бить). А делаю я так: вешаю сигнал на ногу с внешними прерываниями и по первому фронту обнуляю таймер, а по второму считываю сколько он натикал. И вот тут для меня возникает интересный вопрос! Если пользоваться INT7:4, то все работает замечательно, а если INT3:0, то все...приплыли (все время разные интервалы, далее описано почему). Что было сделано: вешал датчик то на INT7:4 то на INT3:0 (в первом случае все работает, во втором нет), проверил настройку прерывания (генерируется оно именно по фронту, не по уровню). Далее сделал так: закодил чтоб при первом входе в обработчик (на прерываниях INT3:0)на какой-нибудь свободной ноге выставлялась 1, а при втором входе выставлялся 0.
И вот что интересное обнаружилось на осциллографе: после прихода фронта с датчика наблюдается задержка с выставлением 1 на свободной ноге, далее лучше, эта задержка УВЕЛИЧИВАЕТСЯ, пока не "догонит" след фронт, а затем снова восстанавливается на небольшую задержку и снова начинает увеличиваться.

Мануал по настройке внешних прерываний говорит след:
для INT7:4 - Нарастающий фронт, выявленный по двум выборкам на INTn, генерирует запрос на прерывание.
для INT3:0 - Нарастающий фронт на INTn генерирует асинхронно запрос на прерывание
В чем разница? И может ли это как раз влиять на результат? Что-то подробнее про "этот" асинхронный запрос я не нашел чтоб понять суть.
И вот тут возникает вопрос: задержка в срабатывании прерывания как-то связана с типами этих прерываний? В момент задержки после прихода фронта где висит мк и что делает?

Код который работает как надо:
Код
ISR(INT7_vect)
{
     if(edge_counter ==1)
     {
          value_timer = TCNT0;
          edge_counter = 0;
     }
     else
     {
          TCNT0 = 0x00;
          edge_counter++;
     }
}
int main(void)
{
//ноги на которых внешние прерывания настроены на вход с подтяжкой  
   DDRC  = 0x00;
   PORTC = 0xFF;
   DDRE = 0x00;
   PORTE = 0xFF;

   DDRD = 0b11000000;
   PORTD = 0xFF;

//=======================
   TCCR0 = 0b00000111; //деление таймера0 на 1024
   //TCCR2 = 0b00000101;

//========================
   TCCR1B = 0b00000011; //делитель на256 16 битного таймера1
   TIMSK = (1<<TOIE1);   //прерывание по переполнению

//========================
  
   EICRA = 0x00;
   EICRB = 0xC0; //настройка прерывания INT7 по фронту
   EIMSK = 0x80; //разрешение прерывания от INT7

   TWI_Master_Initialise();
   _SEI();
        
   while(1)
   {
          //вывод на экран
   }


так не работает:
Код
ISR(INT3_vect)
{
     if(edge_counter ==1)
     {
          value_timer = TCNT0;
          edge_counter = 0;
     }
     else
     {
          TCNT0 = 0x00;
          edge_counter++;
     }
}
int main(void)
{
//ноги на которых внешние прерывания настроены на вход с подтяжкой  
   DDRC  = 0x00;
   PORTC = 0xFF;
   DDRE = 0x00;
   PORTE = 0xFF;

   DDRD = 0b11000000;
   PORTD = 0xFF;

//=======================
   TCCR0 = 0b00000111; //деление таймера0 на 1024
   //TCCR2 = 0b00000101;

//========================
   TCCR1B = 0b00000011; //делитель на256 16 битного таймера1
   TIMSK = (1<<TOIE1);   //прерывание по переполнению

//========================
  
   EICRA = 0b11000000; //настройка прерывания INT3 по фронту
   EICRB = 0x00;
   EIMSK = 0b00001000; //разрешение прерывания от INT3

   TWI_Master_Initialise();
   _SEI();
        
   while(1)
   {
          //вывод на экран
   }

отличия в пару цифр! мк - ATmega128 8MHz внутренним RC
kovigor
Цитата(fatalisk @ Feb 17 2012, 12:07) *
У меня задача такая: есть меандр с изменяющейся частотой и надо замерять время между фронтами.


Насколько я помню, для этого гораздо лучше использовать таймер в режиме Capture ...
fatalisk
Цитата(kovigor @ Feb 17 2012, 12:47) *
Насколько я помню, для этого гораздо лучше использовать таймер в режиме Capture ...

а если датчиков будет больше одного? У 128ой для этого режима только две ножки.
kovigor
Цитата(fatalisk @ Feb 17 2012, 12:49) *
а если датчиков будет больше одного? У 128ой для этого режима только две ножки.


Тогда решиаь задачу, например, путем использования внешних прерываний. Или подобрать другой МК, если этот метод не подходит.

P.S. Все равно ваш метод будет давать погрешность. Необходимо четко фиксировать состояния счетчиков в моменты фронтов и спадов, и фиксировать аппаратно, если вам нужна точность. А как это сделать без Capture, я себе не представляю ...
fatalisk
Цитата(kovigor @ Feb 17 2012, 12:54) *
Тогда решиаь задачу, например, путем использования внешних прерываний. Или подобрать другой МК, если этот метод не подходит.

P.S. Все равно ваш метод будет давать погрешность. Необходимо четко фиксировать состояния счетчиков в моменты фронтов и спадов, и фиксировать аппаратно, если вам нужна точность. А как это сделать без Capture, я себе не представляю ...

INT7:4 справляются с задачей на отлично. В точность измерения они укладываются только в путь. Вы знаете в чем может быть отличие работы у INT3:0?? Почему они входят в обработчик спустя время причем непостоянное.
kovigor
Цитата(fatalisk @ Feb 17 2012, 13:00) *
INT7:4 справляются с задачей на отлично. В точность измерения они укладываются только в путь. Вы знаете в чем может быть отличие работы у INT3:0?? Почему они входят в обработчик спустя время причем непостоянное.


Сделайте тестовый проект - выкиньте из программы все, кроме обработчиков от Int7 и Int0. Тоже так будет ? Мало ли что может задерживать запуск обработчика ? Например, вы сами же блокируете прерывания. Или в данный момент выполняется более приоритетный (или просто другой) обработчик ...
MKdemiurg
Всё просто.

0-3 срабатывает от асинхронно от внутренней логики.
4-7 по результатам выборки, 1 периода синхронизации.

http://www.gaw.ru/html.cgi/txt/doc/micros/avr/arh128/8.htm

Читаем

Таблица 49 – Характеристики асинхронного внешнего прерыванияОбозначение Параметр Мин. Типично Макс. Ед.изм.
tINT Минимальная длительность импульса для генерации асинхронного прерывания 50 нс

Т.е. вам в любом случае ждать 50нс( мне кажется не особо нормируемая величина). Вот вам и задержка.

Зато 0-3 удобно использовать для выхода из режимов глубокого сна. sm.gif

**********
ЗЫ Хотя у вас там и таймер( маловероятно) и TWI( где могут запрещатся прерывания на момент передачи)...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.