|
Тема может быть избита. не понимаю как оргнизовать работу 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; } }
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 30)
|
Jan 8 2007, 13:58
|

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

|
Позволю себе сделать несколько замечаний. 1. При работе не атомарными операциями с разделяемыми переменными надо или вводить атомарные флаги или запрещать прерывания, как Вы правильно заметили. 2. При работе с RS485 я лично делаю так: при начале передачи даю разрешение на драйвер и отключаю прерывание RX, чтобы не принять свою собственную посылку если что. В конце передачи запрещаю драйвер, читаю RXBUF дабы очистить флаги и уже потом разрешаю прерывание RX. Такая схема откатана и работает. Делаю так всегда, даже если у чипа RS485 есть запрещение приёма. 3. Не совсем понимаю логику работы с TX. Не проще ли сделать так: При необходимости передать один байт и подождать завершения передачи - запретить прерывание TX, положить байт в TXBUF и ждать флага. При необходимости передать один байт и не ждать завершения - запретить прерывание TX, положить байт в TXBUF и больше ничего не делать. При необходимости передать несколько байт и подождать завершения передачи - разрешить прерывание TX, положить байт в TXBUF и передавать остальные байты по прерыванию. 4. Код прерываний у Вас, похоже, рабочий. Еще не совсем понятна конструкция Код URCTL1 &= ~ (FE+PE+OE+BRK+RXERR); // Clear error flags ибо Reading UxRXBUF resets the receive-error bits, the RXWAKE bit, and URXIFGx. И еще причем здесь URCTL1? Вы ведь испольуете первый USART?
Сообщение отредактировал HARMHARM - Jan 8 2007, 14:31
|
|
|
|
|
Jan 8 2007, 14:24
|
Участник

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

|
Цитата(HARMHARM @ Jan 8 2007, 15:58)  2. При работе с RS485 я лично делаю так: при начале передачи даю разрешение на драйвер и отключаю прерывание RX, чтобы не принять свою собственную посылку если что. В конце передачи запрещаю драйвер, читаю RXBUF дабы очистить флаги и уже потом разрешаю прерывание RX. Такая схема откатана и работает. Делаю так всегда, даже если у чипа RS485 есть запрещение приёма. ну вообщем-то код пишетс яне только для работы по Rs485. Так и сделал уже(запрещаю прерывания) Код прерываний у Вас, похоже, рабочий. Еще не совсем понятна конструкция Цитата(HARMHARM @ Jan 8 2007, 15:58)  Код URCTL1 &= ~ (FE+PE+OE+BRK+RXERR); // Clear error flags ибо Reading UxRXBUF resets the receive-error bits, the RXWAKE bit, and URXIFGx. И еще причем здесь URCTL1? Вы ведь испольуете первый USART? Ошибочка закралась, да и точно снимаются они чтением UxRXBUF Спасибо
|
|
|
|
|
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)
|
|
|
|
|
Jan 8 2007, 15:05
|
Участник

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

|
Цитата(Сергей Борщ @ Jan 8 2007, 16:54)  Похоже, что нет. Когда все передано прерывание передачи не запрещается и в буфер ничего не пишется. Таким образом программа постоянно после выхода из обработчика передачи снова попадает в него же. я не утвержадю что рабочий на все 100, но повторного вхождни я впрерывание не проихслжит поскольку аппаратно в перрывание снимается бит UTXIFG0 Попробую использовать ваш код вот еще возникла пролемка, если не сложно прокомментируйте while(*str) Uart0PutChar(*str++); //*s++=Tmpchar; странно передает н мой текст а часть его плюс мусор в отлачике по шагам проходит в run-time не всегда, чаще нет, видимо используемые регистры в перрывание изменяются
|
|
|
|
|
Jan 8 2007, 15:27
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
У меня рабочий код. Пока тут в грязь не ткнули Пожалуйста Линейный буфер, slave, timer декрементируется 1мс, Service вставляется в основной цикл программы. Код //pc DOMP protocol char rx_buf1[RxBufSize1]; char *rx_head1; char *rx_tail1; char tx_buf1[TxBufSize1]; char *tx_head1; char *tx_tail1; char domp_status; char usart1_last_received;
void Uart1Configuration9600(void) { U1CTL = CHAR+SWRST; // 8-bit character and reset, 8N1 U1TCTL = SSEL0+SSEL1; // UCLK = SMCLK (8MHz) U1BR0 = 0x00; // 7372800/9600 - 768 or 300h U1BR1 = 0x03; // U1MCTL = 0x00; ME2 &= ~(UTXE1 | URXE1); // Disable USART1 TXD/RXD U1CTL &=~SWRST; // end of reset rx_tail1=rx_buf1; rx_head1=rx_buf1; IE2 &= ~(URXIE1|UTXIE1); // Disable USART1 RX and TX interrupt }
void ClearTxBuffer1(void) { __disable_interrupt(); tx_tail1 = tx_head1 = tx_buf1; __enable_interrupt(); }
void ClearRxBuffer1(void) { rx_tail1 = rx_head1 = rx_buf1; }
void EnableReceiver1 ( void ) { ClearRxBuffer1(); // ME2|= URXE1; // receiver enable IE2|=URXIE1; // receive interrupt enable // UCSR0A &= ~ ( 1 << RXC0 ); // set receiver empty bit }
void Uart1Configuration(void) { Uart1Configuration9600(); tx_tail1 = tx_head1 = tx_buf1; // without interrupt enable EnableReceiver1(); }
void EnableTransmitter1 ( void ) {// tx_tail1=tx_buf1; // transmitt from beginning ME2|= UTXE1; // transmitter enable IFG2|=UTXIFG1; // set transmitter empty bit IE2|=UTXIE1; // transmitt interrupt enable }
#pragma vector=UART1TX_VECTOR __interrupt void USART1_transmit(void) { if ((domp_status==DompTransmitting) && (tx_tail1<tx_head1)) { TXBUF1 =*tx_tail1; tx_tail1++; } else { IE2&=~UTXIE1; // transmitt interrupt disable // ME2&= UTXE1; // transmitter enable IFG2&=~UTXIFG1; // clear transmitter empty bit domp_status_timer = 2; domp_status = DompWaitReceiving; } }
#pragma vector = UART1RX_VECTOR __interrupt void USART1_receive(void) { usart1_last_received=U1RXBUF; // this two lines for Echo // TXBUF1 = b; // EnableTransmitter1();
if (domp_status == DompWaiting) { if (usart1_last_received == START_RX_CHAR) { rx_head1 = rx_buf1; domp_status = DompReceiving; } else return; } if (domp_status == DompReceiving) { *rx_head1 = usart1_last_received; rx_head1 ++; if (rx_head1 >= rx_buf1+RxBufSize1) domp_status=DompProcessing; if (usart1_last_received == END_RX_CHAR) domp_status=DompProcessing;
} } /* #pragma vector = USART0_TXC_vect __interrupt void USART_transmit_complete(void) { usart_status_timer = 2; domp_status = UsartWaitReceiving; } */
void DompService(void) { char b; switch (domp_status)
{ case DompUnconfigured: Uart1Configuration(); // SetReceiveDirection; ClearRxBuffer1(); domp_status = DompWaiting; break; case DompWaiting: domp_status_timer = 2000; // time for receiving break; case DompReceiving: if (!domp_status_timer) domp_status = DompUnconfigured; break; case DompProcessing: b = MyCorrectCommand(); if (!b) { ExecuteCommandAndPrepareAnswer(); domp_status = DompWaitTransmitting; domp_status_timer=5; } else { domp_status = DompWaitReceiving; domp_status_timer = 1; } break; case DompWaitTransmitting: if (domp_status_timer == 0) { SetTransmitDirection; domp_status = DompTransmitting; domp_status_timer = 500; tx_tail1=tx_buf1; // EnableTransmitter1(); !!! } break; case DompTransmitting: if (!domp_status_timer) { domp_status = DompUnconfigured; } break; case DompWaitReceiving: if (domp_status_timer == 0) { ClearRxBuffer1(); SetReceiveDirection; domp_status = DompWaiting;//UsartReceiving; } break; } }
char Usart1EchoTest(void) { char b; Delay(2); b=rtc_data[rtcSecond]; TXBUF1=b; ME2|= UTXE1|URXE1; Delay(10); if (U1RXBUF==b) b=1; else b=0; domp_status=DompUnconfigured; return(b); } Жуткие следы выбора размера табуляций и портирования с АВР
Сообщение отредактировал Dog Pawlowa - Jan 8 2007, 15:44
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jan 8 2007, 15:41
|

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

|
Цитата(AlHakim @ Jan 8 2007, 14:05)  Цитата(Сергей Борщ @ Jan 8 2007, 16:54)  Похоже, что нет. Когда все передано прерывание передачи не запрещается и в буфер ничего не пишется. Таким образом программа постоянно после выхода из обработчика передачи снова попадает в него же.
я не утвержадю что рабочий на все 100, но повторного вхождни я впрерывание не проихслжит поскольку аппаратно в перрывание снимается бит UTXIFG0 В каком месте снимается? Я вижу что если передавать больше нечего то все закомментировано. Цитата while(*str) Uart0PutChar(*str++); //*s++=Tmpchar; странно передает н мой текст а часть его плюс мусор в отлачике по шагам проходит в run-time не всегда, чаще нет, видимо используемые регистры в перрывание изменяются  Uart0Tx.PtrWrByte и Uart0Tx.PtrRdByte объявлены как volatile? Скорее всего нет, иначе компилятор выдавал бы предупреждения на конструкции вроде if (Uart0Tx.PtrWrByte != Uart0Tx.PtrRdByte). Дальше уже может твориться все что угодно. Еще может не хватать стека - для начала увеличьте его размер.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 8 2007, 15:41
|
Участник

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

|
Сергей Борщ Попробовал использовать Ваш код, получил тоже само что и было у мен явначале программа зациклилась Код while(( (Tmp - TxTail) & (TX_BUFF_SIZE - 1)) == (TX_BU причем Uart0PutChar(0x30); - выполняется, а Uart0PutStr("qwe"); зацикливается
Сообщение отредактировал AlHakim - Jan 8 2007, 15:52
|
|
|
|
|
Jan 8 2007, 16:15
|

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

|
Цитата(AlHakim @ Jan 8 2007, 14:41)  Сергей Борщ Попробовал использовать Ваш код, получил тоже само что и было у мен явначале программа зациклилась Код while(( (Tmp - TxTail) & (TX_BUFF_SIZE - 1)) == (TX_BU причем Uart0PutChar(0x30); - выполняется, а Uart0PutStr("qwe"); зацикливается Извиняюсь, в прерывании ошибку допустил. Должно быть так: Код #pragma vector = USART0TX_VECTOR __interrupt void Tx232(void) { uint8_t Tmp = TxTail; // temp. variable because TxTail is volatile
U0TXBUF = TxBuffer[Tmp]; TxTail = Tmp = (Tmp + 1) & (TX_BUFF_SIZE - 1);
if(Tmp == TxHead) // buffer empty IE1 &= ~UTXIE0; // disable tx int }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 8 2007, 18:46
|
Участник

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

|
Спасбо всем, а в особенности Сергею
|
|
|
|
|
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, то передача после первого байта блокируется. Это понятно - нет фронта флага, он повис. Если дергать (устанавливать) флаг готовности передачи в момент добавления в буфер очередного символа, то символы пропадают - тоже понятно - срабатывает прерывание по передаче, когда передача еще идет.
Я конечно найду решение до понедельника, но если кто имеет решение, прошу поделиться. Спасибо.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Sep 20 2014, 19:56
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Genadi Zawidowski @ Sep 20 2014, 22:00)  обычную функцию проверки готовности и разрешения прерывания Ага, спасибо! Уже запустил с отдельным флагом, в принципе можно в качестве флага разрешение и использовать, но переделывать уже не буду: Инициализация: Код OffFlag(tx_over); tx_head0=tx_tail0=0; IE1 |= URXIE0+UTXIE0; Укладка в буфер (DI/EI обязательны!) Код __disable_interrupt(); PUT_TO_BUFFER(c);
#ifdef TX_INTERRUPT if (GetFlag(tx_over)) { IFG1 |= UTXIFG0; OffFlag(tx_over); } #endif __enable_interrupt(); Ну и прерывание: Код if (tx_tail0!=tx_head0) { d=tx_buf0[tx_tail0]; tx_tail0++; if (tx_tail0==TxBufSize0) tx_tail0=0; TXBUF0 = d; } #ifdef TX_INTERRUPT else OnFlag(tx_over); #endif
--------------------
Уходя, оставьте свет...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|