




下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、由一个串口接收数据引发的问题与字节缓冲流系统的设计在一个wifi数据收发项目调试时发现,数据在高速连续发送和接收时,经常出现数据出现了丢失和系统的死机。单片机在接收串口数据时,传统采用中断方法或者查询指定标志位方法接收数据。查询指定标志位:这种方式通常在main函数的大循环中不断的检测标志位或者等待该标志位来判断是否有数据接收。通常有两种方式:1:在大循环中if(标志位成立)表明有数据接收然后进行数据的处理。优点:不会引起整个main函数线程的阻塞;在简单的数据接收项目中可以使用缺点:单片机一般都为单线程,复杂的控制中采用操作系统,例如UC/OS;所以,将所以都函数放在main函数大循环中进行
2、轮番处理。整个循环周期时间不确定,其他任务函数可能发生阻塞,不能够保证数据到来时,正好在执行检测指定标志位,从而出现了数据丢失。2:在大循环中while(标志位);通过while来等待数据的到来。优点:数据不会出现丢失,稳定。缺点:整个main函数主线程出现堵塞,其他函数无法执行,上述所示。显然:以上两种发送在复杂的控制系统中是不能采用的,因此:在没有多任务操作系统时,数据的接收采用中断接收的法式是最佳的。使用中断,可以不用查询和等待的方式接收数据,解决了许多问题。,此时,单片机可以说是多线程执行程序。main函数是一个线程,中断服务子程序是一个线程。中断是前台,main函数是后台。由于是多线
3、程(一般而言),不得不考虑数据的安全性。中断可能随时到来。Main函数会随时被打断,程序计数器寄存器PC指针指向中断函数入口地址,指向中断函数。Main函数在处理数据时被打断,可能会引发数据的丢失。共同访问全局变量时,使用互斥信号量等一些手段保障数据不被修改。设计可能被中断打断的函数时,要注意函数的重入问题,像static等关键字。字节接收缓冲系统设计的核心思想:1:前台(即中断)负责接收数据,并不进行处理,将数据放入消息队列中。2:后台(main函数)负责从消息队列中取出消息,并处理。3:整个接收系统核心为队列,可以当做缓冲区;遵循先进先出原则FIFO采用队列方式接收数据比较简单,并且实现了
4、缓冲,不会出现数据的丢失。消息队列核心算法实现:1:消息队列核心数据结构:typedefstructQueueunsignedcharfront;/队歹U头索弓Iunsignedcharrear;队歹U尾索弓Iunsignedchar*pArray;简易的队列指向数组QueueTypeDef;2:判断队列是否为满伪算法if(rear+1)%数组的元素个数)=front)3:判断队列是否为空伪算法if(rear=front)4:将数据加入队列伪算法if(队列不为满)(pArrayrear=数据;rear=(rear+1)%数组的长度)5:将数据从队列中取出伪算法if(队列不为空)(Val=pAr
5、rayfront;front=(front+1)%数组长度)以上是接收最简单的一个字节的队列;ASCIIC编译通过不依赖于单片机;将其加入中断服务子程序中,把接收的数据加入队列中;以stm32单片机串口中断为例: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);将数据加入消息队列中)if(USA
6、RT_GetFlagStatus(USART2,USART_FLAG_ORE)=SET)(USART_ClearFlag(USART2,USART_FLAG_ORE);USART_ReceiveData(USART2);)Main函数从消息队列中取出数据unsignedcharval;while(1)(if(out_queue(&Queue,&val)从队列中取出数据if(i=16)i=0;LCD_print(1,i,val);显示取出的数据i+;).其他任务.)以上算法思路是以接收最简单的一个字节为例:当然可以接收更复杂的数据,数据结构如下typedefstructMessa
7、ge消息数据结构(u8clientID;/客户端名u8messgeLength;/消息长度u8message_strMessageSize;/存放消息的数组MessageTypeDef;typedefstructQueue消息队列数据结构(u8front;队列头u8rear;队列尾+1MessageTypeDefmessageMessQueueSize;/艄息BOOL(*postMessage)(MessageTypeDefdat);消息进列BOOL(*getMessage)(MessageTypeDef*datAddr);/消息出列MessQueue;MessageTypeDef;这个数据结
8、构中构造了接收数据的格式并不是前面最简单的一个字节,根据实际接收数据的需要来构造数据结构,当然在中断函数中要进行数据的处理,也可以放在主函数中处理数据,中断中依然是将字节放入消息队列中。主函数处理完数据后在放入另一个消息队列中,由其他函数处理数据,多级消息队列。以下是带特定格式的消息数据处理:buffbuff_index=USART_ReceiveData(USART2);将接收的数据(1个字节)放入缓冲区/if(buff0=0x2B)校验数据头/buff_index+;/else/buff_index=0;/if(buff_index=8)获取数据尾/length=(buff7-0x30)+
9、1+buff_index;/计算数据尾索引/if(buff_index=length)/length=200;/buff_index=0;receive=TRUE;/数据接收完成/DISABLE_WIFI_RX_IRQ();/附:字节缓冲流系统源码:文件queue.h#ifndef_QUEUE_H_#define_QUEUE_H_#ifndefbool#defineboolunsignedchar#definetrue1#definefalse0#endif#defineQueueArraySize32队列长度(字节)typedefstructQueueunsignedcharfront;队列
10、头unsignedcharrear;队列尾+1unsignedchar*pArray;指向字节数组QueueTypeDef;externQueueTypeDefQueue;externunsignedcharqueueArrayQueueArraySize;voidqueue_Init(QueueTypeDef*pQ,unsignedchar*array);初始化boolfull_queue(QueueTypeDef*pQ);满boolemput_queue(QueueTypeDef*pQ);空boolen_queue(QueueTypeDef*pQ,unsignedcharval);/入队歹
11、Uboolout_queue(QueueTypeDef*pQ,unsignedchar*dat);/出队歹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;附:复杂数据接收缓冲流实现1:文件:queue.h#ifndef_QUEUE_H_#define_QUEUE_H_#ifndef
14、BOOL#defineBOOLunsignedchar# defineTRUE1# defineFALSE0#endif# defineMessageSize10消息长度(字节)# defineMessQueueSize20队列长度sizeof(MessageTypeDef)typedefunsignedcharu8;typedefunsignedintu16;typedefstructMessage消息数据结构(u8clientID;/客户端名u8messgeLength;/消息长度u8message_strMessageSize;/存放消息的数组MessageTypeDef;typedef
15、structQueue消息队列数据结构(u8front;队列头u8rear;队列尾+1MessageTypeDefmessageMessQueueSize;/艄息BOOL(*postMessage)(MessageTypeDefdat);消息进列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;/定义消息队歹UvoidMessageQueuelnit(void)初始化mess_queue.front=0;mess_queue.rear=0;mess_queue.postMessage=en_queue;mess_queue.getMessage=out_queue;)BOOLfull_queue(void)
17、判断队列是否为满(if(mess_queue.rear+1)%MessQueueSize=mess_queue.front)/rear+1=front(returnTRUE;)else(returnFALSE;)BOOLemput_queue(void)判断队列是否为空(if(mess_queue.front=mess_queue.rear)/front=rear(returnTRUE;)else(returnFALSE;)BOOLen_queue(MessageTypeDefmessage)/入歹U(if(full_queue()判断队列是否为满(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等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 产品清单表-采购商品明细列表
- 执业药师一对一培训体系
- 电力治安方案(3篇)
- 律师税务统筹方案(3篇)
- 2025年小学教学常规管理细则
- 2024年酉阳土家族苗族自治县公务员考试行测真题及答案详解(网校专用)
- 2025年广西烟草专卖局(公司)招聘122人笔试模拟试题及答案详解1套
- 2025年广西血液中心招聘4人笔试模拟试题及参考答案详解1套
- 口腔基础培训课件
- 人口管理培训课件
- 工贸行业法律法规清单法规清单
- 物业服务品质提升培训
- 申论大学生村官考试试题及答案指导(2025年)
- DB34T 4090-2022 智能交通系统工程检验规范
- 2023年江苏省五年制专转本英语统考真题(试卷+答案)
- 2024年全国预防接种技能竞赛【决赛】考试题库-上(单选题)
- 湖南省长沙市雨花区2023-2024学年八年级下学期期末考试历史试题(解析版)
- 预后预测模型的建立
- 2023-2024学年山东省济南市高二下学期7月期末学习质量检测数学试题(含答案)
- 《温病学》复习考试题库(带答案)
- 雇佣协议书范本
评论
0/150
提交评论