|
AT90USB1287 не отрабатывает внешние прерывания, В чем дело? |
|
|
|
Aug 4 2008, 03:41
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Отлаженый проект переношу с MEGA324P на AT90USB1287. После соответствующей коррекции программы перестало отрабатывать нажатия на матричной клавиатуре 4х4. Изменилась схема подключения клавиатуры: раньше COL и RAW подключались к двум разным портам. Теперь занимают один PORTF. И, так как у AT90USB1287 только PORTB имеет PCINT (зачем было так ограничивать функциональность МК ?!!), то выводы RAW через диоды анодами подключены к выводу внешнего прерывания INT6 (PORTE6). Прерывания настраиваю как обычно: Код int main() { // Initialise ACSR = (1<<ACD); // Analog Comparator Disable ................. PORTE = (1<<KEY_INT); // INT6 -> input, pull-up - ON
key_Init(); __enable_interrupt(); // set the Global Interrupt Enable Bit ..................................... ///////////////////////////////////////////
#define ENABLE_INT6 {EIFR |= (1<<INTF6); EIMSK |= (1<<INT6);}// Clear interrupt status flag, Enable external interrupt INT6 #define DISABLE_INT6 EIMSK &= ~(1<<INT6) // Disable external interrupt INT6
void key_Init(void) { /* Init ports */ KEYMATRIX_DDR = 0x0f; // Set row lines to input, Set column lines to output KEYMATRIX_PORT = 0xf0; // Pull row lines high, Drive all column lines low /* Enable external interrupt */ ENABLE_INT6; // Enable pin change interrupt INT6 } Выяснилось, что не вызывается обработчик прерывания INT6. Проверяю по звуковому сигналу BEEP. В симуляторе в AVRSTUDIO тоже прогнал - не вызываются прерывания: ни по низкому уровню, ни по фронтам (заднему и переднему). АЦП (PORTF) не использую. В чем дело? PS. Схему и код выкладываю, чтобы не возникало лишних вопросов.
|
|
|
|
|
 |
Ответов
|
Sep 4 2008, 15:38
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Снова проблема с внешним прерыванием. На этот раз при входе в POWER_DOWN не выходит из него при нажатии на кнопку. Сигнал внешнего прерывания от клавиатурной матрицы 4х4 подключен через аноды диодов на PE6(INT6). Прерывание INT6 настроено на low level. Вот пример кода: Код // Sleep Functions #define SELECT_IDLE SMCR &= ~((1<<SM0)|(1<<SM1)|(1<<SM2)) // Idle mode #define SELECT_ADC SMCR |= (1<<SM0) // ADC Noise Reduction Mode #define SELECT_POWERDOWN SMCR |= (1<<SM1) // Macro to select powerdown sleep mode #define SELECT_POWERSAVE SMCR |= (1<<SM0)|(1<<SM1) // Power Save Mode #define SELECT_STANDBY SMCR |= (1<<SM1)|(1<<SM2) // Standby Mode #define SELECT_EXT_STANDBY SMCR |= (1<<SM0)|(1<<SM1)|(1<<SM2) // Extended Standby Mode
#define SLEEP_ENABLE SMCR |= (1<<SE) // Set the SE (sleep enable) bit #define SLEEP_DISABLE SMCR &= ~(1<<SE) // Clear the SE (sleep enable) bit
int main() { ................................ SLEEP_ENABLE; SELECT_IDLE;
__enable_interrupt(); // set the Global Interrupt Enable Bit TCCR0B = 0x03; // Start System Timer f_clk/64 TIMSK0 |= (1<<TOIE0); // Разрешить прерывания Timer0 по переполнению (OVF) // Период переполнения Timer0 при f_clk=7.3728 Mhz 2.222 ms OS::Run(); }
void TLCD::OnOff(bool On) { if(On) {;} else { ............................................... PORTD |= (1<<SHDN); // Отключить аналоговую периферию //TIMSK0 &= ~(1<<TOIE0); SELECT_POWERDOWN; __sleep(); SELECT_IDLE; //TIMSK0 |= (1<<TOIE0); PORTD &= ~(1<<SHDN); // Включить аналоговую периферию } По команде __sleep() входит в POWER_DOWN. Это подтверждает снижение токопотребления и высокий уровень на SHDN. Но почему не просыпается при нажатии на кнопку, не могу понять.  .. Перепад в "0" на INT6 при нажатии наблюдаю тестером. PS. В errata есть замечание по поводу: 2. High current consumption in sleep mode If a pending interrupt cannot wake the part up from the selected mode, the current consumption will increase during sleep when executing the SLEEP instruction directly after a SEI instruction.
Problem Fix/workaround Before entering sleep, interrupts not used to wake up the part from the sleep mode should be disabled.У меня используется прерывание таймера0. Но запрещение перед входом в режим и разрешение по выходу из режима Power_Down не решает проблему. Какие будут предположения по данной проблеме?
|
|
|
|
|
Sep 5 2008, 07:33
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(alux @ Sep 4 2008, 18:38)  Код int main() { ................................ SLEEP_ENABLE; SELECT_IDLE;
__enable_interrupt(); // set the Global Interrupt Enable Bit TCCR0B = 0x03; // Start System Timer f_clk/64 TIMSK0 |= (1<<TOIE0); // Разрешить прерывания Timer0 по переполнению (OVF) // Период переполнения Timer0 при f_clk=7.3728 Mhz 2.222 ms OS::Run(); } не читал, но осуждаюпролетая над ЧереповцомПробегая мимо интернета нет времени внимательно вчитываться во всю тему, поэтому по теме ответить могу лишь то, что в той старой теме "не всё чисто" было не с прерываниями у 90usb, а с "очиткой". Автором были спутаны INT7 и PCINT7. Не по основной теме: не рекомендую разрешать прерывания до запуска OS::Run() - потребности в этом нет, а что-то левое может и вылезти. Прерывания разрешаются автоматически в конце переключения на первый выполняемый процесс, так как стек каждого процесса инициализируется конструктором таким образом, что в нём сидит образ статусного регистра с установленным битом разрешения прерываний, таким образом при первом переключении на процесс "восстанавливается" SREG.I == 1 и прерывания разрешены.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 5 2008, 09:12
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(ReAl @ Sep 5 2008, 10:33)  не рекомендую разрешать прерывания до запуска OS::Run() - потребности в этом нет, а что-то левое может и вылезти. Этот вопрос я уже поднимал ранее:Потребность иногда есть, например, когда необходимо проинициализировать АЦП, а SPI настроен по прерыванию: Код ......................... __enable_interrupt(); // set the Global Interrupt Enable Bit ad7799_Init(); TCCR0B = 0x03; // Start System Timer f_clk/64 TIMSK0 |= (1<<TOIE0); // Разрешить прерывания Timer0 по переполнению (OVF) // Период переполнения Timer0 при f_clk=7.3728 Mhz 2.222 ms OS::Run(); // при f_clk=20 Mhz 0.8192 ms } Получается сразу после ad7799_Init(); до запуска ОС нужно сделать __disable_interrupt(); ? Почему из POWER_DOWN не вызывается обработчик внешнего прерывания INT6 , настроенный по низкому уровню? Вызов ISR контролирую по изменению вывода BEEP: Код #pragma vector=INT6_vect OS_INTERRUPT void INT6_ISR() { OS::TISRW_SS ISRW;
DISABLE_INT6; // Prevent further external interrupts
Int6.SignalISR(); PORTC |= (1<<BEEP); }
|
|
|
|
Сообщений в этой теме
alux AT90USB1287 не отрабатывает внешние прерывания Aug 4 2008, 03:41 alux Глас вопиющего в пустыне... У меня проект останови... Aug 5 2008, 03:17 SysRq Фьюз JTAGEN проверьте. Если включен JTAG (можно и ... Aug 5 2008, 09:48 alux Цитата(SysRq @ Aug 5 2008, 12:48) Фьюз JT... Aug 5 2008, 10:47 GDI Проверьте в симуляторе какие значения в регистры п... Aug 5 2008, 10:59 alux По-умолчанию, при разрешении соответствующего внеш... Aug 5 2008, 12:34 GDI В вшем коде не видно настройки DDRE, надеюсь на вх... Aug 5 2008, 12:44 alux Цитата(GDI @ Aug 5 2008, 15:44) В вшем ко... Aug 5 2008, 13:40 GDI Цитатау этого камня не правильно пронумерованы век... Aug 5 2008, 13:47 sKWO alux, прочитайте ответ Александра Редчука на телес... Aug 5 2008, 14:47 alux Цитата(sKWO @ Aug 5 2008, 17:47) прочитай... Aug 5 2008, 15:42  sKWO Цитата(alux @ Aug 5 2008, 18:42) Этот пос... Aug 6 2008, 15:02 SysRq А можно понтересоваться (в целях повышения образов... Aug 6 2008, 14:38 alux Цитата(SysRq @ Aug 6 2008, 17:38) у вас О... Aug 6 2008, 15:43  SysRq Цитата(alux @ Aug 6 2008, 19:43) Получает... Aug 6 2008, 23:20 Т.Достоевский По уровню? То-есть если на порту INTx = 0, то заст... Aug 7 2008, 00:44 alux Цитата(Т.Достоевский @ Aug 7 2008, 03:44)... Aug 7 2008, 05:00  SysRq Цитата(alux @ Aug 7 2008, 09:00) Сделал т... Aug 7 2008, 05:53   alux Проверить проект смогу вечером. Пока могу предполо... Aug 7 2008, 09:01    sKWO Цитата(alux @ Aug 7 2008, 12:01) Проверит... Aug 7 2008, 10:12     alux Цитата(sKWO @ Aug 7 2008, 13:12) не молов... Aug 7 2008, 10:16 SysRq Цитата(alux @ Aug 7 2008, 14:16) ...раско... Aug 7 2008, 14:08 alux Цитата(SysRq @ Aug 7 2008, 17:08) На этом... Aug 7 2008, 15:25 SysRq А в железе? Aug 7 2008, 18:17 alux Цитата(SysRq @ Aug 7 2008, 21:17) А в жел... Aug 7 2008, 19:25 alux Обработчик внешнего прерывания не вызывается из-за... Aug 8 2008, 18:58   ReAl Цитата(alux @ Sep 5 2008, 12:12) Потребно... Sep 6 2008, 12:53 SasaVitebsk Надеюсь вы учли, что просыпаться только Only ... Sep 4 2008, 18:55 alux Цитата(SasaVitebsk @ Sep 4 2008, 21:55) Н... Sep 5 2008, 06:12 alux Второй раз наступаю на одни и те же грабли:
Кодvo... Sep 6 2008, 08:33
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|