#include <msp430.h>
static int next = 0;
#pragma vector=USCI_A0_VECTOR
interrupt void bc_uart_irq(void) {
int transmit_flag = UCA0IFG & UCTXIFG;
if (transmit_flag && next == 0) {
next = 1;
UCA0TXBUF = 0x01; // should clear UCTXIFG
} else if (transmit_flag) {
next = 0;
UCA0TXBUF = 0x55; // should clear UCTXIFG (doesnt!)
}
}
/**
* main.c
*/
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
// Setup UART pins
P3SEL |= 0x18; // default UCA0TXD/UCA0RXD on P3.3/4
P3DIR |= BIT3 + BIT4;
// source TA0 from SMCLK for debugging
TA0CTL = 0x0220;
UCA0CTL1 |= UCSWRST;
// source USCIA0 from SMCLK
UCA0CTL1 |= UCSSEL__SMCLK;
// set USCI module to UART mode
UCA0CTL0 &= ~UCSYNC;
// configure UART
UCA0CTL0 &= ~UCPEN; // no parity bit
UCA0CTL0 &= ~UC7BIT; // 8-bit data
UCA0CTL0 &= ~UCMSB; // LSB first
UCA0CTL0 &= ~UCMODE0; // UART mode (00)
UCA0CTL0 &= ~UCMODE1;
// Set baud rate to 9600 (br = 104, brs = 1, brf = 0)
UCA0BR0 = 107;
UCA0BR1 = 0;
UCA0MCTL = 0x02; // UCBRSx = 1
UCA0CTL1 &= ~UCSWRST;
UCA0IE |= 0xFFFF; // enable tx and rx interrupts
__bis_SR_register(GIE);
while(1) {}
return 0;
}
我花了一段时间对此进行调试,在所有情况下,将数据转储到传输缓冲区都不会自动清除该标志(我也尝试在中断中自己清除它)并且不会将 UCBUSY 设置为高电平。我还尝试使用 A1 UART 模块而不是 A0,将引脚排列移至 4.4/5(正如我在其他一些问题中看到的那样)、不同的时钟(我最初有 ACLK),以及将 UCLISTEN 位设置为高。 我不确定我还能尝试什么,因为这似乎与我见过的其他问题的代码相同。我已经确认 SMCLK 正在运行,因为定时器随着调试器的每一步而上升;最合理的罪魁祸首是时钟根本没有到达 USCI 外设,但我不知道这是否属实,也不知道如何测试它。 (我正在使用 CCS,唯一奇怪的事情是,如果数据内存模型不小(代码很大),编译器会对我大喊大叫)。
首先,在 if/else 两种情况下切换引脚,并使用逻辑分析仪或示波器检查软件是否确实进入这些块。只有在那里,您才能确定您进入了写入传输缓冲区的块。
其次,尝试使用参考手册中推荐的中断例程:
#pragma vector = USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) {
switch(__even_in_range(UCA0IV,18)) {
case 0x00: // Vector 0: No interrupts
break;
case 0x02: // Vector 2: UCRXIFG
break;
case 0x04: // Vector 4: UCTXIFG
if (next == 0) {
next = 1;
UCA0TXBUF = 0x01;
} else {
next = 0;
UCA0TXBUF = 0x55;
}
break;
case 0x06: // Vector 6: UCSTTIFG
break;
case 0x08: // Vector 8: UCTXCPTIFG
break;
default: break;
}
}
事实证明,如果没有电线连接到 TX 缓冲区,则 TX 缓冲区实际上并不会清空,因此该标志永远不会被设置。除此之外,当使用 CCS 调试器时,单步执行对 TXBUF 的更新并没有显示中断标志已自动重置,但在设备实际自行运行时确实会发生这种情况。