MSP430F6736A UART发送数据到PC出现乱码问题求助
问题描述
本人基于MSP430F6736A开展嵌入式编程开发,开发环境为Code Composer Studio。当前编写的程序可正常编译通过,但UART向PC端发送数据时,PC仅能接收到.ø€.ø€.€€x这类乱码字符,无法获取正确的采集结果,具体实现代码如下:
#include "msp430g2553.h" #include <stdio.h> float RLDR=0, lux=0, v0=0; unsigned int ADC10_vetor[16]={0}; unsigned int sum=0; unsigned char i=0; unsigned char TX_data[32], tx_index = 0, lux_int =0; void ini_ucon(void); void ini_p1_p2(void); void ini_Timer0(void); void ini_ADC10(void); void ini_USCI_UART(void); void ini_ucon(void){ WDTCTL = WDTPW | WDTHOLD; DCOCTL = CALDCO_8MHZ; BCSCTL1 = CALBC1_8MHZ; BCSCTL2 = DIVS0 + DIVS1; //SMCLK = 1MHz __enable_interrupt(); } void ini_p1_p2(void){ P1DIR = 0xFF; P1OUT = 0x00; P2DIR = 0xFF; P2OUT = 0x00; } void ini_Timer0(void){ TA0CTL = TASSEL1 + ID1 + ID0 + MC0; //SMCLK = 1MHz/8 = 125000 TA0CCTL1 = OUTMOD0 + OUTMOD1 + OUTMOD2 + OUT; TA0CCR0 = 62499; //2Hz = 0.5 secs. , TA0CCR0 = 0.5*125000 - 1 = 62499 TA0CCR1 = 31249; //PWM = 50% } void ini_ADC10(void){ ADC10CTL0 = ADC10SHT1 + MSC + ADC10ON + ADC10IE; ADC10CTL1 = INCH0 + INCH2 + SHS0 + ADC10SSEL1 + CONSEQ1; ADC10AE0 = BIT5; //P1.5 para A5 ADC10DTC0 = 0; ADC10DTC1 = 16; ADC10SA = &ADC10_vetor[0]; ADC10CTL0 |= ENC; } int main(void){ ini_ucon(); ini_p1_p2(); ini_Timer0(); ini_ADC10(); ini_USCI_UART(); while(1){ } } #pragma vector=ADC10_VECTOR __interrupt void ADC10_RTI(void){ ADC10CTL0 &= ~ENC; soma = 0; for(i=0;i<16;i++){ sum = sum + ADC10_vetor[i]; } sum = sum >> 4; //RLDR = (42625000)/(3*sum)-10000; //lux = 500/(RLDR/1000); //v0=5*(sum/(sum+10000)); v0=sum*(3.6/1024); RLDR = (10000*(5-v0))/v0; lux = (500/(RLDR/1000)); lux_int = (unsigned char) lux; sprintf(&TX_data[0], "LUX = %d \n", lux_int); UCA0TXBUF = TX_data[0]; tx_index++; ADC10SA = &ADC10_vetor[0]; ADC10CTL0 |= ENC; } #pragma vector=USCIAB0TX_VECTOR __interrupt void RTI_USCI_UART(void) { IFG2 &= ~UCA0TXIFG; if(TX_data[tx_index] == '\0'){ tx_index = 0; }else{ if(tx_index >= 32){ tx_index = 0; }else{ UCA0TXBUF = TX_data[tx_index]; tx_index++; } } } void ini_USCI_UART(void){ UCA0CTL1 |= UCSWRST; UCA0CTL0 = 0; UCA0CTL1 = UCSSEL0 + UCSSEL1 + UCSWRST; UCA0BR0 = 0xA0; UCA0BR1 = 0x01; UCA0MCTL = UCBRS1 + UCBRS2; UCA0STAT = 0; P1SEL |= BIT2; P1SEL2 |= BIT2; UCA0CTL1 &= ~UCSWRST; IFG2 &= ~UCA0TXIFG; IE2 |= UCA0TXIE; }
故障产生原因
UART乱码本质是通讯两端时序、参数不匹配,或传输过程中数据错位,这段代码的核心问题如下:
- 头文件与目标芯片完全不匹配:实际使用MSP430F6736A,代码却引入MSP430G2553的头文件,两款芯片的寄存器地址、时钟校准常量存储位置、外设引脚映射完全不同,直接导致时钟、波特率、外设配置全部失效。
- 时钟配置失效:代码调用的
CALDCO_8MHZ、CALBC1_8MHZ是G2系列的DCO校准常量,F6736A对应地址存储的不是校准值,配置后DCO实际运行频率和预期8MHz偏差极大,SMCLK分频后也不是注释标注的1MHz,波特率发生器输入时钟不准,输出波特率完全错误。 - 波特率配置不匹配:代码中波特率分频值
0x01A0对应1MHz时钟下约2400波特,调制参数UCBRS1 + UCBRS2配置也存在错误,绝大多数场景下PC端串口助手默认使用9600/115200波特率,两端参数不一致必然出现乱码。 - 发送逻辑存在竞态bug:ADC中断中直接操作TXBUF发送首字节、修改tx_index,没有判断上一次数据是否发送完成,容易和UART发送中断冲突,导致数据错位、字节丢失;同时存在未定义变量
soma、TX_data缓冲区长度不足易溢出、手动清除UCA0TXIFG标志易丢中断的问题,进一步加剧数据错误。 - 引脚映射错误:代码按照G2553的映射把P1.2配置为UART发送引脚,F6736A的UART外设引脚位置和G2553不一致,配置后引脚根本没有连接到UART外设,输出波形完全不符合协议要求。
修复方法
- 替换匹配头文件:将首行
#include "msp430g2553.h"替换为#include "msp430f6736a.h",确保所有寄存器、中断向量、校准值的定义和实际芯片匹配。 - 重新配置时钟:按照F6736A用户手册说明配置DCO时钟,不要直接套用G2系列的校准宏,配置完成后可通过示波器测量SMCLK引脚输出,确认时钟频率和预期一致。
- 对齐波特率参数:先确定PC端串口助手使用的波特率,再根据实际SMCLK频率,对照芯片手册的波特率配置表设置分频值和调制参数。例如SMCLK为1MHz、波特率9600时,正确配置为:
同时确认PC端串口参数为8位数据位、1位停止位、无校验、无流控,和MCU配置完全一致。UCA0BR0 = 0x65; UCA0BR1 = 0x00; UCA0MCTL = UCBRS_1; - 修正引脚配置:查阅F6736A数据手册,找到UART TX功能对应的引脚,配置对应引脚的SEL寄存器为外设功能模式,不要套用G2553的P1.2映射。
- 修复代码逻辑bug:
- 删除未定义的
soma = 0;语句,替换为sum = 0; - 增加发送状态判断,只有当
tx_index == 0(即上一次字符串发送完成)时,才在ADC中断中调用sprintf填充TX_data,再触发首字节发送,避免打断正在进行的传输导致数据错位。 - 将TX_data数组长度扩大到64字节,避免sprintf生成的字符串长度超过32字节导致缓冲区溢出踩内存。
- 删除发送中断里手动清除
UCA0TXIFG的语句,该标志由硬件自动清零,手动操作容易导致中断丢失。
- 删除未定义的
内容的提问来源于stack exchange,提问作者Jonas F.
相关产品推荐
相关产品推荐

