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

 
 
 
Reply to this topicStart new topic
> прерывания USART в AT91SAM7A3, странно себя ведут в дебаггере
Aaron
сообщение Jan 28 2009, 11:29
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 243
Регистрация: 5-10-06
Из: Зеленоград
Пользователь №: 21 007



Доброго времени суток. Пишу прогу для AT91SAM7A3 в Keil + RealView. Проверяю пока всё с помощью встроенного дебаггера.
Разобрался с работой USART с использованием PDC:
1) настраиваю и включаю USART (режим local loopback)
2) включаю transfers AT91C_PDC_TXTEN / AT91C_PDC_RXTEN
3) включаю трансмиттер и ресивер AT91C_US_TXEN / AT91C_US_RXEN
4) с помощью указателей US_TPR / US_TCR и US_RPR / US_RCR посылаю и принимаю пачки данных. отличная автоматизация. всё нормально работает.

Теперь хочу разобраться с работой USART без использования PDC:
1) настраиваю и включаю USART (режим local loopback)
2) с помощью US_IER включаю прерывания US_RXRDY / US_TXRDY
3) настраиваю AIC: AIC_ConfigureIT(AT91C_ID_US0, 0, FavUS0_IRQ_Handler);
4) включаю AIC: AIC_EnableIT(AT91C_ID_US0);
5) включаю трансмиттер и ресивер AT91C_US_TXEN / AT91C_US_RXEN
6) после п.5 попадаю сразу в FavUS0_IRQ_Handler, потому что при включении трансмиттера TXRDY выставляется в 1
7) FavUS0_IRQ_Handler:
CODE
AT91PS_USART pUS = AT91C_BASE_US0;
unsigned int status,mask;
mask = pUS->US_IMR;
status = pUS->US_CSR & mask;
...
if (status&AT91C_US_TXRDY) {
pUS->US_IDR = AT91C_US_TXRDY; // выключаем прырывание, чтобы не зациклиться из-за пустого tx-выхода
flag_sent = 1;
}

всё. прерывание обработали. возвращаюсь в основную программу
8) пытаюсь отправить последовательно несколько байт (внутри функции main()):
CODE
01: str = malloc(BUFFER_SIZE);
02: strcpy(str,"12345");
03:
04: while (!flag_sent);
05: flag_sent = 0;
06: USART0->US_THR = str[0];
07: USART0->US_IER = AT91C_US_TXRDY;
08: while (!flag_sent);
09: flag_sent = 0;
10: USART0->US_THR = str[1];
11: USART0->US_IER = AT91C_US_TXRDY;
12: while (!flag_sent);
...

цифры 01: ... 12: условно показал. дак вот, первый байт отправляется, на строке 08 US_CSR->US_TXRDY переходит из 0 в 1, но при этом программа не входит в обработчик прерывания FavUS0_IRQ_Handler.

Пробовал ещё настраивать local loopback, TX через PDC отправлять (TXTEN=1), а RX через RXRDY ловить. аналогичная ситуация:
один раз заходит в FavUS0_IRQ_Handler, забирает пришедший байт US_RHR, и всё. после этого трансивер отправляет остальные байты, но повторно в обработчик программа не заходит при этом (хотя US_CSR->US_RXRDY = 1).

Подскажите, в какую сторону копать?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 28 2009, 11:32
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Aaron @ Jan 28 2009, 14:29) *
Подскажите, в какую сторону копать?

В сторону записи AIC_EOICR после обслуживания прерывания.
Go to the top of the page
 
+Quote Post
Aaron
сообщение Jan 28 2009, 12:15
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 243
Регистрация: 5-10-06
Из: Зеленоград
Пользователь №: 21 007



Цитата(aaarrr @ Jan 28 2009, 14:32) *
В сторону записи AIC_EOICR после обслуживания прерывания.

спасибо за подсказку. Но, тем не менее, почитав про этот регистр, видимо, не до конца понял как орудовать надо.
в конце функции FavUS0_IRQ_Handler добавил строчку:
AT91C_BASE_AIC->AIC_EOICR = 1;

из-за этого прерывание на выходе вываливается не туда ещё на этапе включения трансмиттера:
AIC_ConfigureIT(AT91C_ID_US0, 0, FavUS0_IRQ_Handler);
AIC_EnableIT(AT91C_ID_US0);

// Enable receiver & transmitter
USART_SetTransmitterEnabled(pUS, 1);
USART_SetReceiverEnabled(pUS, 1); ----- до сюда уже не доходит
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 28 2009, 12:26
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



А FavUS0_IRQ_Handler оформлен как __irq?
Go to the top of the page
 
+Quote Post
Aaron
сообщение Jan 28 2009, 12:35
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 243
Регистрация: 5-10-06
Из: Зеленоград
Пользователь №: 21 007



Цитата(aaarrr @ Jan 28 2009, 15:26) *
А FavUS0_IRQ_Handler оформлен как __irq?

!!! =) только что сам до этого дошёл. Хотел сюда написать. В общем, для тех, кому интересно:
функция должна описываться как
__irq void FavUS0_IRQ_Handler(void)
, и ещё при настройке AIC тоже чуток изменяется строчка (чтобы компилер не ругался):
AIC_ConfigureIT(AT91C_ID_US0, 0, (void (*)(void))FavUS0_IRQ_Handler);

всё, спасибо!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 28 2009, 12:41
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Чтобы компилер не ругался, лучше спокойно руками проинициализировать AIC, вместо использования сомнительных макросов. Заодно и понимание происходящего приходит.

Это относится к любой периферии и всем макросам by Atmel.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 00:00
Рейтинг@Mail.ru


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