Цитата(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)

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