日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

正点原子STM32串口例程解析

發(fā)布時(shí)間:2023/12/10 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 正点原子STM32串口例程解析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

???????學(xué)習(xí)32,串口的使用很重要,特別是現(xiàn)在學(xué)的越多就覺(jué)得在很多方面通信才是主角,原子歷程寫的挺好,但是我看論壇里好像沒(méi)怎么有這個(gè)的解析那就按自己的理解寫寫吧,希望能幫助到正在學(xué)習(xí)的同學(xué)。然后寫在前面,初學(xué)者或者想深入學(xué)習(xí)一定要多看看參考手冊(cè)。
???????在主函中使用以下語(yǔ)句實(shí)現(xiàn)將接收到的數(shù)據(jù)發(fā)送出去:

if(USART_RX_STA&0x8000){ len=USART_RX_STA&0x3fff;printf("\r\n您發(fā)送的消息為:\r\n\r\n");for(t=0;t<len;t++){USART_SendData(USART1, USART_RX_BUF[t]);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);}

???????首先USART_RX_STA是什么呢?在"usart.c"里面有說(shuō)明這是個(gè)接收狀態(tài)標(biāo)記,它既指接收狀態(tài)又表明接收到數(shù)據(jù)的位數(shù),具體使用在下文的串口中斷部分中進(jìn)行說(shuō)明解釋。

u16 USART_RX_STA=0; //接收狀態(tài)標(biāo)記

???????USART_RX_STA的值在USART1_IRQHandler串口接收中斷函數(shù)中被改變,這里USART_RX_STA&0x8000就是判斷是否已經(jīng)接收到了0x0a,0x0a是LF(line feed)換行的意思,光標(biāo)到達(dá)下一行,也是判斷數(shù)據(jù)接收結(jié)束的標(biāo)志。
???????提一下,中斷中是以是否接收到0x0d 0x0a這兩個(gè)數(shù)據(jù),判斷數(shù)據(jù)是否發(fā)送結(jié)束的。假如你發(fā)的數(shù)據(jù)沒(méi)有回車(0x0d )、換行(0x0a)那么單片機(jī)是不會(huì)停止接收的(在PC中回車、換行使用回車按鍵就都包含了,感興趣可以具體查查)。
???????程序使用數(shù)組進(jìn)行數(shù)據(jù)的存儲(chǔ),于是這段代碼也就引出一個(gè)BUG,具體描述不會(huì)描述就簡(jiǎn)單說(shuō)下,嘴笨是硬傷。
???????比如我給單片機(jī)發(fā)送 0x01 0x02 0x03 0x04 0x05 0x06 0x0d,這時(shí)候程序還在運(yùn)行繼續(xù)等待接收,
?????????????????????????????再發(fā)送 0x07 0x08 0x0d 0x0a這時(shí)候接收結(jié)束,看看最后輸出什么?
???????導(dǎo)致這個(gè)BUG的原因就是數(shù)組存儲(chǔ)了信息,知道出錯(cuò)但沒(méi)有清除,只是提一下,注意一點(diǎn)就行,一般使用還是可以的。

if(Res==0x0d)USART_RX_STA|=0x4000;

這句話呢就是判斷是否接收到回車(0x0d ),接收到了回車,那么讓USART_RX_STA標(biāo)志位第二位為1。

if(USART_RX_STA&0x4000) { if(Res!=0x0a)USART_RX_STA=0; else USART_RX_STA|=0x8000; }

這句話呢就是判斷是否接收到換行(0x0a),如果收到換行并進(jìn)行判斷確認(rèn)收到換行符那么讓USART_RX_STA標(biāo)志位最高位為1。不是很懂的話,那就看看后面的那個(gè)圖。至此中斷就差不多說(shuō)明白了,要是還有其他問(wèn)題,看看下面的注釋,這里我是想說(shuō)怎么進(jìn)行的數(shù)據(jù)處理,畢竟我覺(jué)得這一塊是個(gè)難點(diǎn)。

void USART1_IRQHandler(void) //串口1中斷服務(wù)程序{u8 Res;//中間變量,讀取的數(shù)據(jù)進(jìn)行保存if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //查看RXNE寄存器是否為空,以此判斷是否有數(shù)據(jù)發(fā)送過(guò)來(lái)//接收中斷(接收到的數(shù)據(jù)必須是0x0d 0x0a結(jié)尾)//這里判斷發(fā)送接收完成的依據(jù)就是串口數(shù)據(jù)0x0d 0x0a,//0x0d是CR(carriage return)回車的意思,光標(biāo)回到最左邊,//0x0a是LF(line feed)換行的意思,光標(biāo)到達(dá)下一行,//但是在PC上回車和換行是在一起的就是按下回車按鍵//當(dāng)然可以更改程序使用其他進(jìn)行判斷例如使用0x2a也就是*進(jìn)行結(jié)束判斷{Res =USART_ReceiveData(USART1);//(USART1->DR); //讀取接收到的數(shù)據(jù),存放到變量Res中if((USART_RX_STA&0x8000)==0)//判斷接收是否未完成//接收完成未清除標(biāo)志位,還是會(huì)不斷進(jìn)入到接收中斷,所以使用標(biāo)志進(jìn)行判斷,//當(dāng)接收完成便不會(huì)跳入到判斷,從而不執(zhí)行任何指令,空等待//使用條件判斷是否已經(jīng)接收完數(shù)據(jù),這里判斷接收完的依據(jù)就是收到了0x0a;//具體判斷在后面{if(USART_RX_STA&0x4000)//如果接收到了0x0d,那么再進(jìn)一步執(zhí)行是否接收到0x0a的判斷{if(Res!=0x0a)USART_RX_STA=0;//沒(méi)有接收到0x0a那么說(shuō)明,數(shù)據(jù)未正確傳輸或者接收錯(cuò)誤,重新開(kāi)始判斷,//但是這里沒(méi)有將接收到的數(shù)據(jù)進(jìn)行清空,也沒(méi)有退出接收中斷,此程序只是從頭開(kāi)始執(zhí)行接收判斷else USART_RX_STA|=0x8000; //接收完成了,收到了0x0a那么標(biāo)志位USART_RX_STA將會(huì)變成0x8000(使用或指令,只改變最高位),將不再進(jìn)行數(shù)據(jù)檢測(cè)與存儲(chǔ)}else //還沒(méi)收到0X0D,說(shuō)明數(shù)據(jù)還未發(fā)送結(jié)束繼續(xù)進(jìn)行數(shù)據(jù)的檢測(cè)與存儲(chǔ){ if(Res==0x0d)USART_RX_STA|=0x4000;//收到了數(shù)據(jù)0x0d,標(biāo)志位USART_RX_STA變成0x4000(使用或指令,只改變次高位)else{//如果沒(méi)有接收到數(shù)據(jù)0x0d,執(zhí)行判斷是否存儲(chǔ)數(shù)組已滿,已滿則重新開(kāi)始接收USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;//將接收到的數(shù)據(jù)寫進(jìn)數(shù)組,標(biāo)志位USART_RX_STA與上0X3FFF清除前兩位以防止標(biāo)志位與8000和4000沖突USART_RX_STA++;//數(shù)組地址加一,向后排if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收數(shù)據(jù)錯(cuò)誤,超出數(shù)組大小,又開(kāi)始接收向數(shù)組重新寫 } }} } }

???????判斷接收結(jié)束再判斷此次接收數(shù)據(jù)的長(zhǎng)度,USART_RX_STA也表明接收數(shù)據(jù)的位數(shù),要想將接收到的數(shù)據(jù)全部發(fā)送出去就需要知道,一共接收到了幾位然后一位一位的傳出去,所以len=USART_RX_STA&0x3fff;就實(shí)現(xiàn)了將數(shù)據(jù)長(zhǎng)度賦值給變量len,然后使用for循環(huán)依次將接收到的數(shù)據(jù)發(fā)送出去。這里也許會(huì)糊涂為什么是0x3fff呢?看下圖能理解么?
???????接收到0x0d ,USART_RX_STA的值變成0x4000,又接收到0x0a,USART_RX_STA的值變成0xC000那么很容易發(fā)現(xiàn)數(shù)據(jù)的的前兩位是作為標(biāo)志位了,所以用來(lái)記錄其他數(shù)據(jù)位數(shù)就只有0x3fff。

if(USART_RX_STA&0x8000)//如果在串口接收中斷中接收到0x0a,數(shù)據(jù)已接收完畢{ len=USART_RX_STA&0x3fff;//得到此次接收到的數(shù)據(jù)長(zhǎng)度,傳給for循環(huán),循環(huán)依次發(fā)出接收到的數(shù)據(jù)printf("\r\n您發(fā)送的消息為:\r\n\r\n");for(t=0;t<len;t++)//通過(guò)for循環(huán)依次將接收到的數(shù)據(jù)發(fā)送出去{USART_SendData(USART1, USART_RX_BUF[t]);//向串口1發(fā)送數(shù)據(jù),USART_SendData是庫(kù)函數(shù)控制DR寄存器while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待發(fā)送結(jié)束,看TC寄存器的狀態(tài) TC:發(fā)送完成 (Transmission complete) }

???????差不多就是這樣,不懂的可以評(píng)論,有錯(cuò)誤也請(qǐng)指正。一般使用串口不是這么判斷使用的,具體看有沒(méi)有時(shí)間,有時(shí)間整理一份。過(guò)些時(shí)候?qū)⒆⑨尩奈募蟼饕员阆螺d閱讀。

總結(jié)

以上是生活随笔為你收集整理的正点原子STM32串口例程解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。