|
Прерывание от таймера в AT91SAM7X256 |
|
|
|
May 22 2008, 05:35
|
Частый гость
 
Группа: Участник
Сообщений: 141
Регистрация: 10-02-08
Из: Екб
Пользователь №: 34 906

|
Используем FreeRTOS. ВОзникла необходимость использования таймера. Вроде просто так таймер запускается и работает, а вот прерывания не обрабатывает. Я подозреваю, что функцию обработки прерывания нельзя объявлять, как обычную функцию. Наверное, надо прописывать ещё вектор прерывания от таймера где-то там. В том и проблема, что не очень хорошо разбираюсь во всяких там секциях памяти, размещении векторов и т. д (по крайней мере в этом контроллере). Как бы это попроще организовать??? ТЕкст (кстати стандартный) приведен ниже: //ф-ия обработки прерывания void timer1_c_irq_handler(void) { AT91PS_TC TC_pt = AT91C_BASE_TC1; unsigned int dummy; //* Acknowledge interrupt status dummy = TC_pt->TC_SR; //* Suppress warning variable "dummy" was set but never used dummy = dummy; count_timer0_interrupt++; vParTestToggleLED( 2 ); } void AT91F_TC_Open ( AT91PS_TC TC_pt, unsigned int Mode, unsigned int TimerId) { unsigned int dummy; AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1<< TimerId ) ; AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_TC1); TC_pt->TC_CCR = AT91C_TC_CLKDIS ; TC_pt->TC_IDR = 0xFFFFFFFF ; dummy = TC_pt->TC_SR; TC_pt->TC_CMR = Mode ; TC_pt->TC_CCR = AT91C_TC_CLKEN ; } void timer_init ( void ) { unsigned int oldHandler; unsigned int mask ; AT91S_AIC *pAIC = AT91C_BASE_AIC; AT91S_TC *pTMR = AT91C_BASE_TC1; //init the timer interrupt counter count_timer0_interrupt=0; count_timer1_interrupt=0; //* Open timer1 AT91F_TC_Open(AT91C_BASE_TC1,TC_CLKS_MCK128,AT91C_ID_TC1); //* Open Timer 1 interrupt AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_TC1, TIMER1_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, timer1_c_irq_handler); AT91C_BASE_TC1->TC_IER = AT91C_TC_CPCS; // IRQ enable CPC AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC1); //* Start timer1 //AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG ; } P.S. Знаю, что подобные посты уже были, но хотелось бы ещё раз остановиться на данной проблеме! Спасибо заранее за ответы.
|
|
|
|
|
 |
Ответов
|
May 27 2008, 17:31
|
Частый гость
 
Группа: Участник
Сообщений: 141
Регистрация: 10-02-08
Из: Екб
Пользователь №: 34 906

|
Цитата(aaarrr @ May 26 2008, 16:03)  И Вам спасибо за отсутствие AT91F_ в исходниках  Уважаемый aaarrr! Для реализации прерываний USART можно пользоваться обработчиком прерывания, аналогичным обработчику таймера, т е например uart_Wrapper и uart_Handler (как у меня было с таймером)? И ещё, имеет ли разницу, буду я использовать DBGU или же USART? Когда конфигурирую как DBGU, хотя бы посылается и принимается байт по RS232. USART же упорно не хочет работать... P.S. простите за беспокойство ещё раз)
|
|
|
|
|
May 27 2008, 18:38
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(ZAA @ May 27 2008, 21:31)  Для реализации прерываний USART можно пользоваться обработчиком прерывания, аналогичным обработчику таймера, т е например uart_Wrapper и uart_Handler (как у меня было с таймером)? Можно так. Можно и просто оформить прерывание как Код void isr_handler( void ) __attribute__((interrupt("IRQ"))) { ... } если не собираетесь из прерывания вызывать шедулер. Цитата(ZAA @ May 27 2008, 21:31)  И ещё, имеет ли разницу, буду я использовать DBGU или же USART? Когда конфигурирую как DBGU, хотя бы посылается и принимается байт по RS232. USART же упорно не хочет работать...  Разницы нет практически никакой. Проверьте, разрешено ли тактирование.
|
|
|
|
|
May 28 2008, 17:40
|
Частый гость
 
Группа: Участник
Сообщений: 141
Регистрация: 10-02-08
Из: Екб
Пользователь №: 34 906

|
Цитата(aaarrr @ May 27 2008, 21:38)  Разницы нет практически никакой. Проверьте, разрешено ли тактирование. Очень неудобно беспокоить Вас снова, но снова столкнулась с проблемой, вернее, с проблемами. Все те же прерывания от уарта. Пересмотрела кучу постов на эту тему, вроде все прозрачно. Надо генерировать прерывания по приему байта. Тут и начинаются косяки. Если не затруднит, не могли бы Вы помочь мне еще раз 1) Можно ли одновременно использовать и USART0, и DBGU? То есть например, прерывание конфигурировать от USART0, а посылать байт из контроллера через DBGU? 2) Почему-то срабатывают прерывание (но опять же 1 раз - ещё одна проблема) по передаче байта, по флагу RXBUFF, но не по RXRDY? На какой вообще надо настраивать? 3) Снова та же проблема - прерывание выполняется 1 раз 4) программа переходит в обработчик без какого-либо опроса буфера приемника, т е как только что-то пришло в Rx, должно произойти прерывание? 5) Обязательно ли использовать PDC? Вот мои тексты: Код void init_uart(void) { AT91C_BASE_PIOA->PIO_PDR = AT91C_PIO_PA1 | AT91C_PIO_PA0; AT91C_BASE_SYS->AIC_SVR[AT91C_ID_US0] = (unsigned int) vUART_ISR_Wrapper; //растановка приоритета прерывания AT91C_BASE_SYS->AIC_SMR[AT91C_ID_US0] = 0x63; // SRCTYPE=1, PRIOR=3. USART 0 interrupt positive edge-triggered at prio 3 //0x02; AT91C_BASE_SYS->AIC_IECR = (1<<AT91C_ID_US0); AT91C_BASE_SYS->AIC_ICCR = (1<<AT91C_ID_US0);
*AT91C_US0_BRGR = 625; *AT91C_US0_MR = 0x000808C0; // Normal mode, 1 stop bit, no parity, async mode, 8 bits, MCK. *AT91C_US0_IDR = 0xffffffff; // Disable all USART interrupts *AT91C_US0_IER = AT91C_US_ENDRX; //| AT91C_US_RXBUFF;//AT91C_US_TXRDY | AT91C_US_RXRDY;
*AT91C_US0_CR = AT91C_US_RXDIS | AT91C_US_TXDIS; *AT91C_US0_CR = AT91C_US_RXEN | AT91C_US_TXEN; *AT91C_US0_CR = AT91C_US_RSTRX | AT91C_US_RSTTX |AT91C_US_RSTSTA; *AT91C_PMC_PCER = (1 << AT91C_ID_US0); } Здесь собственно говоря смущает AT91C_BASE_SYS. Может надо настраивать как AT91C_BASE_AIC (пример настройки кстати взят из одного из постов)? Обработчик прерывания Код void vUART_ISR_Handler( void ) { int i; char Tmp = *AT91C_US0_CSR; char *Data; char buffer[5]; unsigned int status; status = AT91C_BASE_US0->US_CSR; vParTestToggleLED(Data); count_uart_interrupt++; AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTSTA;//US0->US_CR = AT91C_US_RSTSTA; AT91C_BASE_US0->US_CR = AT91C_US_RSTRX;//US0->US_CR = AT91C_US_RSTRX; AT91C_BASE_US0->US_CR = AT91C_US_RXEN; *AT91C_US0_IER = AT91C_US_ENDRX; AT91C_BASE_AIC->AIC_EOICR = 0; // Signal end of interrupt } Вроде и регистр статуса считываю, и в EOICR пишу в конце. Уже и прерывание снова объявила..Ну ни в какую((( Код void vUART_ISR_Wrapper( void ) { /* Save the context of the interrupted task. */ portSAVE_CONTEXT();
/* Call the handler itself. This must be a separate function as it uses the stack. */ vParTestToggleLED(3); vUART_ISR_Handler(); /* Restore the context of the task that is going to execute next. This might not be the same as the originally interrupted task.*/ portRESTORE_CONTEXT(); } Понимаю, что вопросы стандартные и глупые, но уже погрязла в куче информации и в доках, и в форуме, а времени остаётся все меньше и меньше  Помогите советом ещё раз, плз!!!
|
|
|
|
|
May 28 2008, 18:21
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(ZAA @ May 28 2008, 21:40)  1) Можно ли одновременно использовать и USART0, и DBGU? То есть например, прерывание конфигурировать от USART0, а посылать байт из контроллера через DBGU? Если скорости совпадают, то в отладочных целях можно. Цитата(ZAA @ May 28 2008, 21:40)  2) Почему-то срабатывают прерывание (но опять же 1 раз - ещё одна проблема) по передаче байта, по флагу RXBUFF, но не по RXRDY? На какой вообще надо настраивать? RXBUFF будет установлен, если используется PDC. Без PDC нужно настраивать на RXRDY. Цитата(ZAA @ May 28 2008, 21:40)  3) Снова та же проблема - прерывание выполняется 1 раз Возможно, из-за того, что прерывание настроено как edge sensetive. Цитата(ZAA @ May 28 2008, 21:40)  4) программа переходит в обработчик без какого-либо опроса буфера приемника, т е как только что-то пришло в Rx, должно произойти прерывание? Да. Цитата(ZAA @ May 28 2008, 21:40)  5) Обязательно ли использовать PDC? Нет. Цитата(ZAA @ May 28 2008, 21:40)  Вот мои тексты: Я бы немного переделал: Код void init_uart(void) { //aaarrr сначала PIO и тактирование AT91C_BASE_PIOA->PIO_PDR = AT91C_PIO_PA1 | AT91C_PIO_PA0; AT91C_BASE_SYS->AIC_IDCR = (1<<AT91C_ID_US0); // на всякий случай, если UART уже использовался *AT91C_PMC_PCER = (1 << AT91C_ID_US0);
//aaarrr затем собственно периферийный модуль // а вот здесь иногда лучше использовать макросы для битов регистров *AT91C_US0_BRGR = 625; // (u_int)((MCK + (UART0_BAUDRATE * 0x08)) / (UART0_BAUDRATE * 0x10)); - так может быть удобнее *AT91C_US0_MR = AT91C_US_USMODE_NORMAL | AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE; // Normal mode, 1 stop bit, no parity, async mode, 8 bits, MCK. *AT91C_US0_IDR = 0xffffffff; // Disable all USART interrupts *AT91C_US0_IER = AT91C_US_TXRDY | AT91C_US_RXRDY;
*AT91C_US0_CR = AT91C_US_RXEN | AT91C_US_TXEN; *AT91C_US0_CR = AT91C_US_RSTRX | AT91C_US_RSTTX |AT91C_US_RSTSTA;
//aaarrr и в самом конце - прерывания AT91C_BASE_SYS->AIC_SVR[AT91C_ID_US0] = (unsigned int) vUART_ISR_Wrapper; //растановка приоритета прерывания
// AT91C_BASE_SYS->AIC_SMR[AT91C_ID_US0] = 0x63; // SRCTYPE=1, PRIOR=3. USART 0 interrupt positive edge-triggered at prio 3 //0x02; //aaarrr Для внутренних источников лучше использовать прерывание по уровню AT91C_BASE_SYS->AIC_SMR[AT91C_ID_US0] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 0x03; // SRCTYPE=0, PRIOR=3. USART 0 interrupt high level sensetive at prio 3
AT91C_BASE_SYS->AIC_IECR = (1<<AT91C_ID_US0); } Продолжение следует... Цитата(ZAA @ May 28 2008, 21:40)  Здесь собственно говоря смущает AT91C_BASE_SYS. Может надо настраивать как AT91C_BASE_AIC (пример настройки кстати взят из одного из постов)? Можно и так и так: если Вы посмотрите структуру _AT91S_SYS в файле AT91SAM7X256.h, то убедитесь, что регистры AIC на месте. Для красоты можно, конечно, поменять. Обработчик прерывания Код void vUART_ISR_Handler( void ) { unsigned int status;
status = AT91C_BASE_US0->US_CSR & AT91C_BASE_US0->US_IMR; // Сразу отбросим маскированные прерывания
vParTestToggleLED(Data); count_uart_interrupt++;
if(status & AT91C_US_RXRDY) { // Делаем что нужно, но обязательно читаем US_RHR или запрещаем прерывание RXRDY } if(status & AT91C_US_TXRDY) { // Делаем что нужно, но обязательно пишем US_THR или запрещаем прерывание TXRDY }
AT91C_BASE_AIC->AIC_EOICR = 0; // Signal end of interrupt }
|
|
|
|
|
May 28 2008, 20:51
|
Частый гость
 
Группа: Участник
Сообщений: 141
Регистрация: 10-02-08
Из: Екб
Пользователь №: 34 906

|
Цитата(aaarrr @ May 28 2008, 21:21)  ... В общем, полнейшая ерунда...Если разрешать прерывания по Tx, то программа какое-то количество раз заходит в обработчик, а потом все останавливается. А по Rx прерывания так и не воспринимаются, хотя все делаю по Вашим советам, да и по логике-то должно работать((( Вообще для общения с контроллером я пользуюсь программой Terminal.exe. В обработчике я пишу, так как Вы советовали: Код if(status & AT91C_US_TXRDY) { // Делаем что нужно, но обязательно пишем US_THR или запрещаем прерывание TXRDY (pUS0->US_THR) = 0x1;//Data & 0x1FF; vParTestToggleLED(2); AT91F_DBGU_Printc(count_uart_interrupt); //эта функция по DBGU байт передает }  Мозг взрывается уже
|
|
|
|
|
May 29 2008, 03:06
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(ZAA @ May 29 2008, 00:51)  Если разрешать прерывания по Tx, то программа какое-то количество раз заходит в обработчик, а потом все останавливается. Останавливается как - процессор виснет, или прерывания не прерываются? Цитата(ZAA @ May 29 2008, 00:51)  А по Rx прерывания так и не воспринимаются, хотя все делаю по Вашим советам, да и по логике-то должно работать((( А вот это совсем странно, тем более, что инициализируется оно одновременно с TX. Проверьте все внимательно еще раз. PDC точно выключен?
|
|
|
|
|
May 29 2008, 03:11
|
Частый гость
 
Группа: Участник
Сообщений: 141
Регистрация: 10-02-08
Из: Екб
Пользователь №: 34 906

|
Цитата(aaarrr @ May 29 2008, 06:06)  Останавливается как - процессор виснет, или прерывания не прерываются? Похоже на то, что прерывания не прерываются. Потому что в условии обработчика, где про Tx, я посылаю через DBGU значение счётчика, к-рый инкрементируется каждое прерывание. ПОсылается примерно значений 1500, а дальше все. Да ещё и в прерывание заходит, даже если кабель RS232 не подключен.
|
|
|
|
Сообщений в этой теме
ZAA Прерывание от таймера в AT91SAM7X256 May 22 2008, 05:35 aaarrr Цитата(ZAA @ May 22 2008, 09:35) Я подозр... May 22 2008, 05:40 _4afc_ Цитата(aaarrr @ May 22 2008, 09:40) Нельз... May 22 2008, 07:06  aaarrr Цитата(_4afc_ @ May 22 2008, 11:06) Обраб... May 22 2008, 07:29 ZAA НУ вот, ничего конкретного... а ведь хотя бы один... May 22 2008, 08:41 aaarrr Чтобы получить маааленький совет, укажите:
1. Како... May 22 2008, 09:00 ZAA Цитата(aaarrr @ May 22 2008, 12:00) Чтобы... May 22 2008, 13:24  sla000 Цитата(ZAA @ May 22 2008, 19:24) Я делаю ... May 23 2008, 03:08   ZAA Цитата(sla000 @ May 23 2008, 06:08) Тяжел... May 23 2008, 05:10    sla000 Цитата(ZAA @ May 23 2008, 11:10) Надо сек... May 23 2008, 05:36     ZAA Цитата(sla000 @ May 23 2008, 08:36) Нет, ... May 24 2008, 07:34     ZAA Цитата(sla000 @ May 23 2008, 08:36) Нет, ... May 24 2008, 18:58      KolyanV Цитата(ZAA @ May 24 2008, 21:58) В чем ко... May 24 2008, 20:35      aaarrr Цитата(ZAA @ May 24 2008, 22:58) AT91F_TC... May 24 2008, 21:30 ZAA Цитата(aaarrr @ May 25 2008, 00:30) Timer... May 25 2008, 07:10 aaarrr Цитата(ZAA @ May 25 2008, 11:10) У меня н... May 25 2008, 10:12  ZAA Цитата(aaarrr @ May 25 2008, 13:12) А vTa... May 25 2008, 13:39 aaarrr Нет, отдельный task создавать не нужно. Вы шедулер... May 25 2008, 15:38 ZAA Цитата(aaarrr @ May 25 2008, 18:38) Нет, ... May 25 2008, 16:40 aaarrr CPCSTOP не забыли убрать? May 25 2008, 16:43 ZAA Цитата(aaarrr @ May 25 2008, 19:43) CPCST... May 25 2008, 18:26  aaarrr Цитата(ZAA @ May 25 2008, 22:26) AT91C_BA... May 26 2008, 02:56   ZAA Цитата(aaarrr @ May 26 2008, 05:56) Почем... May 26 2008, 07:05   ZAA Цитата(aaarrr @ May 26 2008, 05:56) Почем... May 26 2008, 13:00   ZAA Цитата(aaarrr @ May 27 2008, 21:38) Можно... May 28 2008, 03:50     ZAA Цитата(aaarrr @ May 28 2008, 21:21)
Спас... May 28 2008, 18:23         ZAA Цитата(aaarrr @ May 29 2008, 07:56) Ну, э... May 29 2008, 07:46 aaarrr Так добавьте какую-нибудь задачу, которая просто б... May 29 2008, 07:50 ZAA Цитата(aaarrr @ May 29 2008, 10:50) Так д... May 29 2008, 10:01 ZAA Цитата(aaarrr @ May 29 2008, 10:50) Так д... Jun 13 2008, 05:15
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|