|
Тема может быть избита. не понимаю как оргнизовать работу UART по прерывания(+) |
|
|
|
Jan 8 2007, 12:58
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-02-05
Из: Уфа
Пользователь №: 2 474

|
Нашел примеры работы UART-a / которые выкладывал VAI? но у него используется только перрывание на прием. Я же хочу чтобы и на передачу и на прием работало по прерваниям Мой код в основной программе Uart0PutChar(0x30); прерывание проходит Uart0PutStr("qwe"); тут как карта ляжет, программа зацикливается .... while(*str){ Uart0Tx.PtrWrByte = ++Uart0Tx.PtrWrByte & UART_BUFFER_MASK; while (Uart0Tx.PtrWrByte == Uart0Tx.PtrRdByte) {} // программа зацикливается Как я понимаю, происходит изменение указателя а в это время возникает прерывание на TX и указатель Uart0Tx.PtrRdByte принимает значение Uart0Tx.PtrWrByte ----------------------------------------- Модуль Uart.c Код #pragma vector=USART0TX_VECTOR __interrupt void irq_Uart0_Tx(void) { if (Uart0Tx.PtrWrByte != Uart0Tx.PtrRdByte){ Uart0Tx.PtrRdByte = ++Uart0Tx.PtrRdByte & UART_BUFFER_MASK; TXBUF0 = Uart0Tx.Buffer[Uart0Tx.PtrRdByte]; } // else{ // // флаг на завершение Tx и необходимости переключится на прием // // if (EventFlags & fwRxWaitTime){ // //bSwitchTxToRx = 1; // EventFlags |= fwSwitchTxToRx; // pRS485Tx = 0; // приемопередатчик на Rx // }
}
#pragma vector=USART0RX_VECTOR __interrupt void irq_Uart0_Rx(void) { volatile char dummy; unsigned char RxData;
if ( FE+PE+OE+BRK+RXERR ){ // overflow or framing error - URCTL1 &= ~ (FE+PE+OE+BRK+RXERR); // Clear error flags dummy = RXBUF0; // dummy read to clear RXE flag } else{ RxData = RXBUF0; // Read the received data if ((Uart0Rx.PtrWrByte + 1) != Uart0Rx.PtrRdByte){ Uart0Rx.PtrWrByte = ++Uart0Rx.PtrWrByte & UART_BUFFER_MASK; Uart0Rx.Buffer[Uart0Rx.PtrWrByte] = RxData; } } }
void Uart0PutChar(unsigned char TxData) { Uart0Tx.PtrWrByte = ++Uart0Tx.PtrWrByte & UART_BUFFER_MASK; while (Uart0Tx.PtrWrByte == Uart0Tx.PtrRdByte) { // // Сброс сторожевого таймера // } // Wait for incomming data Uart0Tx.Buffer[Uart0Tx.PtrWrByte] = TxData; if ((IFG1 & UTXIFG0) != UTXIFG0) // UART0_ENABLE_TX_INTERRUPT; IFG1 |= UTXIFG0; }
void Uart0PutStr(unsigned char *str) { // while(*str) Uart0PutChar(*str++); //*s++=Tmpchar; while(*str){ Uart0Tx.PtrWrByte = ++Uart0Tx.PtrWrByte & UART_BUFFER_MASK; while (Uart0Tx.PtrWrByte == Uart0Tx.PtrRdByte) {} // Wait for incomming data
Uart0Tx.Buffer[Uart0Tx.PtrWrByte] = *str++; if ((IFG1 & UTXIFG0) != UTXIFG0) //UART0_ENABLE_TX_INTERRUPT; IFG1 |= UTXIFG0; } }
|
|
|
|
|
 |
Ответов
(15 - 29)
|
May 5 2008, 16:05
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Jan 8 2007, 16:54)  Вот мой код... Пытаясь выжать (вдруг я чего-то не понимаю, чего другие понимают  )из простейшего UART-а MSP430 все возможное, набрел на эту старую тему. По поводу твоего кода, Сергей, перемудрил ты несколько с voltile и c масками. Можно проще, например, передача: Код #define TX_BUFF_SIZE 16 // must be power of two #define TX_BUFF_MASK (TX_BUFF_SIZE-1) char TxBuffer[TX_BUFF_SIZE]; uint8_t volatile TxTail; uint8_t TxHead;
#pragma vector = USART0TX_VECTOR __interrupt void Tx232(void) {
U0TXBUF = TxBuffer[TxTail++ & TX_BUFF_MASK]; if( TxTail == TxHead ) // buffer empty IE1 &= ~UTXIE0; // disable tx int }
void putchar(int symbol) {
while( TxHead - TxTail >= TX_BUFF_SIZE ); // wait while buffer full
TxBuffer[TxHead++ & TX_BUFF_MASK] = symbol;
IE1 |= UTXIE0; // enable tx int }
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
May 7 2008, 04:39
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(rezident @ May 6 2008, 21:42)  Для инициации передачи UART недостаточно просто разрешить прерывание. Желательно принудительно (программно) установить флаг UTXIFGx. Иначе нельзя быть на 100% уверенным, что прерывание действительно возникнет. Флаг может быть оказаться сброшен после вызова "лишнего" прерывания при неудачном стечении (программных) обстоятельств. А я вообще не понимаю, зачем запрещать и разрешать прерывания по TX. Может просветите? Я вот так делаю Код //------------------------------------------------------------------------------
#pragma vector = UART0TX_VECTOR __interrupt void uart0_write_interrupt_handler(void) { IFG1 &= ~UTXIFG0; // clear flag TXD0 if(MessLen0--)U0TXBUF=*cTXbuf0ptr++; }
//------------------------------------------------------------------------------ Закончили передачу сообщения - просто не кидаем в буфер ничего и прерывание не возникнет. Зачем же его тогда запрещать?
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
May 7 2008, 05:28
|
Участник

Группа: Свой
Сообщений: 63
Регистрация: 16-06-04
Из: Россия, Уфа
Пользователь №: 31

|
вопрос действительно уже не раз поднимавшийся и в этот раз я тыркну сцылку )) http://kurt.embedders.org/wiki/sources:uart1
|
|
|
|
|
May 7 2008, 08:56
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(MrYuran @ May 7 2008, 10:39)  А я вообще не понимаю, зачем запрещать и разрешать прерывания по TX. Может просветите? При пакетной передаче я тоже не запрещаю. Потому как в прерывании анализируется состояние буфера передачи (количество символов в очереди). Но для посимвольной передачи прерывание запрещать нужно прямо на выходе из прерывания. Иначе может иметь быть место какое-нибудь дублирование символов. Цитата(MrYuran @ May 7 2008, 10:39)  Я вот так делаю Цитата(MrYuran @ May 7 2008, 10:39)  Закончили передачу сообщения - просто не кидаем в буфер ничего и прерывание не возникнет. Дык это у вас как раз случай буферизированной пакетной передачи. Выше же про putchar речь идет, где посимвольная передача. Цитата(AHTOXA) Тогда при отсутствии передачи надо первый символ кидать не в буфер, а в U0TXBUF, а то прерывание вообще не возникнет. То есть, нужен какой-то флажок, который отслеживает наличие символа в передатчике. Флажки все есть UTXIFGx и EPT, нужно только не забывать их проверять.
|
|
|
|
|
Sep 20 2014, 18:37
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Оппа... Понадобилось перевести передачу на прерывания, не работает так как надо. У меня особенность - в циклический буфер добавляются байты (или строки) если - передача идет - если передача стоит
Если оперировать только разрешением прерывания, как у zltigo, то передача после первого байта блокируется. Это понятно - нет фронта флага, он повис. Если дергать (устанавливать) флаг готовности передачи в момент добавления в буфер очередного символа, то символы пропадают - тоже понятно - срабатывает прерывание по передаче, когда передача еще идет.
Я конечно найду решение до понедельника, но если кто имеет решение, прошу поделиться. Спасибо.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|