关于单片机串口接收不固定字节长度的解决方案
之前老是有個(gè)問(wèn)題困惑著小編,串口這種一字節(jié)一字節(jié)的接收和發(fā)送的機(jī)制,而在實(shí)際應(yīng)用中如果收發(fā)雙方不制定一個(gè)協(xié)議,沒(méi)有幀頭,幀尾做一幀數(shù)據(jù)接收開(kāi)始和結(jié)束的標(biāo)準(zhǔn)。或者收發(fā)數(shù)據(jù)長(zhǎng)度不固定,怎么去確定每一幀長(zhǎng)度不同的幀呢?
面對(duì)這種每次發(fā)送長(zhǎng)度不固定的情況,我最開(kāi)始采用的是定時(shí)器中斷加串口中斷的方式。
? ? 如現(xiàn)在來(lái)了一幀長(zhǎng)度為86字節(jié)的數(shù)據(jù),我在串口接收中斷中將這86個(gè)字節(jié)一一入循環(huán)隊(duì)列,假設(shè)循環(huán)隊(duì)列的長(zhǎng)度是256個(gè)字節(jié),現(xiàn)在86個(gè)字節(jié)已經(jīng)接收完畢,那么,我在哪里出隊(duì)來(lái)確保這86個(gè)字節(jié)能一次性出完呢,很多人可能考慮的是主函數(shù)輪詢出隊(duì),但是你可想過(guò),如果主函數(shù)里面處理的任務(wù)不多,導(dǎo)致輪詢過(guò)快,如果此時(shí)出隊(duì)列就會(huì)導(dǎo)致86個(gè)字節(jié)出隊(duì)時(shí)不能出完,從而會(huì)被多次拆分形成多幀數(shù)據(jù),處理數(shù)據(jù)無(wú)效。
? ? 所以可以采用定時(shí)器中斷,每80ms中斷一次,每次中斷,數(shù)據(jù)出隊(duì)列,80ms已經(jīng)可以實(shí)現(xiàn)一次性接收256個(gè)字節(jié)都會(huì)完整的出隊(duì)了。而且80ms肉眼基本看不出,只能看到這邊發(fā)送,那邊就已經(jīng)把完整的數(shù)據(jù)打印出來(lái)了,而且256個(gè)字節(jié)以內(nèi)任意發(fā)多少,都沒(méi)有數(shù)據(jù)被拆分,丟失的問(wèn)題。這樣顯然是初步解決了任意長(zhǎng)度發(fā)送,接收的問(wèn)題,但是在實(shí)際應(yīng)用使用中,如果要求串口高速度,發(fā)不定長(zhǎng)的數(shù)據(jù),就會(huì)出現(xiàn)一系列的問(wèn)題,如現(xiàn)在客戶要求任意長(zhǎng)度的一幀數(shù)據(jù),我連續(xù)發(fā)送多幀,而且每幀的時(shí)間間隔要小于10ms,并且我們之間收發(fā)沒(méi)有通信協(xié)議,我想給你發(fā)什么就發(fā)什么,你要解析數(shù)據(jù)。面對(duì)這種客戶要求這種定時(shí)器中斷加串口中斷肯定是不行了的。那么采用什么會(huì)有效解決這個(gè)問(wèn)題呢。
? ? 仔細(xì)看單片機(jī)的數(shù)據(jù)手冊(cè)關(guān)于串口中斷的描述,會(huì)發(fā)現(xiàn),其實(shí)串口中斷中,存在一個(gè)空閑中斷,這個(gè)空閑中斷幫了我大忙,空閑中斷并不是說(shuō)串口空閑就觸發(fā),這樣的話豈不是串口如果沒(méi)有數(shù)據(jù)過(guò)來(lái),空閑中斷一直觸發(fā),那么整個(gè)程序不就一直處于中斷之中嘛。空閑中斷是指,當(dāng)最后一個(gè)字節(jié)接收完畢后,硬件接收中斷接收完數(shù)據(jù)后使得IDLE寄存器中的標(biāo)志位置高,于是,我們便可以采用此空閑中斷標(biāo)志置高來(lái)提醒主程序可以出隊(duì),因?yàn)橐粠瑪?shù)據(jù)已經(jīng)發(fā)送完畢了。
1、下圖為初始化時(shí)使能串口接收中斷和空閑中斷,及重寫(xiě)串口中斷函數(shù)方法:
?注意:USART5_IRQHandler函數(shù)里面,用關(guān)于先讀SR,再讀DR是為了清除空閑中斷標(biāo)志,以至于下一幀數(shù)據(jù)還能觸發(fā)此中斷,而下面那個(gè)變量置1,提醒主程序一幀數(shù)據(jù)接收完畢,你該去處理了。
2、下圖為在主程序里輪詢檢測(cè)數(shù)據(jù)結(jié)束標(biāo)志,如果標(biāo)志被置1則進(jìn)行相應(yīng)處理。
?注意:uart5_handle函數(shù)里面據(jù)實(shí)際情況而實(shí)現(xiàn),如果你只想單純的轉(zhuǎn)發(fā)數(shù)據(jù),那么直接判斷隊(duì)列里數(shù)據(jù)長(zhǎng)度,根據(jù)長(zhǎng)度出隊(duì)所有數(shù)據(jù),然后進(jìn)行轉(zhuǎn)發(fā)就行,如果需要解析處理數(shù)據(jù)的話,也可以先出隊(duì)再解析處理。
以上就是關(guān)于單片機(jī)接收不定長(zhǎng)數(shù)據(jù)的解決方案的全部處理過(guò)程,其中如果收發(fā)雙方如果制定了協(xié)議,則可以根據(jù)協(xié)議收發(fā)不定長(zhǎng)數(shù)據(jù)。如果沒(méi)有串口通信協(xié)議則可以使用,串口接收中斷加串口空閑中斷的方式處理!!小編也是剛剛?cè)肟硬痪?#xff0c;歡迎各位大佬對(duì)不對(duì)的地方評(píng)論。謝謝!!
?
總結(jié)
以上是生活随笔為你收集整理的关于单片机串口接收不固定字节长度的解决方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ios swift5 弹出原生的提示框(
- 下一篇: ios swift 5 UIView切圆