|
Прерывание в UART1, Help |
|
|
|
Jul 16 2008, 17:52
|
Частый гость
 
Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600

|
Исходные данные: KEIL322a, LPC2138 Исходник: Код void main ( void ) { … … //выполняется обмен с модемом GSMInit() OutMenu( "Вывод меню пользователя через UART0" ); while (1); } Инициализация UART: Код //UART0 - 115200 - Отладочный порт PINSEL0 |= 0x00000005; //Enable RxD and TxD pins U0LCR = 0x83; //8 bits, no Parity, 1 Stop bit U0DLL = (VPB_CLOCK/16/BAUD_RATE0) & 0xFF; //Setup Baudrate U0DLM = ((VPB_CLOCK/16/BAUD_RATE0) >> 8) & 0xFF; U0LCR = 0x03; //DLAB = 0
//настройка прерывания UART0 VICVectAddr6 = (unsigned long)uart0_interrupt; //прерывание на 6 векторе VICVectCntl6 = 0x20 | 0x06; VICIntEnable |= 0x00000040; //включить прерывание от UART0
U0IER = IER_RBR | IER_THRE; //конфигурация прерывания UART0 //приняты данные, буфер пуст
//UART1 PINSEL0 |= 0x00050000; //Enable RxD and TxD pins U1LCR = 0x83; //8 bits, no Parity, 1 Stop bit U1DLL = (VPB_CLOCK/16/BAUD_RATE1) & 0xFF; //Setup Baudrate U1DLM = ((VPB_CLOCK/16/BAUD_RATE1) >> 8) & 0xFF; U1FCR = 0x07; //Разрешение работы и сброс TX and RX FIFO, граница - 1 байт U1LCR = 0x03; //DLAB = 0 разрешить работу порта
//настройка прерывания UART1 VICVectAddr7 = (unsigned long)uart1_interrupt; VICVectCntl7 = 0x20 | 0x07; VICIntEnable |= 0x00000080; U1IER = IER_RBR | IER_THRE; Обработка прерывания: Код __irq void uart1_interrupt( void ) {
int IIRValue, LSRValue; char ch, RBRValue; volatile char Dummy;
IIRValue = U1IIR; IIRValue = (IIRValue & 0x0E) >> 1; // Выделяем информацию об источнике прерывания
if ( IIRValue == 0x03 ) { //Изменился статус приемной линии //сбросим времени счетчик последнего обмена LSRValue = U1LSR; if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) ) { //Пустое чтения для сброса флага прерывания Dummy = U1RBR; VICVectAddr = 0; return; } } if ( IIRValue == IIR_RDA || IIRValue == IIR_CTI ) { //Принят новый байт данных и достигнута граница тригера RBRValue = U1RBR; GSMRecv( RBRValue ); } if ( IIRValue == IIR_THRE ) { //Прочитаем статус и убедимся, что действительно THR пуст LSRValue = U1LSR; if ( LSRValue & LSR_THRE ) //буфер передачи пуст UART1TxEmpty = 1; /*if ( GSMSendByte( &ch ) ) U1THR = ch;*/ else UART1TxEmpty = 0; } //сброс прерывания VICVectAddr = 0; } GSMInit – отрабатывает нормально в main, передает несколько команд в модем, но как только попадаем в while(1) функция перестает отрабатывать, т.е. передается один байт и все. Вход в __irq void uart1_interrupt( void ) не происходит вообще, программа вешается. Второй вызов GSMInit выполняется по нажатию пользовательской кнопки или по команде с консоли. Если отключить вызов GSMInit в main а потом вызвать отдельно, ситуация повторяется, т.е. передача одного байта и ступор. Обмен по UART0 идет без проблен, пока не вызывать GSMInit  В чем может быть проблема, может что-то пропустил при инициализации !? Гляньте пожалуйста свежим взглядом !
|
|
|
|
|
Jul 17 2008, 18:29
|
Частый гость
 
Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600

|
Цитата(HARMHARM @ Jul 17 2008, 00:36)  Приведите пожалуйста код передачи байтов в UART1. Вообще маловато данных чтоб что-то понять. Код void UART1Send( char *str ) {
while ( *str ) { //ждем завершение передачи while ( !UART1TxEmpty ); //передаем следущий байт U1THR = *str; UART1TxEmpty = 0; str++; } }
|
|
|
|
|
Jul 18 2008, 03:01
|
Группа: Новичок
Сообщений: 6
Регистрация: 28-02-07
Пользователь №: 25 748

|
UART1TxEmpty обявлена как volatile?
|
|
|
|
|
Jul 18 2008, 08:37
|
Частый гость
 
Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600

|
Нет, обычный int Цитата(Qwertty @ Jul 18 2008, 00:30)  По моему очевидно, что проблема в GSMInit. Возможно, только почему до входа в while(1) она, GSMInit, отрабатывает нормально ?!
|
|
|
|
|
Jul 18 2008, 18:58
|
Частый гость
 
Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600

|
Весь исходник в файле. Цитата(Qwertty @ Jul 18 2008, 00:30)  А саму функцию обработчиком не сделал. Т.е. не описал как "__irq" ?
Прикрепленные файлы
gsm.rar ( 4.23 килобайт )
Кол-во скачиваний: 61
|
|
|
|
|
Jul 21 2008, 20:28
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата if ( IIRValue == IIR_RDA || IIRValue == IIR_CTI ) { //Принят новый байт данных и достигнута граница тригера тут коментарий как-то не вяжется с условием || --> "или", а коментарии написано "и". Цитата if ( IIRValue == IIR_THRE ) { //Прочитаем статус и убедимся, что действительно THR пуст Если в статусе THRE, дык берите да заполняйте FIFO. и так ясно что писать можно Возможно тут и висло. Самое главное, вы учли в константах IIR_THRE / IIR_RDA что IIRValue сдвинут вправо на 1?
|
|
|
|
|
Jul 22 2008, 06:34
|
Частый гость
 
Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600

|
Коментарий исправлю. С константами все нормально: Код #define IIR_RDA 0x02 #define IIR_CTI 0x06 #define IIR_THRE 0x01 биты 1-3 U1IIR: 010 - Receive Data Available (RDA). 110 - Character Time-out Indicator (CTI). 001 - THRE Interrupt После передачи первого байта в прерывание не входит, отладчиком проверял (j-Link)
|
|
|
|
|
Jul 23 2008, 06:48
|
Частый гость
 
Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600

|
Вот: Код __irq void uart0_interrupt( void ) {
int endinp = 0, IIRValue, LSRValue;
IIRValue = U0IIR; IIRValue = (IIRValue & 0x0E) >> 1; // Выделяем информацию об источнике прерывания
if ( IIRValue == IIR_RDA ) //Receive Data Available //данные приняты endinp = InputLine( U0RBR ); if ( IIRValue == IIR_THRE ) { //THRE, буфер передачи пуст LSRValue = U0LSR; if ( LSRValue & LSR_THRE ) { //передаем символ if ( QueueHeadSer < QueueTailSer ) U0THR = *QueueHeadSer++; else SetHeadQueue(); } } //сброс прерывания VICVectAddr = 0;
//ввели команду, надо обработать if ( endinp ) ParseCmnd(); } Передача следующего байта организована как выборка из очереди.
Сообщение отредактировал srg_co - Jul 23 2008, 06:52
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|