單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)_第1頁
單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)_第2頁
單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)_第3頁
單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)_第4頁
單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、由一個(gè)串口接收數(shù)據(jù)引發(fā)的問題與字節(jié)緩沖流系統(tǒng)的設(shè)計(jì)在一個(gè)wifi數(shù)據(jù)收發(fā)項(xiàng)目調(diào)試時(shí)發(fā)現(xiàn),數(shù)據(jù)在高速連續(xù)發(fā)送和接收時(shí),經(jīng)常出現(xiàn)數(shù)據(jù)出現(xiàn)了丟失和系統(tǒng)的死機(jī)。單片機(jī)在接收串口數(shù)據(jù)時(shí),傳統(tǒng)采用中斷方法或者查詢指定標(biāo)志位方法接收數(shù)據(jù)。查詢指定標(biāo)志位:這種方式通常在main函數(shù)的大循環(huán)中不斷的檢測(cè)標(biāo)志位或者等待該標(biāo)志位來判斷是否有數(shù)據(jù)接收。通常有兩種方式:1:在大循環(huán)中if(標(biāo)志位成立)表明有數(shù)據(jù)接收然后進(jìn)行數(shù)據(jù)的處理。優(yōu)點(diǎn):不會(huì)引起整個(gè)main函數(shù)線程的阻塞;在簡(jiǎn)單的數(shù)據(jù)接收項(xiàng)目中可以使用缺點(diǎn):?jiǎn)纹瑱C(jī)一般都為單線程,復(fù)雜的控制中采用操作系統(tǒng),例如UC/OS;所以,將所以都函數(shù)放在main函數(shù)大循環(huán)中進(jìn)行

2、輪番處理。整個(gè)循環(huán)周期時(shí)間不確定,其他任務(wù)函數(shù)可能發(fā)生阻塞,不能夠保證數(shù)據(jù)到來時(shí),正好在執(zhí)行檢測(cè)指定標(biāo)志位,從而出現(xiàn)了數(shù)據(jù)丟失。2:在大循環(huán)中while(標(biāo)志位);通過while來等待數(shù)據(jù)的到來。優(yōu)點(diǎn):數(shù)據(jù)不會(huì)出現(xiàn)丟失,穩(wěn)定。缺點(diǎn):整個(gè)main函數(shù)主線程出現(xiàn)堵塞,其他函數(shù)無法執(zhí)行,上述所示。顯然:以上兩種發(fā)送在復(fù)雜的控制系統(tǒng)中是不能采用的,因此:在沒有多任務(wù)操作系統(tǒng)時(shí),數(shù)據(jù)的接收采用中斷接收的法式是最佳的。使用中斷,可以不用查詢和等待的方式接收數(shù)據(jù),解決了許多問題。,此時(shí),單片機(jī)可以說是多線程執(zhí)行程序。main函數(shù)是一個(gè)線程,中斷服務(wù)子程序是一個(gè)線程。中斷是前臺(tái),main函數(shù)是后臺(tái)。由于是多線

3、程(一般而言),不得不考慮數(shù)據(jù)的安全性。中斷可能隨時(shí)到來。Main函數(shù)會(huì)隨時(shí)被打斷,程序計(jì)數(shù)器寄存器PC指針指向中斷函數(shù)入口地址,指向中斷函數(shù)。Main函數(shù)在處理數(shù)據(jù)時(shí)被打斷,可能會(huì)引發(fā)數(shù)據(jù)的丟失。共同訪問全局變量時(shí),使用互斥信號(hào)量等一些手段保障數(shù)據(jù)不被修改。設(shè)計(jì)可能被中斷打斷的函數(shù)時(shí),要注意函數(shù)的重入問題,像static等關(guān)鍵字。字節(jié)接收緩沖系統(tǒng)設(shè)計(jì)的核心思想:1:前臺(tái)(即中斷)負(fù)責(zé)接收數(shù)據(jù),并不進(jìn)行處理,將數(shù)據(jù)放入消息隊(duì)列中。2:后臺(tái)(main函數(shù))負(fù)責(zé)從消息隊(duì)列中取出消息,并處理。3:整個(gè)接收系統(tǒng)核心為隊(duì)列,可以當(dāng)做緩沖區(qū);遵循先進(jìn)先出原則FIFO采用隊(duì)列方式接收數(shù)據(jù)比較簡(jiǎn)單,并且實(shí)現(xiàn)了

4、緩沖,不會(huì)出現(xiàn)數(shù)據(jù)的丟失。消息隊(duì)列核心算法實(shí)現(xiàn):1:消息隊(duì)列核心數(shù)據(jù)結(jié)構(gòu):typedefstructQueueunsignedcharfront;/隊(duì)歹U頭索弓Iunsignedcharrear;隊(duì)歹U尾索弓Iunsignedchar*pArray;簡(jiǎn)易的隊(duì)列指向數(shù)組QueueTypeDef;2:判斷隊(duì)列是否為滿偽算法if(rear+1)%數(shù)組的元素個(gè)數(shù))=front)3:判斷隊(duì)列是否為空偽算法if(rear=front)4:將數(shù)據(jù)加入隊(duì)列偽算法if(隊(duì)列不為滿)(pArrayrear=數(shù)據(jù);rear=(rear+1)%數(shù)組的長(zhǎng)度)5:將數(shù)據(jù)從隊(duì)列中取出偽算法if(隊(duì)列不為空)(Val=pAr

5、rayfront;front=(front+1)%數(shù)組長(zhǎng)度)以上是接收最簡(jiǎn)單的一個(gè)字節(jié)的隊(duì)列;ASCIIC編譯通過不依賴于單片機(jī);將其加入中斷服務(wù)子程序中,把接收的數(shù)據(jù)加入隊(duì)列中;以stm32單片機(jī)串口中斷為例:voidUSART2_IRQHandler(void)(if(USART_GetITStatus(USART2,USART_IT_RXNE)=SET)(USART_ClearITPendingBit(USART2,USART_IT_RXNE);en_queue(&Queue,(uint8_t)USART_ReceiveData(USART2);將數(shù)據(jù)加入消息隊(duì)列中)if(USA

6、RT_GetFlagStatus(USART2,USART_FLAG_ORE)=SET)(USART_ClearFlag(USART2,USART_FLAG_ORE);USART_ReceiveData(USART2);)Main函數(shù)從消息隊(duì)列中取出數(shù)據(jù)unsignedcharval;while(1)(if(out_queue(&Queue,&val)從隊(duì)列中取出數(shù)據(jù)if(i=16)i=0;LCD_print(1,i,val);顯示取出的數(shù)據(jù)i+;).其他任務(wù).)以上算法思路是以接收最簡(jiǎn)單的一個(gè)字節(jié)為例:當(dāng)然可以接收更復(fù)雜的數(shù)據(jù),數(shù)據(jù)結(jié)構(gòu)如下typedefstructMessa

7、ge消息數(shù)據(jù)結(jié)構(gòu)(u8clientID;/客戶端名u8messgeLength;/消息長(zhǎng)度u8message_strMessageSize;/存放消息的數(shù)組MessageTypeDef;typedefstructQueue消息隊(duì)列數(shù)據(jù)結(jié)構(gòu)(u8front;隊(duì)列頭u8rear;隊(duì)列尾+1MessageTypeDefmessageMessQueueSize;/艄息BOOL(*postMessage)(MessageTypeDefdat);消息進(jìn)列BOOL(*getMessage)(MessageTypeDef*datAddr);/消息出列MessQueue;MessageTypeDef;這個(gè)數(shù)據(jù)結(jié)

8、構(gòu)中構(gòu)造了接收數(shù)據(jù)的格式并不是前面最簡(jiǎn)單的一個(gè)字節(jié),根據(jù)實(shí)際接收數(shù)據(jù)的需要來構(gòu)造數(shù)據(jù)結(jié)構(gòu),當(dāng)然在中斷函數(shù)中要進(jìn)行數(shù)據(jù)的處理,也可以放在主函數(shù)中處理數(shù)據(jù),中斷中依然是將字節(jié)放入消息隊(duì)列中。主函數(shù)處理完數(shù)據(jù)后在放入另一個(gè)消息隊(duì)列中,由其他函數(shù)處理數(shù)據(jù),多級(jí)消息隊(duì)列。以下是帶特定格式的消息數(shù)據(jù)處理:buffbuff_index=USART_ReceiveData(USART2);將接收的數(shù)據(jù)(1個(gè)字節(jié))放入緩沖區(qū)/if(buff0=0x2B)校驗(yàn)數(shù)據(jù)頭/buff_index+;/else/buff_index=0;/if(buff_index=8)獲取數(shù)據(jù)尾/length=(buff7-0x30)+

9、1+buff_index;/計(jì)算數(shù)據(jù)尾索引/if(buff_index=length)/length=200;/buff_index=0;receive=TRUE;/數(shù)據(jù)接收完成/DISABLE_WIFI_RX_IRQ();/附:字節(jié)緩沖流系統(tǒng)源碼:文件queue.h#ifndef_QUEUE_H_#define_QUEUE_H_#ifndefbool#defineboolunsignedchar#definetrue1#definefalse0#endif#defineQueueArraySize32隊(duì)列長(zhǎng)度(字節(jié))typedefstructQueueunsignedcharfront;隊(duì)列

10、頭unsignedcharrear;隊(duì)列尾+1unsignedchar*pArray;指向字節(jié)數(shù)組QueueTypeDef;externQueueTypeDefQueue;externunsignedcharqueueArrayQueueArraySize;voidqueue_Init(QueueTypeDef*pQ,unsignedchar*array);初始化boolfull_queue(QueueTypeDef*pQ);滿boolemput_queue(QueueTypeDef*pQ);空boolen_queue(QueueTypeDef*pQ,unsignedcharval);/入隊(duì)歹

11、Uboolout_queue(QueueTypeDef*pQ,unsignedchar*dat);/出隊(duì)歹U#endif文件:queue.c#include"queue.h"QueueTypeDefQueue;unsignedcharqueueArrayQueueArraySize;voidqueue_Init(QueueTypeDef*pQ,unsignedchar*array)Queue.front;Queue.rear;pQ->pArray=array;pQ->front=0;pQ->rear=0;boolfull_queue(QueueTypeDe

12、f*pQ)if(pQ->rear+1)%QueueArraySize=pQ->front)returntrue;elsereturnfalse;boolemput_queue(QueueTypeDef*pQ)if(pQ->front=pQ->rear)returntrue;elsereturnfalse;boolen_queue(QueueTypeDef*pQ,unsignedcharval)(if(full_queue(pQ)(returnfalse;else(*(pQ->pArray)+(pQ->rear)=val;/pQ->pArraypQ-&g

13、t;rear=val;pQ->rear=(pQ->rear+1)%QueueArraySize;returntrue;boolout_queue(QueueTypeDef*pQ,unsignedchar*dat)(if(emput_queue(pQ)(returnfalse;else(*dat=pQ->pArraypQ->front;pQ->front=(pQ->front+1)%QueueArraySize;returntrue;附:復(fù)雜數(shù)據(jù)接收緩沖流實(shí)現(xiàn)1:文件:queue.h#ifndef_QUEUE_H_#define_QUEUE_H_#ifndef

14、BOOL#defineBOOLunsignedchar# defineTRUE1# defineFALSE0#endif# defineMessageSize10消息長(zhǎng)度(字節(jié))# defineMessQueueSize20隊(duì)列長(zhǎng)度sizeof(MessageTypeDef)typedefunsignedcharu8;typedefunsignedintu16;typedefstructMessage消息數(shù)據(jù)結(jié)構(gòu)(u8clientID;/客戶端名u8messgeLength;/消息長(zhǎng)度u8message_strMessageSize;/存放消息的數(shù)組MessageTypeDef;typedef

15、structQueue消息隊(duì)列數(shù)據(jù)結(jié)構(gòu)(u8front;隊(duì)列頭u8rear;隊(duì)列尾+1MessageTypeDefmessageMessQueueSize;/艄息BOOL(*postMessage)(MessageTypeDefdat);消息進(jìn)列BOOL(*getMessage)(MessageTypeDef*datAddr);/消息出列MessQueue;externMessQueuemess_queue;voidMessageQueueInit(void);初始化BOOLfull_queue(void);/判斷是否為滿BOOLemput_queue(void);/判斷是否為空BOOLen_

16、queue(MessageTypeDefmessage);/入歹UBOOLout_queue(MessageTypeDef*message);/出歹U#endif2:文件:queue.c#include"queuel.h"MessQueuemess_queue;/定義消息隊(duì)歹UvoidMessageQueuelnit(void)初始化mess_queue.front=0;mess_queue.rear=0;mess_queue.postMessage=en_queue;mess_queue.getMessage=out_queue;)BOOLfull_queue(void)

17、判斷隊(duì)列是否為滿(if(mess_queue.rear+1)%MessQueueSize=mess_queue.front)/rear+1=front(returnTRUE;)else(returnFALSE;)BOOLemput_queue(void)判斷隊(duì)列是否為空(if(mess_queue.front=mess_queue.rear)/front=rear(returnTRUE;)else(returnFALSE;)BOOLen_queue(MessageTypeDefmessage)/入歹U(if(full_queue()判斷隊(duì)列是否為滿(returnFALSE;)else(u8i=

18、0;(&(mess_queue.messagemess_queue.rear)->clientID=message.clientID;(&(mess_queue.messagemess_queue.rear)->messgeLength=message.messgeLength;for(i=0;i<(message.messgeLength);i+)(&(mess_queue.messagemess_queue.rear)->message_stri=message.message_stri;mess_queue.rear=(mess_queue.rear+1)%MessQueueSize;returnTRUE;BOOLout_queue(MessageTypeDef*message)出歹Uif(emput_queue()判斷是否為空returnFALSE;elseu8i;message->clientID=(&(mess_queue.messagemess_queue.front)->clientID;message->messgeLength=(&(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論