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.

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

Other Parts Discussed in Thread: MSP430F5438

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

  • 你好,

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

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

  • 您好!非常感谢您的回复,具体外设为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;
    }
    }

  • 你好,

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

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

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

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

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

    1.波特率为9600。

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

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

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

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

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

    1.波特率为9600

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

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

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

    还麻烦您能指点迷津。

  • 楼主,

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

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

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

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

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

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

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

    非常感谢您的指点迷津。