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

 
 
> 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
Ответов (1 - 3)
Д_М
сообщение 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
Д_М
сообщение Mar 23 2015, 19:39
Сообщение #3


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

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



Кажется нашёл способ. Когда остаётся передать один байт, надо отключить очередь передачи. Тогда прерывание генерируется после завершения передачи последнего байта.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 24 2015, 03:33
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Д_М @ Mar 13 2015, 15:28) *
Было замечено, что прерывание THRE возникает не при опустошении регистра хранения передатчика, а при опустошении сдвигового регистра передатчика.

Сомнительное утверждение.
Я конечно конкретно это не проверял, но у нас много устройств на разных LPC с RS-485, где после приёма THREI мониторится состояние TEMT и, после его возникновения, отключается передатчик. И все работают ок.

Цитата(Д_М @ Mar 13 2015, 15:28) *
Перед начало передачи была сброшена очередь передачи и включен светодиод. В обработчике прерывания опустошения регистра хранения передатчика светодиод выключался. Как я себе представляю, когда очередь пустая, один записанный байт тут же помещается в сдвиговый регистр и начинается его передача. Очередь становится опять пустой и должно сгенерироваться прерывание опустошения регистра хранения. Если так, то мигания светодиода не наблюдалось бы, так как время между двумя событиями слишком мало. Но светодиод вспыхивает очень хорошо. Это доказывает что прерывание THRE после завершения передачи.

Не знаю про какой Вы исходник говорите, но в Вашем светодиод вроде включается после наступления события таймаута приёма. При этом все прерывания запрещаются и когда и где Вы потом опять их разрешаете не видно из исходника.
Так что мигать может как угодно и гореть как угодно долго.
И вообще - у Вас там такая каша, что трудно разобраться.
Научитесь пользоваться функциями или макросами для вкл/выкл светодиода.
И странно сначала запрещать все прерывания, а после этого считывать IIR.

PS: Ещё раз повторю - в 99.9% случаев ищите ошибку у себя, а не в чипе. А с таким кодом и во всех 100% у себя....
Go to the top of the page
 
+Quote Post

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

 


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


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