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

 
 
> Тема может быть избита. не понимаю как оргнизовать работу UART по прерывания(+)
AlHakim
сообщение Jan 8 2007, 12:58
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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;
    }
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Сергей Борщ
сообщение Jan 8 2007, 14:54
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
rezident
сообщение Jan 8 2007, 15:33
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Сергей Борщ @ Jan 8 2007, 16:54) *
Цитата(HARMHARM @ Jan 8 2007, 15:58) *

Код прерываний у Вас, похоже, рабочий.
Похоже, что нет. Когда все передано прерывание передачи не запрещается и в буфер ничего не пишется. Таким образом программа постоянно после выхода из обработчика передачи снова попадает в него же.

Переход по вектору прерывания от передатчика автоматически сбрасывает флаг вызова прерывания. Так что лишний вызов произойдет только один раз по окончании передачи.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 8 2007, 21:12
Сообщение #4


Гуру
******

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



Цитата(rezident @ Jan 8 2007, 14:33) *
Переход по вектору прерывания от передатчика автоматически сбрасывает флаг вызова прерывания.
Да, про это я забыл, каюсь.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- 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
|- - zltigo   Цитата(Сергей Борщ @ Jan 8 2007, 16:54) В...   May 5 2008, 16:05
|- - 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
|- - rezident   Цитата(zltigo @ May 5 2008, 22:05) Можно ...   May 6 2008, 18:42
|- - 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


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

 


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


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