zoukankan      html  css  js  c++  java
  • STM32之USART库函数USART_SendData的bug

    转载自:http://www.cnblogs.com/itloverhpu/p/3250537.html

    1.最近在调试ATM32F103CB时发现,一串数据的最后一个字节总是发送不出去,用的是RS485收发;

    2.代码如下:

        void uartReturn(unsigned char childBoardAddr)

     uchar temp = 0;  //must have
      
     temp += 0xAB;
      temp += childBoardAddr;
      temp += 0x30;
      temp += 0x01;
      temp += childBoardAddr;
     
     RS485_TX_EN;  //enable rs485 tx 
     
     sendByte(0xAB);
     sendByte(childBoardAddr);
     sendByte(0x30);
     sendByte(0x01);
     sendByte(childBoardAddr);
     sendByte(temp);
     
     RS485_RX_EN;  //enable rs485 rx 
    }

    其中:sendByte函数如下:

      void  sendByte( unsigned char data)
    {
      //RS485_TX_EN; 
      USART_SendData( USART2,data );
      while( USART_GetFlagStatus( USART2,USART_FLAG_TXE ) == RESET ); //数据没有被传入输出移位寄存器,则一直等待下去 
      //RS485_RX_EN;
    }

    同事帮忙改了一下lib库函数:USART_SendData,在其后面加了: while((USARTx->SR&0x40)==0);//////////发现最后一字节数据会漏发,才加上的;

    这调语句可不就是等价于:while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET)吗;

    >>>>>>>>来看看网上是怎么说的?

    用串口连续发送一串数字时,第一个数总是发不出去,我用STM32F103ZE,STM32F103CB都是这样的情况,以下是代码:
    USART_SendData(USART1,0x06);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
    USART_SendData(USART1,0x07);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
    USART_SendData(USART1,0x08);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);

    呵呵,第一字节发送不出去,看网友是怎么分析解答的吧:

    1:这个问题的根本原因是复位后,TC和TXE标志位默认都是1,很多人喜欢这样写: 
        USART_SendData(USART1, (u8) ch);  while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)  
        while在发送第一个字节时没有起到应有作用,直接跳出,接着写第二个字节,这时第一个字节还未发出,数据被破坏了.

    看看datasheet,果然复位以后,SR=0x00c0;TC=TXE=1;

    疑问:为什么网友说:只要第一个用TXE,其它用什么标志无所谓,都能正常发送。按道理,TXE也没起到保护啊!!!

    2.while的确很费时,另外当TDR寄存器中的数据被硬件转移到移位寄存器的时候,TXE被硬件置位(注意:单缓冲器传输中使用该位);当包含有数据的一帧发送完成后,并且TXE=1时,由硬件将该位置’1’,只有在多缓存通讯中才推荐这种清除程序。其中TC判断的是一帧数据,而TXE是当TDR数据传到移位寄存器就被置位了,所以TC的时间比较长,很容易被下一次数据覆盖~~~所以一般喜欢判断TXE,数据写到DR就可以了 ,剩下的工作就交给硬件了

    3.一般的用TXE就可以了, TC一般用于需要延时的场合,比如说是232/485转换器,需要得到TC后,才能将发送改变成接收,否则最后一个字节发送不完全。

     看来,3很符合我的情况:我的相当于2个等待:

            while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET;   //@1

            while( USART_GetFlagStatus( USART2,USART_FLAG_TXE ) == RESET ); //@2

    考虑一下:@2能不能拿掉呢??

  • 相关阅读:
    鲜牛奶与纯牛奶的区别 All In One
    Rough Notation Animation All In One
    java基础编程String及相关
    JDBC1
    java基础数据类型
    java基础编程
    JDBC3
    MYSQL1
    JDBC2
    JSP和Servlet的相同点和不同点,他们之间的联系
  • 原文地址:https://www.cnblogs.com/wupengda/p/4090100.html
Copyright © 2011-2022 走看看