mempfis_ 0 31 марта, 2010 Опубликовано 31 марта, 2010 (изменено) · Жалоба Пытаюсь настроить USART0 для передачи данных в терминал без использования прерываний. После чтения документации пришёл к таким настройкам: #define BOARD_MCK 48000000 #define US0_BAUD 115200 #define BAUDRATE0 (BOARD_MCK / US0_BAUD) / 16; //настройка usart0 void ConfigureUART(void) { //разрешение тактирования uart0 AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_US0); // сброс и запрет приёмника/передатчика AT91C_BASE_US0->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS; //асинхронный режим, 8 бит, 1 стоповый, без чётности, системный клок 48МГц AT91C_BASE_US0->US_MR = AT91C_US_USMODE_HWHSH | AT91C_US_CLKS_CLOCK | AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE | AT91C_US_NBSTOP_1_BIT | AT91C_US_CHMODE_NORMAL; //настройка предделителя частоты AT91C_BASE_US0->US_BRGR = BAUDRATE0; //очищаем прерывания AT91C_BASE_US0->US_CSR; //включаем приём/передачу AT91C_BASE_US0->US_CR = AT91C_US_RXEN|AT91C_US_TXEN; } /******************************************************************/ В PIO настраиваю альтернативные функции - PA5/PA6 RXD/TXD соответственно /*******************************************/ //линии uart #define RXD (1<<5) //in #define TXD (1<<6) //out pu //настройка альтернативных функций void PIO_alternat_config(void) { //разрешаем альтернативным функциям управлять выводами AT91C_BASE_PIOA->PIO_PDR = RXD|TXD; //разрешаем подтягивающий резистор на TXD AT91C_BASE_PIOA->PIO_PPUER = TXD; //разрешаем альтернативные функции AT91C_BASE_PIOA->PIO_ASR = RXD|TXD; } /*******************************************/ Для передачи символа определил функцию: void _putcharSerial0(unsigned char data) { //ожидаем завершения передачи //while(!(AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY)); AT91C_BASE_US0->US_THR = data; for(int i=1000000; i; i--); } Сначала попробовал опрашивать флаг готовности к передаче и потом пихать символ в US_THR. Программа зависла как только я попытался передать первый-же символ (вероятно на строчке ожидания готовности к передаче). Заменил ожидание на задержку перед отправкой следующего символа - в терминале 0, программа после попытки отправить символ пошла исполняться дальше. Т.е. полагаю что USART0 всёже не включился. Хотя я подал на него тактирование, настроил регистры управления, предделитель, включил приём/передачу, настроил альтернативные функции в PIO! Вопрос - что я упустил в настройках? Заранее спасибо за ответы :) Изменено 31 марта, 2010 пользователем mempfis_ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 25 31 марта, 2010 Опубликовано 31 марта, 2010 · Жалоба Пытаюсь настроить USART0 для передачи данных в терминал без использования прерываний. Вопрос - что я упустил в настройках? Заранее спасибо за ответы :) Меня смущает AT91C_US_USMODE_HWHSH. И PIO_alternat_config я вызываю сразу после AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_US0); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mempfis_ 0 31 марта, 2010 Опубликовано 31 марта, 2010 · Жалоба Меня смущает AT91C_US_USMODE_HWHSH. И PIO_alternat_config я вызываю сразу после AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_US0); Да уж моя внимательность при списывании примеров от атмела на грани фантастики..... Заменил AT91C_US_USMODE_HWHSH на AT91C_US_USMODE_NORMAL всё заработало сразу. А PIO_alternat_config вызывается в функции настройки PIO которая идёт перед настройкой уарта. Спасибо за подсказку :) Буду теперь организовывать работу уарта по прерываниям :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mempfis_ 0 31 марта, 2010 Опубликовано 31 марта, 2010 · Жалоба Продолжение темы :) Организовал работу по прерывания - настроил уарт, разрешил прерывания по готовности приёмника и передатчика. Создал обработчик прерывания в котором при возникновении прерывания после передачи байта проверяется есть ли в фифо уарта данные (хвост не равен голове) и если есть то извлекается следующий байт а хвост передвигается вперёд. При приёме байт просто ложится в приёмную фифо. /******************************************************************/ #define US0_RXBUFSIZE 512 #define US0_TXBUFSIZE 512 //Глобальные переменные volatile int Rx0Buf[US0_RXBUFSIZE];// the receiver buffer. int Rx0Head = 0;// int Rx0Tail = 0; volatile int Tx0Buf[US0_RXBUFSIZE];// the transmit buffer. int Tx0Head = 0;// int Tx0Tail = 0; //обработчик прерываний usart0 void USART0_ISR(void) { int status; //читаем регистр статуса status = AT91C_BASE_US0->US_CSR; if(status & AT91C_US_TXRDY) { //передача байта завершена if (Tx0Tail != Tx0Head) { AT91C_BASE_US0->US_THR = Tx0Buf[Tx0Tail++]; if (Tx0Tail >= US0_TXBUFSIZE) Tx0Tail = 0; } } if(status & AT91C_US_RXRDY) { //приём завершён Rx0Buf[Rx0Head++] = AT91C_BASE_US0->US_RHR; if (Rx0Head >= US0_RXBUFSIZE) Rx0Head = 0; } } /******************************************************************/ Код прекрасно работал в atmegaх. В АRMе при выполнении этого кода программа зависает. Т.е. входит в обработчик доходит до момента считывания байта из фифо для передачи его в AT91C_BASE_US0->US_THR. После этого программа вылетает непонятно куда. Если вставить простое присваивание любого числа передающему регистру (AT91C_BASE_US0->US_THR = 'A') или закоментировать строчку if (Tx0Tail != Tx0Head) то видно что прерывание работает - идёт непрерывная передача данных. Вопрос - как можно объяснить такое поведение программы? Это что глюк компилятора или я чтото не учитываю при написании программ под 32хбитные контроллеры ARM? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 64 31 марта, 2010 Опубликовано 31 марта, 2010 · Жалоба Это что глюк компилятора или я чтото не учитываю при написании программ под 32хбитные контроллеры ARM? Если в прерывании по передаче не произойдет записи US_THR, то источник прерывания снят не будет, т.е. получите "зависание". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mempfis_ 0 1 апреля, 2010 Опубликовано 1 апреля, 2010 · Жалоба Если в прерывании по передаче не произойдет записи US_THR, то источник прерывания снят не будет, т.е. получите "зависание". Спасибо за подсказку. Перечитал моменты связанные в приёмом/передачей и соответствующими битами в регистре статуса. Пришел к такому варианту реализации: (UART настроен. Приёмник и передатчик включены. Разрешено прерывание AT91C_US_RXRDY) /**************************************************************/ //ложим байт в передающий регистр или фифо void _putcharSerial0(unsigned char data) { if ( !(AT91C_BASE_US0->US_IMR & AT91C_US_TXEMPTY) ) { //прерывания по опустошению передающего регистра запрещены (нет передачи) //ложим байт в передающий буффер и разрешаем прерывание AT91C_BASE_US0->US_THR = data; AT91C_BASE_US0->US_IER = AT91C_US_TXEMPTY; } else { //выполняется передача - ложим байт в фифо Tx0Buf[Tx0Head++] = data; if (Tx0Head >= US0_RXBUFSIZE) Tx0Head = 0; } } /**************************************************************/ void _putstring0( const unsigned char *pData) { while(*pData != 0x00) _putcharSerial0(*pData++); } #define PutString0(x) do{static const unsigned char str[]=x; _putstring0(str);}while(0); /******************************************************************/ //обработчик прерываний usart0 void USART0_ISR(void) { int status; //читаем регистр статуса status = AT91C_BASE_US0->US_CSR; if(status & AT91C_US_TXEMPTY) { //передача байта завершена if (Tx0Tail != Tx0Head) { //есть ещё байты на передачу AT91C_BASE_US0->US_THR = Tx0Buf[Tx0Tail++]; if (Tx0Tail >= US0_TXBUFSIZE) Tx0Tail = 0; } else { //больше нет байт на передачу //запрещаем прерывания по опустошению передающего регистра AT91C_BASE_US0->US_IDR = AT91C_US_TXEMPTY; } } if(status & AT91C_US_RXRDY) { //приём байта завершён //считываем байт в фифо Rx0Buf[Rx0Head++] = AT91C_BASE_US0->US_RHR; if (Rx0Head >= US0_RXBUFSIZE) Rx0Head = 0; } } /******************************************************************/ Всё работает как задумывалось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megarazor 0 3 августа, 2010 Опубликовано 3 августа, 2010 · Жалоба Какие именно примеры атмела использовал ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mempfis_ 0 3 августа, 2010 Опубликовано 3 августа, 2010 · Жалоба Какие именно примеры атмела использовал ? Приеры из папки examples/atmel. Сейчас стоит другой iar поэтому точнее сказать не могу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться