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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Прерывание в UART1, Help
srg_co
сообщение Jul 16 2008, 17:52
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 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 sad.gif
В чем может быть проблема, может что-то пропустил при инициализации !? Гляньте пожалуйста свежим взглядом !
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Jul 16 2008, 20:36
Сообщение #2


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Приведите пожалуйста код передачи байтов в UART1. Вообще маловато данных чтоб что-то понять.
Go to the top of the page
 
+Quote Post
srg_co
сообщение Jul 17 2008, 18:29
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 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++;
      }
}
Go to the top of the page
 
+Quote Post
Qwertty
сообщение Jul 17 2008, 20:30
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



По моему очевидно, что проблема в GSMInit.
Сегодня у коллеги был похожий случай, только не с UART a c I2C - в Vic вектор прописал, а саму функцию обработчиком не сделал. Соответственно получил похожую картину - прерывание отрабатывается один раз, затем возвращается в главный цикл, но не в USER а в IRQ, и прерываний больше нет. Проверьте режим после выхода из GSMInit. И уж если приводить код, то лучше той функции, которая явно вызывает непонятные эффекты.
Go to the top of the page
 
+Quote Post
Roman Mich.
сообщение Jul 18 2008, 03:01
Сообщение #5





Группа: Новичок
Сообщений: 6
Регистрация: 28-02-07
Пользователь №: 25 748



UART1TxEmpty обявлена как volatile?
Go to the top of the page
 
+Quote Post
srg_co
сообщение Jul 18 2008, 08:37
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600



Нет, обычный int

Цитата(Qwertty @ Jul 18 2008, 00:30) *
По моему очевидно, что проблема в GSMInit.


Возможно, только почему до входа в while(1) она, GSMInit, отрабатывает нормально ?!
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Jul 18 2008, 14:44
Сообщение #7


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Цитата(srg_co @ Jul 18 2008, 11:37) *
Возможно, только почему до входа в while(1) она, GSMInit, отрабатывает нормально ?!

Нам, не видя кода, остается только гадать.
Go to the top of the page
 
+Quote Post
srg_co
сообщение Jul 18 2008, 18:58
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600



Весь исходник в файле.


Цитата(Qwertty @ Jul 18 2008, 00:30) *
А саму функцию обработчиком не сделал.


Т.е. не описал как "__irq" ?
Прикрепленные файлы
Прикрепленный файл  gsm.rar ( 4.23 килобайт ) Кол-во скачиваний: 61
 
Go to the top of the page
 
+Quote Post
srg_co
сообщение Jul 21 2008, 19:56
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600



Так что скажут профессионалы ?
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 21 2008, 20:28
Сообщение #10


кекс
******

Группа: Свой
Сообщений: 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?
Go to the top of the page
 
+Quote Post
srg_co
сообщение Jul 22 2008, 06:34
Сообщение #11


Частый гость
**

Группа: Свой
Сообщений: 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)
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 22 2008, 11:20
Сообщение #12


кекс
******

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



Цитата(srg_co @ Jul 22 2008, 09:34) *
После передачи первого байта в прерывание не входит, отладчиком проверял (j-Link)

GSMInit использует тот же драйвер uart'a?
Go to the top of the page
 
+Quote Post
srg_co
сообщение Jul 22 2008, 11:53
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 131
Регистрация: 22-03-05
Из: Краснодар
Пользователь №: 3 600



Только он его и использует,
UART0 - отладочный
UART1 - обмен с модемом.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 23 2008, 00:19
Сообщение #14


кекс
******

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



Цитата(srg_co @ Jul 22 2008, 14:53) *
Только он его и использует,
UART0 - отладочный
UART1 - обмен с модемом.
...
Вход в __irq void uart1_interrupt( void ) не происходит вообще, программа вешается.

ну дык, GSMInit-то отработал с UART1.
Приведите для полноты картины обработчик UART0 (тот который VICVectAddr6 = (unsigned long)uart0_interrupt; ) и функцию отправки ч/з Uart0
Go to the top of the page
 
+Quote Post
srg_co
сообщение Jul 23 2008, 06:48
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post

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

 


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


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