新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > STM32之USART庫函數(shù)USART_SendData的bug

        STM32之USART庫函數(shù)USART_SendData的bug

        作者: 時間:2016-11-19 來源:網(wǎng)絡(luò) 收藏
        1.最近在調(diào)試ATM32F103CB時發(fā)現(xiàn),一串數(shù)據(jù)的最后一個字節(jié)總是發(fā)送不出去,用的是RS485收發(fā);

        2.代碼如下:

        本文引用地址:http://www.104case.com/article/201611/318087.htm

        voiduartReturn(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函數(shù)如下:

        voidsendByte( unsigned char data)
        {
        //RS485_TX_EN;
        USART_SendData( USART2,data );
        while( USART_GetFlagStatus( USART2,USART_FLAG_TXE ) == RESET );//數(shù)據(jù)沒有被傳入輸出移位寄存器,則一直等待下去
        //RS485_RX_EN;
        }

        同事幫忙改了一下lib庫函數(shù):USART_SendData,在其后面加了:while((USARTx->SR&0x40)==0);//////////發(fā)現(xiàn)最后一字節(jié)數(shù)據(jù)會漏發(fā),才加上的;

        這調(diào)語句可不就是等價于:while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET)嗎;

        >>>>>>>>來看看網(wǎng)上是怎么說的?

        用串口連續(xù)發(fā)送一串數(shù)字時,第一個數(shù)總是發(fā)不出去,我用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);

        ,第一字節(jié)發(fā)送不出去,看網(wǎng)友是怎么分析解答的吧:

        1:這個問題的根本原因是復位后,TC和TXE標志位默認都是1,很多人喜歡這樣寫:
        USART_SendData(USART1, (u8) ch); while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
        while在發(fā)送第一個字節(jié)時沒有起到應(yīng)有作用,直接跳出,接著寫第二個字節(jié),這時第一個字節(jié)還未發(fā)出,數(shù)據(jù)被破壞了.

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

        疑問:為什么網(wǎng)友說:只要第一個用TXE,其它用什么標志無所謂,都能正常發(fā)送。按道理,TXE也沒起到保護啊!!!

        2.while的確很費時,另外當TDR寄存器中的數(shù)據(jù)被硬件轉(zhuǎn)移到移位寄存器的時候,TXE被硬件置位(注意:單緩沖器傳輸中使用該位);當包含有數(shù)據(jù)的一幀發(fā)送完成后,并且TXE=1時,由硬件將該位置’1’,只有在多緩存通訊中才推薦這種清除程序。其中TC判斷的是一幀數(shù)據(jù),而TXE是當TDR數(shù)據(jù)傳到移位寄存器就被置位了,所以TC的時間比較長,很容易被下一次數(shù)據(jù)覆蓋~~~所以一般喜歡判斷TXE,數(shù)據(jù)寫到DR就可以了 ,剩下的工作就交給硬件了

        3.一般的用TXE就可以了, TC一般用于需要延時的場合,比如說是232/485轉(zhuǎn)換器,需要得到TC后,才能將發(fā)送改變成接收,否則最后一個字節(jié)發(fā)送不完全。

        看來,3很符合我的情況:我的相當于2個等待:

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

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

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



        關(guān)鍵詞: STM32USART庫函數(shù)bu

        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 从化市| 昭平县| 弥渡县| 长泰县| 巴彦县| 苗栗县| 双城市| 武夷山市| 太谷县| 宁阳县| 惠安县| 常山县| 莱州市| 五河县| 新乡县| 潍坊市| 昌吉市| 台南市| 江城| 嘉祥县| 建湖县| 深水埗区| 长葛市| 伽师县| 肥东县| 礼泉县| 莲花县| 当雄县| 泽州县| 施秉县| 龙游县| 儋州市| 河北区| 建湖县| 灵川县| 平江县| 岳阳县| 十堰市| 寻乌县| 张家港市| 饶平县|