|
Приоритет прерываний, и прерывание прерываний |
|
|
|
 |
Ответов
(30 - 44)
|
Aug 30 2008, 08:31
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Дам пару советов. Во первых, код написать таким образом (правда, это для IAR, но для гнуся все остается в силе) Код #pragma vector=INT0_vect __interrupt void INT0_proc(void) { unsigned char t=pos-1; if (PIND&0x01) t+=2; pos=t; }
#pragma vector=TIMER1_OVF_vect __interrupt void T1_proc(void) { unsigned char t; __enable_interrupt(); t=PORTC; t<<=1; if (PORTC&0x08) t=1; PORTC=t; TCNT1 = 0x10000 - 62500 / Frq; } Общая идея в том, чтобы не работать с глобальными переменными, а работать с регистровыми. Например, обработчик INT0 после переделки занимает 27 тактов со всеми входами и выходами (это результат IAR'а). Далее, если Вы боитесь, что в прерывании от переполнения Timer1 возможен второй вход - поставьте его в режим Clear On Compare Match и в OCR1 занесите 1. В результате, после переполнения, произойдет прерывание, а таймер дальше не пойдет, его все время Compare Match будет сбрасывать. Как только Вы занесете в таймер значение больше 1 - опять начнется отсчет.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Aug 30 2008, 08:42
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(PhX @ Aug 30 2008, 09:26)  Как ли это делается в WinAVR? Позволю себе поправить: Код ISR(TIMER1_OVF_vect) { uint8_t TIMSK_save = TIMSK; TIMSK = 0; // Что-то сюда еще наверное нужно вставить чтобы аналогично запретить остальные прерывания кроме INT0
sei(); // Разрешаем прерывания // первым делом обновляем счетчик таймера. Если мы сделаем это позже, // то возможна ситуация, когда при обновлении счетчик "перепрыгнет" нулевое значение и прерывание будет потеряно. // с момента возникновения прерывания таймер мог уже что-то насчитать, поэтому для // увеличения точности не присвоение, а сложение TCNT1 += 0x10000 - 62500 / Frq; if (!(PORTC & (1 << 3))) // это компилится в одну инструкцию sbis вместо in, and, jne PORTC<<=1; else PORTC = 0x01; cli(); TIMSK = TIMSK_save; }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Aug 30 2008, 09:27
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата if (!(PORTC & (1 << 3))) // это компилится в одну инструкцию sbis вместо in, and, jne PORTC<<=1; else PORTC = 0x01; Вот не согласен. Есть же else  Так что лучше написать так, как у меня (у меня можно проверить и регистр, но IAR почему-то не хочет компилить SBRS, хотя SBIS изготавливает влет). Цитата TCNT1 += 0x10000 - 62500 / Frq; Это надо бы делать до SEI. А вообще данное место зависит от необходимой точности частоты прерываний от таймера. Точно будет только при использовании Clear On Compare Match и прерывания по Compare.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Aug 30 2008, 09:45
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(Сергей Борщ @ Aug 30 2008, 12:38)  Нет. Эта операция довольно долгая (16-битный таймер как-никак), до sei() она будет увеличивать латентность. А в этом месте прерывания от таймеров остались запрещены, поэтому делать ее в этом месте вполне безопасно. Если можно вообще говорить о безопасности при доступе к 16-битному работающему таймеру на 8-битной машине. Насчет Clear On Compare Match абсолютно согласен. Опасения конечно есть, но при чтении с 16-ти битных регистров у АВР предусмотрен временный регистр. При чтении сначала младший байт помещается в тмп, после этого производится чтение. ИАР это делает правильно.
Сообщение отредактировал sKWO - Aug 30 2008, 09:48
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Aug 30 2008, 10:14
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата оэтому делать ее в этом месте вполне безопасно. Не, я про то, что если возникнет прерывание между чтением TCNT1 и установкой - будет уж очень большая погрешность. Тогда уж лучше так: Код __interrupt void T1_proc(void) { unsigned char t; __enable_interrupt(); t=PORTC; __disable_interrupt(); TCNT1+=_ADJUST_T1_+0x10000 - 62500 / Frq; __enable_interrupt(); t<<=1; if (PORTC&0x08) t=1; PORTC=t; __disable_interrupt(); TCNT1 = 0x10000 - 62500 / Frq; } _ADJUST_T1_ - это поправочная константа на время между чтением TCNT1 и записью. Ее надо выбрать по результирующему коду обработчика. А чтобы не бояться повторного входа, установить заранее OCR1 на число меньшее, чем заносится в TCNT1 (или, например, неплохо будет занести туда время, которое допустимо между вызовами прерывания). По флагу OCF1 можно ориентироваться, что произошло гуано в генерации частоты. На самом деле это хорошо работает, если прескаллер равен 1. Кстати, я надеюсь у автора Frq - константа? Если нет, то расчет значения для занесения в таймер надо убирать из прерывания.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Aug 30 2008, 17:52
|
Частый гость
 
Группа: Новичок
Сообщений: 83
Регистрация: 25-08-08
Пользователь №: 39 801

|
Цитата(PhX @ Aug 28 2008, 20:53)  Есть три обработчика прерываний: От Timer1 от INT0 и допустим от Timer2 Прерывание от INT0 наиважнейшее не обработается вовремя расстрел (считает импульсы энкодера максимальная частота 250 КГц). Вопрос как сделать так, чтобы это прерывание имело наивысший приоритет и прерывало обработчики остальных прерываний? Компилятор WinAVR. Дык в ATmega-х прерывание INT0 и так "наиважнейшее" поэтому его вектор стоит на самом 1-м месте. Просто при входе в обработчики таймерных прерываний делайте глобальное разрешение прерываний командой SEI и проектируйте систему так, чтобы не было вложенных обработчиков( ну когда обработчик не успел ещё одно прерывание отработать, а уже наступило следующее).. А если вложенные обработчики Вас не пугают и Вы анализируете флаг повторной входимости, тогда вообще Ноу Проблем
Сообщение отредактировал Боинг749 - Aug 30 2008, 17:57
|
|
|
|
|
Aug 30 2008, 21:08
|
Частый гость
 
Группа: Новичок
Сообщений: 83
Регистрация: 25-08-08
Пользователь №: 39 801

|
Цитата(defunct @ Aug 31 2008, 00:59)  выбросить все манипуляции с TCNT. Работать нужно только с OCR, и пользовать CTC режим. А причём тут это? Какое отношение Ваши реплики имеют к вопросу темы? НАПОМИНАЮ, вопрос темы звучал так: Цитата(PhX @ Aug 28 2008, 20:53)  как сделать так, чтобы это прерывание <INT0>{прим.Боинг749} имело наивысший приоритет и прерывало обработчики остальных прерываний? И КОНКРЕТНО на этот вопрос я ответил чуть выше
Сообщение отредактировал Боинг749 - Aug 30 2008, 21:13
|
|
|
|
|
Aug 31 2008, 06:43
|

Местный
  
Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249

|
Цитата(defunct @ Aug 31 2008, 01:59)  выбросить все манипуляции с TCNT. Работать нужно только с OCR, и пользовать CTC режим. Абсолютно согласен. Уже попробывал моргание светодиодом.  Просто с AVR знаком 3-й день не знаю всех особенностей. Текущий проект удалось упростить до использования 2-х прерываний, так что проблем быть не должно. А вообще, с теоретической точки зрения, интересный вопрос, для более сложных проектов весьма актуальный.
--------------------
Если все, то не я...
|
|
|
|
|
Aug 31 2008, 07:40
|
Частый гость
 
Группа: Новичок
Сообщений: 83
Регистрация: 25-08-08
Пользователь №: 39 801

|
Цитата(defunct @ Aug 31 2008, 11:34)  Прямое - минимизация латентности обработчиков прерываний. Почитайте весь топик. Дык я же ответил: просто надо сразу при входе в обработчик таймера разрешать прерывания командой SEI. Причём тут режимы работы таймера?
|
|
|
|
|
Aug 31 2008, 14:14
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата с какого момента вы были наделены правами и обязанностями модератора? Свят-свят... Только дохтура нам модератором не хватало... Кстати, а что правила говорят о повторной регистрации? Явно ж клиент на бан. Пардон за офтоп.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|