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

 
 
> LPC2129 прерывание UART, не получается прерывание завершения передачи
Д_М
сообщение Mar 11 2015, 20:34
Сообщение #1


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

Группа: Участник
Сообщений: 121
Регистрация: 15-04-05
Из: Краснодар
Пользователь №: 4 185



Здравствуйте!
Работает прерывание приёма и опустошения регистра передачи. Очень хочется, чтобы было прерывание и по окончании передачи.
Ниже обработчик прерывания

CODE
#define RBR_Interrupt_Enable (1<< 0)
#define THRE_Interrupt_Enable (1<< 1)
#define LS_Interrupt_Enable (1<< 2)
#define Receive_Line_Status 6
#define Receive_Data_Available 4
#define Character_TimeOut_Indicator 0x0C
#define THRE_Interrupt 2
#define msk_ULSR_Errors 0x9E

void UART0VectoredIRQ (void) __irq
{
char
Msg,
dummy;

if(((Msg = U0IIR) & 0x01) == 0) // Flag Status of RX Int
{
switch(Msg & 0x0E) // Filter Msg
{
case Receive_Line_Status:
if (IOPIN & LED_G)
LEDS_ON = LED_G;
else
LEDS_OFF = LED_G;

if (U0LSR & msk_ULSR_Errors)
break;
else
if ((RTS0) && (U0LSR & (1<< TEMP))) // Transmition Finish
{
// Run Tx handler
/* if (IOPIN & LED_G)
LEDS_ON = LED_G;
else
LEDS_OFF = LED_G; */
U0IER = RBR_Interrupt_Enable | LS_Interrupt_Enable;
RTS0 = 0;
break;
}

case Receive_Data_Available:
RTS0 = 1;
U0IER = THRE_Interrupt_Enable;
U0THR = U0RBR + 3;
/* if (IOPIN & LED_G)
LEDS_ON = LED_G;
else
LEDS_OFF = LED_G; */
break;
case THRE_Interrupt:
if (IOPIN & LED_G)
LEDS_ON = LED_G;
else
LEDS_OFF = LED_G;

U0IER = LS_Interrupt_Enable;
/*
if (RTS0) // Transmition
if (amount_SIO0--)
U0THR = *ptr_SIO0++;
else
dummy = U0LSR; */
break;
default:
break;
}
}
VICVectAddr = 1;// Dummy write to signal end of interrupt
}

Программа должна возвращать один байт на один байт запроса. Как я себе представляю, при обработке прерывания опустошения регистра передачи, включается прерывание "состояние линии" (LS_Interrupt_Enable). Когда произойдёт это прерывание, отследить в регистре состояния линии (LSR) бит TransmitterEmpty(TEMT). Однако, управление не переходит на Receive_Line_Status
Что не так?

Сообщение отредактировал IgorKossak - Mar 12 2015, 18:30
Причина редактирования: [codebox] для длинного кода, [code] - для короткого
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Д_М
сообщение Mar 13 2015, 09:28
Сообщение #2


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

Группа: Участник
Сообщений: 121
Регистрация: 15-04-05
Из: Краснодар
Пользователь №: 4 185



Здравствуйте!
Было замечено, что прерывание THRE возникает не при опустошении регистра хранения передатчика, а при опустошении сдвигового регистра передатчика. Перед начало передачи была сброшена очередь передачи и включен светодиод. В обработчике прерывания опустошения регистра хранения передатчика светодиод выключался. Как я себе представляю, когда очередь пустая, один записанный байт тут же помещается в сдвиговый регистр и начинается его передача. Очередь становится опять пустой и должно сгенерироваться прерывание опустошения регистра хранения. Если так, то мигания светодиода не наблюдалось бы, так как время между двумя событиями слишком мало. Но светодиод вспыхивает очень хорошо. Это доказывает что прерывание THRE после завершения передачи.

CODE
void UART0VectoredIRQ (void) __irq
{
char
Msg,
dummy;

if(((Msg = U0IIR) & 0x01) == 0) // Flag Status of RX Int
{
switch(Msg & 0x0E) // Filter Msg
{
case Receive_Line_Status:
// if (RTS0)
if (IOPIN & LED_G)
LEDS_ON = LED_G;
else
LEDS_OFF = LED_G;

if (U0LSR & msk_ULSR_Errors)
/* if ((IOPIN & LED_G) && RTS0)
LEDS_ON = LED_G;
else
LEDS_OFF = LED_G; */

break;
else
/* if (RTS0)
{
if (IOPIN & LED_G)
LEDS_ON = LED_G;
else
LEDS_OFF = LED_G; */

if (U0LSR & (1<< TEMP)) // Transmition Finish
{
// Run Tx handler
/* if (IOPIN & LED_G)
LEDS_ON = LED_G;
else
LEDS_OFF = LED_G; */
U0IER = RBR_Interrupt_Enable | LS_Interrupt_Enable;
RTS0 = 0;
break;
}
// }

case Receive_Data_Available:
while(U0LSR & 1) // U0RBR contains valid data.
dummy = U0RBR;
// LEDS_ON = LED_G;
/* RTS0 = 1;
U0IER = 0;
U0FCR = SD_FIFO_ENABLE | SD_FIFO_RX_RESET | SD_FIFO_TX_RESET | RX_Trigger_Level1;
U0IER = THRE_Interrupt_Enable;
U0THR = U0RBR + 3;
LEDS_ON = LED_G;
if (IOPIN & LED_G)
LEDS_ON = LED_G;
else
LEDS_OFF = LED_G; */
break;
case Character_TimeOut_Indicator:
while(U0LSR & 1) // U0RBR contains valid data.
dummy = U0RBR;
// LEDS_OFF = LED_G;
LEDS_ON = LED_G;
RTS0 = 1;
U0IER = 0;
U0FCR = SD_FIFO_ENABLE | SD_FIFO_RX_RESET | SD_FIFO_TX_RESET | RX_Trigger_Level1;
break;
case THRE_Interrupt:
Msg = U0LSR;

if (Msg & (1<< THRE))
{
if (amount_SIO0--)
{
U0THR = 8;
LEDS_OFF = LED_G;
}
/* if (IOPIN & LED_G)
LEDS_ON = LED_G;
else
LEDS_OFF = LED_G; */
}

if (Msg & (1<< TEMP))
{
RTS0 = 0;
U0IER = RBR_Interrupt_Enable | LS_Interrupt_Enable;
/* if (IOPIN & LED_G)
LEDS_ON = LED_G;
else
LEDS_OFF = LED_G; */
}

break;
default:
break;
}
}
VICVectAddr = 1;// Dummy write to signal end of interrupt
}


Сообщение отредактировал IgorKossak - Mar 13 2015, 15:56
Причина редактирования: [codebox] для длинного кода, [code] - для короткого
Go to the top of the page
 
+Quote Post



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

 


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


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