版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)由一個(gè)串口接收數(shù)據(jù)引發(fā)的問(wèn)題與字節(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)采用中斷方法或者查詢(xún)指定標(biāo)志位方法接收數(shù)據(jù)。 查詢(xún)指定標(biāo)志位:這種方式通常在main函數(shù)的大循環(huán)中不斷的檢測(cè)標(biāo)志位或者等待該標(biāo)志位來(lái)判斷是否有數(shù)據(jù)接收。通常有兩種方式: 1:在大循環(huán)中if(標(biāo)志位成立)表明有數(shù)據(jù)接收然后進(jìn)行數(shù)據(jù)的處理。 優(yōu)點(diǎn):不會(huì)引起整個(gè)main函數(shù)線(xiàn)程的阻塞;在簡(jiǎn)單的數(shù)據(jù)接收項(xiàng)目中可以使用缺點(diǎn):?jiǎn)纹瑱C(jī)一般都為單線(xiàn)程,復(fù)雜的控制中采用操作系統(tǒng),例如UC/OS;所以,將所以都函數(shù)放在main函數(shù)大循環(huán)中進(jìn)行輪番處理。整個(gè)循環(huán)周期時(shí)間不確定,其他任務(wù)函數(shù)可能發(fā)生阻塞,不能夠保證數(shù)據(jù)到來(lái)時(shí),正好在執(zhí)行檢測(cè)指定標(biāo)志位,從而出現(xiàn)了數(shù)據(jù)丟失。 2:在大循環(huán)中while(標(biāo)志位);通過(guò)while來(lái)等待數(shù)據(jù)的到來(lái)。 優(yōu)點(diǎn):數(shù)據(jù)不會(huì)出現(xiàn)丟失,穩(wěn)定。 缺點(diǎn):整個(gè)main函數(shù)主線(xiàn)程出現(xiàn)堵塞,其他函數(shù)無(wú)法執(zhí)行,上述所示。顯然:以上兩種發(fā)送在復(fù)雜的控制系統(tǒng)中是不能采用的,因此:在沒(méi)有多任務(wù)操作系統(tǒng)時(shí),數(shù)據(jù)的接收采用中斷接收的法式是最佳的。使用中斷,可以不用查詢(xún)和等待的方式接收數(shù)據(jù),解決了許多問(wèn)題。,此時(shí),單片機(jī)可以說(shuō)是多線(xiàn)程執(zhí)行程序。main函數(shù)是一個(gè)線(xiàn)程,中斷服務(wù)子程序是一個(gè)線(xiàn)程。中斷是前臺(tái),main函數(shù)是后臺(tái)。由于是多線(xiàn)程(一般而言),不得不考慮數(shù)據(jù)的安全性。中斷可能隨時(shí)到來(lái)。Main函數(shù)會(huì)隨時(shí)被打斷,程序計(jì)數(shù)器寄存器PC指針指向中斷函數(shù)入口地址,指向中斷函數(shù)。Main函數(shù)在處理數(shù)據(jù)時(shí)被打斷,可能會(huì)引發(fā)數(shù)據(jù)的丟失。共同訪(fǎng)問(wèn)全局變量時(shí),使用互斥信號(hào)量等一些手段保障數(shù)據(jù)不被修改。設(shè)計(jì)可能被中斷打斷的函數(shù)時(shí),要注意函數(shù)的重入問(wèn)題,像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)了緩沖,不會(huì)出現(xiàn)數(shù)據(jù)的丟失。消息隊(duì)列核心算法實(shí)現(xiàn):1:消息隊(duì)列核心數(shù)據(jù)結(jié)構(gòu):typedefstructQueue{ unsignedcharfront;//隊(duì)列頭索引 unsignedcharrear;//隊(duì)列尾索引 unsignedchar*pArray;//簡(jiǎn)易的隊(duì)列指向數(shù)組}QueueTypeDef;單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第1頁(yè)。單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第1頁(yè)。2:判斷隊(duì)列是否為滿(mǎn)偽算法 if((rear+1)%數(shù)組的元素個(gè)數(shù))==front)3:判斷隊(duì)列是否為空偽算法 if(rear==front)4:將數(shù)據(jù)加入隊(duì)列偽算法 if(隊(duì)列不為滿(mǎn)){ pArray[rear]=數(shù)據(jù); rear=(rear+1)%數(shù)組的長(zhǎng)度}5:將數(shù)據(jù)從隊(duì)列中取出偽算法if(隊(duì)列不為空){ Val=pArray[front];front=(front+1)%數(shù)組長(zhǎng)度}以上是接收最簡(jiǎn)單的一個(gè)字節(jié)的隊(duì)列;ASCIIC編譯通過(guò)不依賴(lài)于單片機(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(USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET) { USART_ClearFlag(USART2,USART_FLAG_ORE); USART_ReceiveData(USART2); } }Main函數(shù)從消息隊(duì)列中取出數(shù)據(jù) unsignedcharval;while(1) {單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第2頁(yè)。 if(out_queue(&Queue,&val))//從隊(duì)列中取出數(shù)據(jù)單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第2頁(yè)。 { 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)如下typedefstructMessage//消息數(shù)據(jù)結(jié)構(gòu){ u8clientID; //客戶(hù)端名 u8messgeLength;//消息長(zhǎng)度 u8message_str[MessageSize];//存放消息的數(shù)組 }MessageTypeDef;typedefstructQueue//消息隊(duì)列數(shù)據(jù)結(jié)構(gòu){ u8front; //隊(duì)列頭 u8rear; //隊(duì)列尾+1 MessageTypeDefmessage[MessQueueSize];//消息 BOOL(*postMessage)(MessageTypeDefdat);//消息進(jìn)列 BOOL(*getMessage)(MessageTypeDef*datAddr);//消息出列 }MessQueue;MessageTypeDef;這個(gè)數(shù)據(jù)結(jié)構(gòu)中構(gòu)造了接收數(shù)據(jù)的格式并不是前面最簡(jiǎn)單的一個(gè)字節(jié),根據(jù)實(shí)際接收數(shù)據(jù)的需要來(lái)構(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ù)處理:buff[buff_index]=USART_ReceiveData(USART2); //將接收的數(shù)據(jù)(1個(gè)字節(jié))放入緩沖區(qū)// // if(buff[0]==0x2B)//校驗(yàn)數(shù)據(jù)頭// {// buff_index++; // }// else單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第3頁(yè)。// {單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第3頁(yè)。// buff_index=0;// }// // if(buff_index==8)//獲取數(shù)據(jù)尾// {// length=(buff[7]-0x30)+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#defineQueueArraySize 32//隊(duì)列長(zhǎng)度(字節(jié))typedefstructQueue{ unsignedcharfront;//隊(duì)列頭 unsignedcharrear;//隊(duì)列尾+1 unsignedchar*pArray;//指向字節(jié)數(shù)組}QueueTypeDef;單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第4頁(yè)。單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第4頁(yè)。externQueueTypeDefQueue;externunsignedcharqueueArray[QueueArraySize];voidqueue_Init(QueueTypeDef*pQ,unsignedchar*array);//初始化boolfull_queue(QueueTypeDef*pQ);//滿(mǎn)boolemput_queue(QueueTypeDef*pQ);//空boolen_queue(QueueTypeDef*pQ,unsignedcharval);//入隊(duì)列boolout_queue(QueueTypeDef*pQ,unsignedchar*dat);//出隊(duì)列#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è)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第5頁(yè)。單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第5頁(yè)。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ù)接收緩沖流實(shí)現(xiàn)1:文件:queue.h#ifndef__QUEUE_H__#define__QUEUE_H__#ifndefBOOL#defineBOOL unsignedchar#defineTRUE 1#defineFALSE 0#endif#defineMessageSize 10//消息長(zhǎng)度(字節(jié))單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第6頁(yè)。#defineMessQueueSize 20//隊(duì)列長(zhǎng)度sizeof(MessageTypeDef)單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第6頁(yè)。typedefunsignedcharu8;typedefunsignedintu16;typedefstructMessage//消息數(shù)據(jù)結(jié)構(gòu){ u8clientID; //客戶(hù)端名 u8messgeLength;//消息長(zhǎng)度 u8message_str[MessageSize];//存放消息的數(shù)組 }MessageTypeDef;typedefstructQueue//消息隊(duì)列數(shù)據(jù)結(jié)構(gòu){ u8front; //隊(duì)列頭 u8rear; //隊(duì)列尾+1 MessageTypeDefmessage[MessQueueSize];//消息 BOOL(*postMessage)(MessageTypeDefdat);//消息進(jìn)列 BOOL(*getMessage)(MessageTypeDef*datAddr);//消息出列 }MessQueue;externMessQueuemess_queue;voidMessageQueueInit(void);//初始化BOOLfull_queue(void);//判斷是否為滿(mǎn)BOOLemput_queue(void);//判斷是否為空BOOLen_queue(MessageTypeDefmessage);//入列BOOLout_queue(MessageTypeDef*message);//出列#endif2:文件:queue.c#include"queue1.h"MessQueuemess_queue;//定義消息隊(duì)列單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第7頁(yè)。voidMessageQueueInit(void)//初始化單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第7頁(yè)。{ mess_queue.front=0; mess_queue.rear=0; mess_queue.postMessage=en_queue; mess_queue.getMessage=out_queue;}BOOLfull_queue(void)//判斷隊(duì)列是否為滿(mǎn){ if((mess_queue.rear+1)%MessQueueSize==mess_queue.front)//rear+1=front { returnTRUE; } else { returnFALSE; }}BOOLemput_queue(void)//判斷隊(duì)列是否為空{(diào) if(mess_queue.front=mess_queue.rear)//front=rear { returnTRUE; } else { returnFALSE; }}BOOLen_queue(MessageTypeDefmessage)//入列{ if(full_queue())//判斷隊(duì)列是否為滿(mǎn) { returnFALSE; } else { u8i=0; 單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第8頁(yè)。 (&(mess_queue.message[mess_queue.rear]))->clientID=message.clientID;單片機(jī)數(shù)據(jù)接收緩沖流的設(shè)計(jì)與實(shí)現(xiàn)全文共9頁(yè),當(dāng)前為第8頁(yè)。 (&(mess_queue.message[mess_queue.rear]))->messgeLength=message.messgeLength; for(i=0;i<(message.messgeLength);i++) { (&(mess_queue.message[mess_q
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 教育培訓(xùn)合作委托居間合同
- 品牌營(yíng)銷(xiāo)推廣策略指南
- 技術(shù)產(chǎn)品銷(xiāo)售合同
- 華為勞動(dòng)合同管理制度
- 遺傳基因技術(shù)服務(wù)合同
- 外貿(mào)實(shí)務(wù)操作作業(yè)指導(dǎo)書(shū)
- 倉(cāng)儲(chǔ)配送合同
- 智能工廠(chǎng)建設(shè)與運(yùn)營(yíng)作業(yè)指導(dǎo)書(shū)
- 2025年來(lái)賓貨運(yùn)從業(yè)資格證模擬考試題庫(kù)
- 2025年陜西貨運(yùn)從業(yè)資格考試模擬考試題庫(kù)及答案大全
- 小學(xué)校本課程教材《趣味數(shù)學(xué)》
- 干細(xì)胞療法推廣方案
- (2024年)電工安全培訓(xùn)(新編)課件
- mil-std-1916抽樣標(biāo)準(zhǔn)(中文版)
- 城鄉(xiāng)環(huán)衛(wèi)一體化內(nèi)部管理制度
- 廣匯煤炭清潔煉化有限責(zé)任公司1000萬(wàn)噸年煤炭分級(jí)提質(zhì)綜合利用項(xiàng)目變更環(huán)境影響報(bào)告書(shū)
- 小學(xué)數(shù)學(xué)六年級(jí)解方程練習(xí)300題及答案
- 大數(shù)據(jù)在化工行業(yè)中的應(yīng)用與創(chuàng)新
- 光伏十林業(yè)可行性報(bào)告
- 小學(xué)綜合實(shí)踐《我做環(huán)保宣傳員 保護(hù)環(huán)境人人有責(zé)》
- 鋼煤斗內(nèi)襯不銹鋼板施工工法
評(píng)論
0/150
提交評(píng)論