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

 
 
 
Reply to this topicStart new topic
> Внешние прерывания 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
kovigor
сообщение Feb 17 2012, 08:47
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(fatalisk @ Feb 17 2012, 12:07) *
У меня задача такая: есть меандр с изменяющейся частотой и надо замерять время между фронтами.


Насколько я помню, для этого гораздо лучше использовать таймер в режиме Capture ...
Go to the top of the page
 
+Quote Post
fatalisk
сообщение Feb 17 2012, 08:49
Сообщение #3





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



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

а если датчиков будет больше одного? У 128ой для этого режима только две ножки.
Go to the top of the page
 
+Quote Post
kovigor
сообщение Feb 17 2012, 08:54
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



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


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

P.S. Все равно ваш метод будет давать погрешность. Необходимо четко фиксировать состояния счетчиков в моменты фронтов и спадов, и фиксировать аппаратно, если вам нужна точность. А как это сделать без Capture, я себе не представляю ...
Go to the top of the page
 
+Quote Post
fatalisk
сообщение Feb 17 2012, 09:00
Сообщение #5





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



Цитата(kovigor @ Feb 17 2012, 12:54) *
Тогда решиаь задачу, например, путем использования внешних прерываний. Или подобрать другой МК, если этот метод не подходит.

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

INT7:4 справляются с задачей на отлично. В точность измерения они укладываются только в путь. Вы знаете в чем может быть отличие работы у INT3:0?? Почему они входят в обработчик спустя время причем непостоянное.
Go to the top of the page
 
+Quote Post
kovigor
сообщение Feb 17 2012, 09:10
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



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


Сделайте тестовый проект - выкиньте из программы все, кроме обработчиков от Int7 и Int0. Тоже так будет ? Мало ли что может задерживать запуск обработчика ? Например, вы сами же блокируете прерывания. Или в данный момент выполняется более приоритетный (или просто другой) обработчик ...
Go to the top of the page
 
+Quote Post
MKdemiurg
сообщение Feb 21 2012, 19:46
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 624
Регистрация: 15-06-10
Из: Россия
Пользователь №: 57 939



Всё просто.

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( где могут запрещатся прерывания на момент передачи)...

Сообщение отредактировал MKdemiurg - Feb 21 2012, 20:49
Go to the top of the page
 
+Quote Post

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

 


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


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