This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430G2553:从计时器回调运行时通过 UART 进行写入时出现问题

Guru**** 2564565 points
Other Parts Discussed in Thread: MSP430G2553

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/605442/msp430g2553-problem-writing-through-the-uart-when-running-from-a-timer-callback

器件型号:MSP430G2553

大家好、我将开始学习如何使用 Launchpad 对 msp430g2553进行编程。 我有自己的库可以通过 UART 进行写入。 这可以正常工作。 另一方面、我将使用该计时器库:

两个库单独正常工作、但当我尝试使用这两个库时、我遇到了问题、并且我不知道如何查找错误。 正如您在主代码中看到的、我最初通过 UART 'Hello World'进行写入、然后启动两个计时器。 第一个计时器每秒闪烁一次绿色 LED、第二个计时器每五秒通过 UART 写入一次"再见"。 前五次闪烁正常、但当第二个计时器运行"timeToGo"回调时、绿色 LED 停止闪烁、并且不会通过 UART 写入任何内容。 我想这是因为执行线程在'uartWriteChar'方法的'while'中停止、检查 UART 的写入标志。 为什么会发生这种情况? 您是否认为这是另一个原因?提前感谢。

主代码:

int timer_handle =-1;

静态 void blinkGreenLED (void *arg){

(无效) arg;
P1OUT ^= BIT6;//切换 P1.6

}

静态空时间 ToGo (空*arg){

(无效) arg;
//P1OUT ^= BIT0;//切换 P1.0
uartWriteString ((char *)"Byo\n");
}

int main (void){


WDTCTL = WDTPW + WDTHOLD; //停止 WDT
BCSCTL1 = CALBC1_1MHz; //将 DCO 设置为1MHz
DCOCTL = CALDCO_1MHz; //将 DCO 设置为1MHz

uartInit(); //初始化 UART 连接

_enable_interrupt (); //中断被启用

uartWriteString ((char *)"Hello World\n\n");

P1OUT &= 0x00; //关闭所有内容
P1DIR &= 0x00;
P1DIR |= BIT0 + BIT6; // P1.0和 P1.6引脚输出其余为输入

timer_init();

Timer_handle = timer_create (500、1、blinkGreenLED、0);
Timer_handle = timer_create (5000、1、timeToGo、0);

bis_SR_register (GIE);

while (1){}

UART.c 库:

#define LED BIT0
#define RXD BIT1
#define TXD BIT2

volatile unsigned int txFlag; Tx_char 的//邮箱标志。
volatile unsigned char txChar; //this char 是进入 UART 的最新字符

/* uartInit
*通过 USCI */

void uartInit (void)
{设置 UART 接口
P1SEL = RXD + TXD; //设置 I/O
P1SEL2 = RXD + TXD;

P1DIR |= LED; //P1.0红色 LED。 接收到字符时切换。
P1OUT |= LED; //LED 关闭

UCA0CTL1 |= UCSSEL_2; //SMCLK
//1、000、000Hz、9600Baud、UCBRx=6、UCBRSx=0、UCBRFx=1
UCA0BR0=6; //8MHz、OSC16、9600
UCA0BR1=0; //((1MHz/9600)/16)
UCA0MCTL = UCBRF3 + UCOS16; //UCBRFx=1、UCBRSx=0、UCOS16=1
UCA0CTL1 &=~UCSWRST; // USCI 状态机
IE2 |= UCA0RXIE; //启用 USCI_A0 RX 中断

rxFlag = 0; //将 rxFlag 设置为0
TxFlag = 0; //将 txFlag 设置为0

return;
}

/* uartWriteChar
*向 UART 发送 char。 如果 UART 忙
*/
void uartWriteChar (unsigned char c)
{、则将等待
txChar = c; //将 char 放入 TX_char 中
IE2 |= UCA0TXIE; //启用 USCI_A0 TX 中断
while (txFlag = 1); //必须等待 TX 缓冲区
TxFlag = 1; //重置 txFlag
return;
}

/* uartWriteString
*向 UART 发送字符串。 如果 UART 正忙、则将等待
*/
void uartWriteString (char *str) //向 UART 发送字符串。
{
while (* str) uartWriteChar (* str++); //通过字符串前进直到结束
return;
}

#pragma vector = USCIAB0TX_vector //UART TX USCI 中断
_INTERRUPT void USCI0TX_ISR (void)
{
UCA0TXBUF = txChar; //Copy char to the TX Buffer
TxFlag = 0; //ACK txFlag
IE2 &=~UCA0TXIE; //关闭中断以保存 CPU
} 

 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在中断处理程序内、中断被禁用。 因此 uartWriteString()等待从未运行的中断。

    您应该将 UART 代码更改为自动发送中断处理程序中字符串的下一个字节、这样主代码就不必等待任何内容。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的回答。 现在我了解了为什么它不起作用、但我不理解您的解决方案。 如果我直接发送每一个拜、如何确保发送器已准备好发送? 当然、它非常简单、但我从微控制器开始。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当 TXBUF 为空时、TXIFG 被置位。