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

 
 
> Внешние прерывания ATmega128
fatalisk
сообщение Feb 17 2012, 08:07
Сообщение #1





Группа: Новичок
Сообщений: 3
Регистрация: 17-02-12
Пользователь №: 70 314



Всем привет. У меня задача такая: есть меандр с изменяющейся частой и надо замерять время между фронтами. Надо сказать, что в МК я новичок так что прошу не бить). А делаю я так: вешаю сигнал на ногу с внешними прерываниями и по первому фронту обнуляю таймер, а по второму считываю сколько он натикал. И вот тут для меня возникает интересный вопрос! Если пользоваться 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
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 20:45
Рейтинг@Mail.ru


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