Antokha 0 22 апреля, 2009 Опубликовано 22 апреля, 2009 · Жалоба Про ошибку завтра днём. Компилятор (от IAR 5.11) дома не пашет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 22 апреля, 2009 Опубликовано 22 апреля, 2009 · Жалоба У меня почти такая же проблема: второй раз не обрабатывает прерывание и докучи перезаписывает один из существующих массивов (программа не зависает, если это важно). Обработчик: extern int p[33]; static void PIOA_Handler( void ) { AT91C_BASE_AIC->AIC_IVR; AT91C_BASE_PIOB->PIO_SODR |= ( DDS_P2_MODULATION ); /* PB7 - выв 87 AT91RM9200 */ AT91C_BASE_PIOB->PIO_CODR |= ( DDS_P2_MODULATION ); /* PB7 are output */ AT91C_BASE_AIC->AIC_ICCR |= ( 1UL<<AT91C_ID_IRQ2 );//clear interrupt AT91C_BASE_AIC->AIC_EOICR = 0; } Во-первых как Вам уже сказали нужно оформить правильно функцию прерывания(в зависимости от компилятора). Ну и вообще-то сброс прерывания от PIO делается не записью AIC_ICCR, а чтением PIOx_ISR, при этом нужно иметь в виду что сбросятся все прерывания которые пришли на порт в данный момент времени: When the software reads PIO_ISR, all the interrupts are automatically cleared. This signifies that all the interrupts that are pending when PIO_ISR is read must be handled. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 22 апреля, 2009 Опубликовано 22 апреля, 2009 · Жалоба Ну и вообще-то сброс прерывания от PIO делается не записью AIC_ICCR, а чтением PIOx_ISR... Ну, вот и Вы попались :) Это не прерывание PIO, а вполне честное EXT_IRQ2. А имя PIOA_Handler, похоже, перекочевало "из книжки". Или дано специально для введения в заблуждение желающих помочь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 22 апреля, 2009 Опубликовано 22 апреля, 2009 · Жалоба Ну, вот и Вы попались :) Это не прерывание PIO, а вполне честное EXT_IRQ2. А имя PIOA_Handler, похоже, перекочевало "из книжки". Или дано специально для введения в заблуждение желающих помочь. Да..., хорошее имя..., информативное... :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 123 22 апреля, 2009 Опубликовано 22 апреля, 2009 · Жалоба extern int p[33]; static void PIOA_Handler( void ) { AT91C_BASE_AIC->AIC_IVR; ... __irq_handler: ldr PC,[PC,#-0xF20] ;; IRQ .... AIC_IVR читается дважды. Огласите название книжки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Antokha 0 23 апреля, 2009 Опубликовано 23 апреля, 2009 (изменено) · Жалоба AIC_IVR читается дважды. Огласите название книжки. Это моя отсебятина, начитался pdf-ника. Там сказано регистр считать, а cstartup.s не доглядел. Про ошибку: При использовании функции AT91F_AIC_ConfigureIt объявляя функцию static __arm __irq void PIOA_Handler( void ), получаю ошибку: Error[Pe167]: argument of type "void (__arm __irq *)()" is incompatible with parameter of type "void (*)()" На данный момент сделал так: Инит: AT91C_BASE_PIOA->PIO_PPUDR |= ( DataInput ); AT91C_BASE_PIOA->PIO_ODR = ( DataInput ); AT91C_BASE_PIOA->PIO_BSR = ( DataInput ); AT91C_BASE_AIC->AIC_IDCR = ( 1UL<<AT91C_ID_IRQ2 );//disable interrupt IRQ2 AT91C_BASE_AIC->AIC_SVR[AT91C_ID_IRQ2] |= ( AT91_REG )PIOA_Handler; // set isr AT91C_BASE_AIC->AIC_SMR[AT91C_ID_IRQ2] |= ( AT91C_AIC_SRCTYPE_EXT_HIGH_LEVEL ) | ( 7 ); // prio 7 AT91C_BASE_AIC->AIC_ICCR = ( 1UL<<AT91C_ID_IRQ2 );//clear interrupt AT91C_BASE_AIC->AIC_IECR = ( 1UL<<AT91C_ID_IRQ2 );//enable interrupt Обработка: static __irq __arm void PIOA_Handler( void ) {AT91C_BASE_PIOB->PIO_SODR = ( DDS_P2_MODULATION ); /* PB7 - выв 87 AT91RM9200 */ AT91C_BASE_PIOB->PIO_CODR = ( DDS_P2_MODULATION ); /* PB7 are output */ AT91C_BASE_AIC->AIC_EOICR = 0; } виснет после команды __enable_interrupt(); P.S. Имя обработчика прерывания осталось от нужного когда-то прерывания, извините уж. А книжка - Это Редькин П.П. "32/16-битные микроконтроллеры ARM7 семейства AT91SAM7 Руководство пользователя" Изменено 23 апреля, 2009 пользователем Antokha Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 23 апреля, 2009 Опубликовано 23 апреля, 2009 · Жалоба AT91C_BASE_AIC->AIC_SVR[AT91C_ID_IRQ2] |= ( AT91_REG )PIOA_Handler; // set isr AT91C_BASE_AIC->AIC_SMR[AT91C_ID_IRQ2] |= ( AT91C_AIC_SRCTYPE_EXT_HIGH_LEVEL ) | ( 7 ); // prio 7 Опять |=, да еще и при записи адреса. А книжка - Это Редькин П.П. "32/16-битные микроконтроллеры ARM7 семейства AT91SAM7 Руководство пользователя" В печку ее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SpiritDance 0 28 апреля, 2009 Опубликовано 28 апреля, 2009 · Жалоба Опять |=, да еще и при записи адреса. В печку ее. Вместе с автором. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MiklPolikov 0 20 ноября, 2009 Опубликовано 20 ноября, 2009 · Жалоба AT91SAM7S32 Если читаю IVR вначале прерывания, прерывание один раз происходит и больше не хочет. Почему так ? Если убрать строчку i=*AT91C_AIC_IVR; прерывание происходит много раз как и должно. Спасибо ! __irq void PIOA_interrupt(void) { int i; i=*AT91C_AIC_IVR; i=*AT91C_PIOA_ISR; i=*AT91C_PIOA_PDSR; *AT91C_AIC_EOICR = 0; } void SET_PIOA_interrupt(void) { AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PIOA]=(3<<0)|(0<<5); AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PIOA]=(unsigned long)PIOA_interrupt; AT91C_BASE_AIC->AIC_IECR=(1<<AT91C_ID_PIOA); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dron_Gus 2 20 ноября, 2009 Опубликовано 20 ноября, 2009 · Жалоба Потому что если вы уже попали в обработчик конкретного прерывания, значит обертка на IRQ векторе уже прочитала этот регистр и перешла по соответствующему адресу. Вы же его читаете повторно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться