版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)由一個串口接收數(shù)據(jù)引發(fā)的問題與字節(jié)緩沖流系統(tǒng)的設(shè)計 在一個wifi數(shù)據(jù)收發(fā)項目調(diào)試時發(fā)現(xiàn),數(shù)據(jù)在高速連續(xù)發(fā)送和接收時,經(jīng)常出現(xiàn)數(shù)據(jù)出現(xiàn)了丟失和系統(tǒng)的死機(jī)。單片機(jī)在接收串口數(shù)據(jù)時,傳統(tǒng)采用中斷方法或者查詢指定標(biāo)志位方法接收數(shù)據(jù)。 查詢指定標(biāo)志位:這種方式通常在main函數(shù)的大循環(huán)中不斷的檢測標(biāo)志位或者等待該標(biāo)志位來判斷是否有數(shù)據(jù)接收。通常有兩種方式: 1:在大循環(huán)中if(標(biāo)志位成立)表明有數(shù)據(jù)接收然后進(jìn)行數(shù)據(jù)的處理。 優(yōu)點:不會引起整個main函數(shù)線程的阻塞;在簡單的數(shù)據(jù)接收項目中可以使用缺點:單片機(jī)一般都為單線程,復(fù)雜的控制中采用操作系統(tǒng),例如UC/OS;所以,將所以都函數(shù)放在main函數(shù)大循環(huán)中進(jìn)行輪番處理。整個循環(huán)周期時間不確定,其他任務(wù)函數(shù)可能發(fā)生阻塞,不能夠保證數(shù)據(jù)到來時,正好在執(zhí)行檢測指定標(biāo)志位,從而出現(xiàn)了數(shù)據(jù)丟失。 2:在大循環(huán)中while(標(biāo)志位);通過while來等待數(shù)據(jù)的到來。 優(yōu)點:數(shù)據(jù)不會出現(xiàn)丟失,穩(wěn)定。 缺點:整個main函數(shù)主線程出現(xiàn)堵塞,其他函數(shù)無法執(zhí)行,上述所示。顯然:以上兩種發(fā)送在復(fù)雜的控制系統(tǒng)中是不能采用的,因此:在沒有多任務(wù)操作系統(tǒng)時,數(shù)據(jù)的接收采用中斷接收的法式是最佳的。使用中斷,可以不用查詢和等待的方式接收數(shù)據(jù),解決了許多問題。,此時,單片機(jī)可以說是多線程執(zhí)行程序。main函數(shù)是一個線程,中斷服務(wù)子程序是一個線程。中斷是前臺,main函數(shù)是后臺。由于是多線程(一般而言),不得不考慮數(shù)據(jù)的安全性。中斷可能隨時到來。Main函數(shù)會隨時被打斷,程序計數(shù)器寄存器PC指針指向中斷函數(shù)入口地址,指向中斷函數(shù)。Main函數(shù)在處理數(shù)據(jù)時被打斷,可能會引發(fā)數(shù)據(jù)的丟失。共同訪問全局變量時,使用互斥信號量等一些手段保障數(shù)據(jù)不被修改。設(shè)計可能被中斷打斷的函數(shù)時,要注意函數(shù)的重入問題,像static等關(guān)鍵字。字節(jié)接收緩沖系統(tǒng)設(shè)計的核心思想: 1:前臺(即中斷)負(fù)責(zé)接收數(shù)據(jù),并不進(jìn)行處理,將數(shù)據(jù)放入消息隊列中。 2:后臺(main函數(shù))負(fù)責(zé)從消息隊列中取出消息,并處理。 3:整個接收系統(tǒng)核心為隊列,可以當(dāng)做緩沖區(qū);遵循先進(jìn)先出原則FIFO采用隊列方式接收數(shù)據(jù)比較簡單,并且實現(xiàn)了緩沖,不會出現(xiàn)數(shù)據(jù)的丟失。消息隊列核心算法實現(xiàn):1:消息隊列核心數(shù)據(jù)結(jié)構(gòu):typedefstructQueue{ unsignedcharfront;//隊列頭索引 unsignedcharrear;//隊列尾索引 unsignedchar*pArray;//簡易的隊列指向數(shù)組}QueueTypeDef;單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第1頁。單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第1頁。2:判斷隊列是否為滿偽算法 if((rear+1)%數(shù)組的元素個數(shù))==front)3:判斷隊列是否為空偽算法 if(rear==front)4:將數(shù)據(jù)加入隊列偽算法 if(隊列不為滿){ pArray[rear]=數(shù)據(jù); rear=(rear+1)%數(shù)組的長度}5:將數(shù)據(jù)從隊列中取出偽算法if(隊列不為空){ Val=pArray[front];front=(front+1)%數(shù)組長度}以上是接收最簡單的一個字節(jié)的隊列;ASCIIC編譯通過不依賴于單片機(jī);將其加入中斷服務(wù)子程序中,把接收的數(shù)據(jù)加入隊列中;以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ù)加入消息隊列中 } if(USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET) { USART_ClearFlag(USART2,USART_FLAG_ORE); USART_ReceiveData(USART2); } }Main函數(shù)從消息隊列中取出數(shù)據(jù) unsignedcharval;while(1) {單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第2頁。 if(out_queue(&Queue,&val))//從隊列中取出數(shù)據(jù)單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第2頁。 { if(i==16) i=0; LCD_print(1,i,val);//顯示取出的數(shù)據(jù) i++; } …. ….. //其他任務(wù)……. }以上算法思路是以接收最簡單的一個字節(jié)為例:當(dāng)然可以接收更復(fù)雜的數(shù)據(jù),數(shù)據(jù)結(jié)構(gòu)如下typedefstructMessage//消息數(shù)據(jù)結(jié)構(gòu){ u8clientID; //客戶端名 u8messgeLength;//消息長度 u8message_str[MessageSize];//存放消息的數(shù)組 }MessageTypeDef;typedefstructQueue//消息隊列數(shù)據(jù)結(jié)構(gòu){ u8front; //隊列頭 u8rear; //隊列尾+1 MessageTypeDefmessage[MessQueueSize];//消息 BOOL(*postMessage)(MessageTypeDefdat);//消息進(jìn)列 BOOL(*getMessage)(MessageTypeDef*datAddr);//消息出列 }MessQueue;MessageTypeDef;這個數(shù)據(jù)結(jié)構(gòu)中構(gòu)造了接收數(shù)據(jù)的格式并不是前面最簡單的一個字節(jié),根據(jù)實際接收數(shù)據(jù)的需要來構(gòu)造數(shù)據(jù)結(jié)構(gòu),當(dāng)然在中斷函數(shù)中要進(jìn)行數(shù)據(jù)的處理,也可以放在主函數(shù)中處理數(shù)據(jù),中斷中依然是將字節(jié)放入消息隊列中。主函數(shù)處理完數(shù)據(jù)后在放入另一個消息隊列中,由其他函數(shù)處理數(shù)據(jù),多級消息隊列。以下是帶特定格式的消息數(shù)據(jù)處理:buff[buff_index]=USART_ReceiveData(USART2); //將接收的數(shù)據(jù)(1個字節(jié))放入緩沖區(qū)// // if(buff[0]==0x2B)//校驗數(shù)據(jù)頭// {// buff_index++; // }// else單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第3頁。// {單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第3頁。// buff_index=0;// }// // if(buff_index==8)//獲取數(shù)據(jù)尾// {// length=(buff[7]-0x30)+1+buff_index;//計算數(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#defineQueueArraySize 32//隊列長度(字節(jié))typedefstructQueue{ unsignedcharfront;//隊列頭 unsignedcharrear;//隊列尾+1 unsignedchar*pArray;//指向字節(jié)數(shù)組}QueueTypeDef;單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第4頁。單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第4頁。externQueueTypeDefQueue;externunsignedcharqueueArray[QueueArraySize];voidqueue_Init(QueueTypeDef*pQ,unsignedchar*array);//初始化boolfull_queue(QueueTypeDef*pQ);//滿boolemput_queue(QueueTypeDef*pQ);//空boolen_queue(QueueTypeDef*pQ,unsignedcharval);//入隊列boolout_queue(QueueTypeDef*pQ,unsignedchar*dat);//出隊列#endif文件:queue.c#include"queue.h"QueueTypeDefQueue;unsignedcharqueueArray[QueueArraySize];voidqueue_Init(QueueTypeDef*pQ,unsignedchar*array){ Queue.front; Queue.rear; pQ->pArray=array; pQ->front=0; pQ->rear=0;}boolfull_queue(QueueTypeDef*pQ){ if((pQ->rear+1)%QueueArraySize==pQ->front) returntrue; else returnfalse;}boolemput_queue(QueueTypeDef*pQ){ if(pQ->front==pQ->rear) returntrue; else returnfalse;}單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第5頁。單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第5頁。boolen_queue(QueueTypeDef*pQ,unsignedcharval){ if(full_queue(pQ)) { returnfalse; } else { *((pQ->pArray)+(pQ->rear))=val; //pQ->pArray[pQ->rear]=val; pQ->rear=(pQ->rear+1)%QueueArraySize; returntrue; }}boolout_queue(QueueTypeDef*pQ,unsignedchar*dat){ if(emput_queue(pQ)) { returnfalse; } else { *dat=pQ->pArray[pQ->front]; pQ->front=(pQ->front+1)%QueueArraySize; returntrue; }}附:復(fù)雜數(shù)據(jù)接收緩沖流實現(xiàn)1:文件:queue.h#ifndef__QUEUE_H__#define__QUEUE_H__#ifndefBOOL#defineBOOL unsignedchar#defineTRUE 1#defineFALSE 0#endif#defineMessageSize 10//消息長度(字節(jié))單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第6頁。#defineMessQueueSize 20//隊列長度sizeof(MessageTypeDef)單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第6頁。typedefunsignedcharu8;typedefunsignedintu16;typedefstructMessage//消息數(shù)據(jù)結(jié)構(gòu){ u8clientID; //客戶端名 u8messgeLength;//消息長度 u8message_str[MessageSize];//存放消息的數(shù)組 }MessageTypeDef;typedefstructQueue//消息隊列數(shù)據(jù)結(jié)構(gòu){ u8front; //隊列頭 u8rear; //隊列尾+1 MessageTypeDefmessage[MessQueueSize];//消息 BOOL(*postMessage)(MessageTypeDefdat);//消息進(jìn)列 BOOL(*getMessage)(MessageTypeDef*datAddr);//消息出列 }MessQueue;externMessQueuemess_queue;voidMessageQueueInit(void);//初始化BOOLfull_queue(void);//判斷是否為滿BOOLemput_queue(void);//判斷是否為空BOOLen_queue(MessageTypeDefmessage);//入列BOOLout_queue(MessageTypeDef*message);//出列#endif2:文件:queue.c#include"queue1.h"MessQueuemess_queue;//定義消息隊列單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第7頁。voidMessageQueueInit(void)//初始化單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第7頁。{ mess_queue.front=0; mess_queue.rear=0; mess_queue.postMessage=en_queue; mess_queue.getMessage=out_queue;}BOOLfull_queue(void)//判斷隊列是否為滿{ if((mess_queue.rear+1)%MessQueueSize==mess_queue.front)//rear+1=front { returnTRUE; } else { returnFALSE; }}BOOLemput_queue(void)//判斷隊列是否為空{(diào) if(mess_queue.front=mess_queue.rear)//front=rear { returnTRUE; } else { returnFALSE; }}BOOLen_queue(MessageTypeDefmessage)//入列{ if(full_queue())//判斷隊列是否為滿 { returnFALSE; } else { u8i=0; 單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第8頁。 (&(mess_queue.message[mess_queue.rear]))->clientID=message.clientID;單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計與實現(xiàn)全文共9頁,當(dāng)前為第8頁。 (&(mess_queue.message[mess_queue.rear]))->messgeLength=message.messgeLength; for(i=0;i<(message.messgeLength);i++) { (&(mess_queue.message[mess_q
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《小麥蛋白特性與速凍餃子皮品質(zhì)關(guān)系的研究》
- 泡沫玻璃板施工方案
- 二零二五年度文化旅游產(chǎn)業(yè)投資合同3篇
- 2025年度葡萄鮮果直銷合作社采購合同范本3篇
- 2024集體土地承包經(jīng)營權(quán)流轉(zhuǎn)合同
- 中藥制劑技術(shù)練習(xí)題復(fù)習(xí)試題附答案
- 二零二五年度家庭裝修拆除與環(huán)保材料采購合同3篇
- 安全情報視域下的網(wǎng)絡(luò)空間安全態(tài)勢感知
- 底系梁及承臺施工方案
- 2025年度新能源設(shè)備紙箱包裝采購與運(yùn)輸服務(wù)協(xié)議3篇
- 運(yùn)用QC方法提高雨、污水管道施工質(zhì)量
- 標(biāo)志牌及標(biāo)志牌基礎(chǔ)施工組織設(shè)計
- 王力指紋鎖中文使用說明
- 物流運(yùn)籌學(xué)附錄習(xí)題答案
- 市政府副市長年道路春運(yùn)工作會議講話稿
- GB_T 37514-2019 動植物油脂 礦物油的檢測(高清版)
- 閘門水力計算說明
- 大型塔器“立裝成段整體就位”工法
- 車輛使用授權(quán)書
- 常用函數(shù)圖像(1)
- 說明書ZWY-150(120)-45L煤礦用挖掘式裝載機(jī)
評論
0/150
提交評論