|
Тема может быть избита. не понимаю как оргнизовать работу 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; } }
|
|
|
|
|
 |
Ответов
|
Jan 8 2007, 14:54
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(AlHakim @ Jan 8 2007, 11:58)  Модуль Uart.c Код if ((IFG1 & UTXIFG0) != UTXIFG0) // UART0_ENABLE_TX_INTERRUPT; IFG1 |= UTXIFG0; Не совсем красиво разрешать/запрещать прерывания дергая флаг. Он ведь может измениться аппаратно пока вы пытаетесь его изменить программно. У вас в комментариях написано ENABLE_TX_INTERRUPT, так и делайте это при помощи специально предназначенного для этого бита. Про атомарность HARMHARM правильно заметил, опять же про volatile не забываем. Вот мой код, в нем обращения атомарны, запреты прерываний не нужны: Код #include <msp430x14x.h> #include <stdio.h> #include <stdint.h>
#include "Hardware.h"
#define RX_BUFF_SIZE 32 // must be power of two #define TX_BUFF_SIZE 16 // must be power of two
char RxBuffer[RX_BUFF_SIZE]; char TxBuffer[TX_BUFF_SIZE]; uint8_t volatile RxHead, RxTail, TxHead, TxTail;
void UART_Init (void) { U0BR0 = (SMCLK / UART_BAUDRATE) & 0xFF; U0BR1 = (SMCLK / UART_BAUDRATE) >> 8; U0MCTL = 0; U0CTL = (0 * PENA) | (0 * SPB) | (1 * CHAR) | (0 * LISTEN) | (0 * SYNC) | (0 * SWRST); U0TCTL = (1 * SSEL1) | (0 * SSEL0) | (1 * TXEPT);
ME1 = URXE0 | UTXE0; // enable tx & rx P3SEL |= (1<<5) | (1<<4); // enable pins IE1 = URXIE0; // enable RX int }
#pragma vector = USART0TX_VECTOR __interrupt void Tx232(void) { uint8_t Tmp = TxTail; // temp. variable because TxTail is volatile
U0TXBUF = TxBuffer[Tmp++]; TxTail = (Tmp + 1) & (TX_BUFF_SIZE - 1);
if(Tmp == TxHead) // buffer empty IE1 &= ~UTXIE0; // disable tx int }
#pragma vector = USART0RX_VECTOR __interrupt void Rx232 (void) { uint8_t Tmp = RxHead; // temp. variable because RxHead is volatile RxBuffer[Tmp] = U0RXBUF; RxHead = (Tmp + 1) & (RX_BUFF_SIZE - 1); }
int putchar(int symbol) { uint8_t Tmp = TxHead; // temp. variable because TxHead is volatile while(( (Tmp - TxTail) & (TX_BUFF_SIZE - 1)) == (TX_BUFF_SIZE - 1)); // wait while buffer full
TxBuffer[Tmp] = symbol; TxHead = (Tmp + 1) & (TX_BUFF_SIZE - 1);
IE1 |= UTXIE0; // enable tx int return (1); }
int getchar(void) { uint8_t Tmp = RxTail; // temp. variable because RxTail is volatile int Symbol;
while(RxHead == Tmp); // wait while buffer empty
Symbol = RxBuffer[Tmp]; RxTail = (Tmp + 1) & (RX_BUFF_SIZE - 1); return Symbol; }
int hasinput(void) { uint8_t Tmp = RxTail; // temp. variable because RxTail is volatile return RxHead - Tmp; }
int puts(const char * string) { char c; while (c = *string++) putchar(c); } Цитата(HARMHARM @ Jan 8 2007, 12:58)  2. При работе с RS485 я лично делаю так: при начале передачи даю разрешение на драйвер и отключаю прерывание RX, чтобы не принять свою собственную посылку если что. В конце передачи запрещаю драйвер, читаю RXBUF дабы очистить флаги и уже потом разрешаю прерывание RX. Зачем такие сложности если можно отключить прием ( ME1 &= ~URXE0 )? Цитата(HARMHARM @ Jan 8 2007, 15:58)  Код прерываний у Вас, похоже, рабочий. Похоже, что нет. Когда все передано прерывание передачи не запрещается и в буфер ничего не пишется. Таким образом программа постоянно после выхода из обработчика передачи снова попадает в него же.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
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
|
|
|
|
Сообщений в этой теме
AlHakim Тема может быть избита. не понимаю как оргнизовать работу UART по прерывания(+) Jan 8 2007, 12:58 HARMHARM Позволю себе сделать несколько замечаний.
1. При р... Jan 8 2007, 13:58 AlHakim Цитата(HARMHARM @ Jan 8 2007, 15:58) 2. П... Jan 8 2007, 14:24 HARMHARM Не успел добавить комментарии, прочтите моё сообще... Jan 8 2007, 14:30 rezident Цитата(Сергей Борщ @ Jan 8 2007, 16:54) Ц... Jan 8 2007, 15:33  Сергей Борщ Цитата(rezident @ Jan 8 2007, 14:33) Пере... Jan 8 2007, 21:12  AHTOXA Цитата(zltigo @ May 5 2008, 22:05) Можно ... May 6 2008, 18:30   zltigo Цитата(AHTOXA @ May 6 2008, 20:30) Или же... May 7 2008, 05:38    Сергей Борщ Цитата(zltigo @ May 7 2008, 08:38) Просто... May 7 2008, 06:50   MrYuran Цитата(rezident @ May 6 2008, 21:42) Для ... May 7 2008, 04:39    AHTOXA Цитата(MrYuran @ May 7 2008, 10:39) Я вот... May 7 2008, 04:59     MrYuran Цитата(AHTOXA @ May 7 2008, 07:59) Тогда ... May 7 2008, 05:05      AHTOXA Цитата(MrYuran @ May 7 2008, 11:05) ну да... May 7 2008, 05:19    rezident Цитата(MrYuran @ May 7 2008, 10:39) А я в... May 7 2008, 08:56     Сергей Борщ Цитата(rezident @ May 7 2008, 11:56) Флаж... May 7 2008, 10:05 AlHakim Цитата(Сергей Борщ @ Jan 8 2007, 16:54) П... Jan 8 2007, 15:05 Dog Pawlowa У меня рабочий код. Пока тут в грязь не ткнули
... Jan 8 2007, 15:27 Сергей Борщ Цитата(AlHakim @ Jan 8 2007, 14:05) Цитат... Jan 8 2007, 15:41 jorikdima Посматрите AppNotes на сайте TI. Для каждого семей... Jan 8 2007, 15:25 AlHakim Сергей Борщ Попробовал использовать Ваш код, полу... Jan 8 2007, 15:41 Сергей Борщ Цитата(AlHakim @ Jan 8 2007, 14:41) Серге... Jan 8 2007, 16:15 VAI А я был уверен, что выкладывал и прием и передачу ... Jan 8 2007, 15:51 jorikdima http://www.ti.com/litv/zip/slac015k
тут простейшие... Jan 8 2007, 16:24 AlHakim Спасбо всем, а в особенности Сергею Jan 8 2007, 18:46 Kurt вопрос действительно уже не раз поднимавшийся и в ... May 7 2008, 05:28 Dog Pawlowa Оппа...
Понадобилось перевести передачу на прерыва... Sep 20 2014, 18:37 Genadi Zawidowski После добавления чего-то в буфер вызвать (запретив... Sep 20 2014, 19:00 Dog Pawlowa Цитата(Genadi Zawidowski @ Sep 20 2014, 22... Sep 20 2014, 19:56
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|