TI中文支持网
TI专业的中文技术问题搜集分享网站

关于MSP430F5438 Uart 通信问题,请高人来指点!

       利用MSP430F5438来和外设进行串口通信,具体为MSP430F5438向外设发送一串字符串,然后外设根据这串字符串进行相应回复。利用中断来进行串口数据的收取,双方的码率等配置都是一致的,但是发现430发送完后,可能是外设响应回复的过快导致收取一串字符串数据,只接收到字符串的最后一个字节。通过PC端的串口调试助手和外设通信是良好的。并且通过PC端的串口调试助手模拟外设和MSP430F5438通信,发现430发起通信发送数据后,PC端立即点击发送数据后,加断的点调试过程中,和之前外设与430通信的情况一致,为只能收到字符串的最后一个字节。若等430发起通信发送数据后,稍迟延一点,在再PC端点击发送数据,加断点发现,整个一个字符串的数据是完整的。所以来请高人来指点迷津,非常感谢。

kqian0327:

你好,

所谓外设是另外一个MCU设备吗?

我比较关心的是你是如何发送发送UART数据的,是否在发送数据之后while循环,等待该帧数据全部发送出去?

ZHIchen TU:

回复 kqian0327:

您好!非常感谢您的回复,具体外设为GSM模块通过串口与430进行数据和命令交互。发送数据没有通过中断的方式。

通过以下函数实现单个字节的发送。发送一帧的数据也是调用这个函数实现一个一个字节的发送的。发送一帧的数据也通过串口调试助手可以确定为正确无误的。

void Uart_Send_Char(unsigned char data){        while (!(UCA0IFG&UCTXIFG)); // USCI_A1 TX buffer ready?        UCA0TXBUF = data; // TX -> data_cache character}

以下为串口的配置

void InitializeUart(void){ P3SEL = 0x30; // P3.4,5 = USCI_A0 TXD/RXD UCA0CTL1 |= UCSWRST; // **Put state machine in reset** UCA0CTL1 |= UCSSEL_1; // CLK = ACLK UCA0BR0 = 0x03; // 32kHz/9600=3.41 (see User's Guide) UCA0BR1 = 0x00; // UCA0MCTL = UCBRS_3+UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt}

若立即通过PC端串口调试助手回复后,我在接受中断函数中建立一个缓存区,如下。我一帧数据为6个字节,icounter_test全局变量初值为0,一开始在icounter_test = 0;这里加断点,若立即回复后发现程序没有在断点处停下来,我手动将程序停下来,观察缓存去中只有字符串的最后一个字节,但若稍微迟一点儿回复后,发现程序可以在断点处停下来的,并且缓存去中也为6个字节的数据。后来我又取消了刚才的断点,在 icounter_test++;这里添加断点,然后用串口调试助手,马上回复一串数据,按理来说这里,即为收到第一个字节的数据就程序停下来了, UCA0RXBUF的数据应该为一帧数据的第一个字节,但是发现此时停下来后, UCA0RXBUF的数据为一帧数据的最后一个字节。故这里为问题的所在。所以想要咨询一下,430的uart模块应该在RX和TX都有响应的缓存区,两者之间应该不干扰的,为什么430在发送后马上有数据回复后出现丢数据的现象呢?

// Echo back RXed character, confirm TX buffer is ready first#pragma vector=USCI_A0_VECTOR__interrupt void USCI_A0_ISR(void){ switch(__even_in_range(UCA0IV,4)) { case 0:break; // Vector 0 – no interrupt case 2: // Vector 2 – RXIFG     uchar Rec_temp;     Rec_temp = UCA0RXBUF;     icounter_test++;     UART_RX_Buffer[UART_RX_Status++] = UCA0RXBUF;     if(icounter_test == 6)     {            icounter_test = 0;       } break; case 4:break; // Vector 4 – TXIFG default: break; }}

kqian0327:

回复 ZHIchen TU:

你好,

你的波特率设置的是多少?9600?

你确定是你发送一帧数据之后才有接收中断的,有没有可能是程序的逻辑上市在发送数据的时候,就还是有RX数据?

提高波特率会不会有改善?

另外,你程序是只有RX中断这一个中断源,不会有其他中断源了吧?

ZHIchen TU:

回复 kqian0327:

您好!非常感谢您的回复。

1.波特率为9600。

2.您说“没有可能是程序的逻辑上市在发送数据的时候,就还是有RX数据”这个的意思是,我在收取数据的时候有可能这时候MCU还在用uart在往外发数据吗? 这个时候没有新的数据在用uart往外发了。我在初始配置的时候,没有开启发送的中断的使能,如按您说的,此时若最后MCU这端发送后,可能会影响到接收的中断请求吗?

3.因为GSM模块默认的波特率为9600,故暂时无法实验提高波特率。

4.我程序里包含其他的中断源,但是相应的其他中断源都没有使能,但是总中断源是开的。

请您再来指点迷津,非常感谢。

ZHIchen TU:

回复 kqian0327:

您好!非常感谢您的回复

1.波特率为9600

2.您说“有没有可能是程序的逻辑上市在发送数据的时候,就还是有RX数据”的意思是,我在接收的同时可能这里MCU有新的数据要通过Uart向外发送吗?但是我这里没有新的数据要通过uart向外发送,并且我在初始化uart配置时,也没有在uart的发送中断使能。

3.因为GSM模块默认的波特率为9600,故无法实验提高波特率

4.初始化配置的时候配置了其他中断,但没有使能,并且开启了总中断。

还麻烦您能指点迷津。

step by step:

回复 ZHIchen TU:

楼主,

  你好,程序上看应该没有什么问题,有两点:

1.     uchar Rec_temp;     Rec_temp = UCA0RXBUF;这两句应该是你为了调试加的吧

2. 楼主主频用的是32k吗?时钟源是DCO吗?将主频提高会不会有改善?

如果方便的话楼主能不能用示波器抓取整个过程中TXD和RXD的波形一起分析一下?

ZHIchen TU:

回复 step by step:

您好!非常感谢您的回复。

您说的细节的话,刚开始我的系统MCLK和SMCLK用的是DCO,然后跑在12M,出现问题后,我怀疑是uart在接收数据后,MCU这边中断程序可能执行不够快,导致收一串数据,只能收到最后一个字节。所以我又用了外部晶振XT2,为25M。ACLK的话,是XT1,用的32K的晶振。波形的话我去实验室截下屏再发上来好了。

我仔细又看看了User Gudie,我能否可以通过UCAxSTAT寄存器中的UCRXERR或者UCOE位来判断是否我在UCA0RXBUF的数据(会清此时的接收中断标志位)前又有新的数据到来了,导致多个接收数据到来,但是我的MCU端来不及响应。导致数据丢失,只能收到最后一个字节?

非常感谢您的指点迷津。

赞(0)
未经允许不得转载:TI中文支持网 » 关于MSP430F5438 Uart 通信问题,请高人来指点!
分享到: 更多 (0)