




已阅读5页,还剩1页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
玩转单片机之三-串口通信,接收数据单片机接收代码#include #define uchar unsigned char /byte#define uint unsigned int /wordsbit led1=P00; sbit fir=P24; /fir=0;工作sbit sec=P25; /sec=0;工作sbit thi=P26; /thi=0;工作sbit fot=P27; /fot=0;工作uchar table=0x28,0xeb,0x32,0xa2,0xe1,0xa4,0x24,0xea,0x20,0xa0;/P1=tablei;/* 0 1 2 3 4 5 6 7 8 9 */static uchar dispbuf5;/动态显示数字的函数void scandisp(void) unsigned int i; fir=0; P1=table dispbuf0 ; for(i=0;i200;i+);fir=1; sec=0; P1=table dispbuf1 ; for(i=0;i200;i+);sec=1; thi=0; P1=table dispbuf2 ; for(i=0;i200;i+);thi=1; fot=0; P1=table dispbuf3 ; for(i=0;i200;i+);fot=1; /十六进制转十进制存储void HEX_TO_BCD(unsigned int n) dispbuf3=n/1000; dispbuf2=(n/100)%10; dispbuf1=(n/10)%10; dispbuf0=n%10;void main(void) uchar a; uint mydata; mydata=0x00; TMOD=0x20; PCON=0x00; SCON=0x50; TL1=0xfd; TH1=0xfd; TR1=1; while(1)/动态现实是接收的数据 /如果没有接收到数据,RI=0,一直循环显示原值 /如果有接收到数据,RI=1,跳出循环重新计算并再次进入循环 HEX_TO_BCD(mydata); while(RI=0) scandisp(); RI=0; /重新置0 a=SBUF;/从缓冲区获取数据 mydata=a; /HEX_TO_BCD(mydata); /scandisp(); /SBUF=a; /while(TI=0) /TI=0; 1 自定义数据通信协议 这里所说的数据协议是建立在物理层之上的通信数据包格式。所谓通信的物理层就是指我们通常所用到的RS232、RS485、红外、光纤、无线等等通信方式。在这个层面上,底层软件提供两个基本的操作函数:发送一个字节数据、接收一个字节数据。所有的数据协议全部建立在这两个操作方法之上。通信中的数据往往以数据包的形式进行传送的,我们把这样的一个数据包称作为一帧数据。类似于网络通信中的TCPIP协议一般,比较可靠的通信协议往往包含有以下几个组成部分:帧头、地址信息、数据类型、数据长度、数据块、校验码、帧尾。 帧头和帧尾用于数据包完整性的判别,通常选择一定长度的固定字节组成,要求是在整个数据链中判别数据包的误码率越低越好。减小固定字节数据的匹配机会,也就是说使帧头和帧尾的特征字节在整个数据链中能够匹配的机会最小。通常有两种做法,一、减小特征字节的匹配几率。二、增加特征字节的长度。通常选取第一种方法的情况是整个数据链路中的数据不具有随即性,数据可预测,可以通过人为选择帧头和帧尾的特征字来避开,从而减小特征字节的匹配几率。使用第二种方法的情况更加通用,适合于数据随即的场合。通过增加特征字节的长度减小匹配几率,虽然不能够完全的避免匹配的情况,但可以使匹配几率大大减小,如果碰到匹配的情况也可以由校验码来进行检测,因此这种情况在绝大多说情况下比较可靠。 地址信息主要用于多机通信中,通过地址信息的不同来识别不同的通信终端。在一对多的通信系统中,可以只包含目的地址信息。同时包含源地址和目的地址则适用于多对多的通信系统。 数据类型、数据长度和数据块是主要的数据部分。数据类型可以标识后面紧接着的是命令还是数据。数据长度用于指示有效数据的个数。 校验码则用来检验数据的完整性和正确性。通常对数据类型、数据长度和数据块三个部分进行相关的运算得到。最简单的做法可是对数据段作累加和,复杂的也可以对数据进行CRC运算等等,可以根据运算速度、容错度等要求来选取。2 上位机和下位机中的数据发送 物理通信层中提供了两个基本的操作函数,发送一个字节数据则为数据发送的基础。数据包的发送即把数据包中的左右字节按照顺序一个一个的发送数据而已。当然发送的方法也有不同。 在单片机系统中,比较常用的方法是直接调用串口发送单个字节数据的函数。这种方法的缺点是需要处理器在发送过程中全程参与,优点是所要发送的数据能够立即的出现在通信线路上,能够立即被接收端接收到。另外一种方法是采用中断发送的方式,所有需要发送的数据被送入一个缓冲区,利用发送中断将缓冲区中的数据发送出去。这种方法的优点是占用处理器资源小,但是可能出现需要发送的数据不能立即被发送的情况,不过这种时延相当的小。对于51系列单片机,比较倾向于采用直接发送的方式,采用中断发送的方式比较占用RAM资源,而且对比直接发送来说也没有太多的优点。以下是51系列单片机中发送单个字节的函数。void SendByte(unsigned char ch) SBUF = ch; while(TI = 0); TI = 0; 上位机中关于串口通信的方式也有多种,这种方式不是指数据有没有缓冲的问题,而是操作串口的方式不同,因为PC上数据发送基本上都会被缓冲后再发送。对于编程来说操作串口有三种方式,一、使用windows系统中自带的串口通信控件,这种方式使用起来比较简单,需要注意的是接收时的阻塞处理和线程机制。二、使用系统的API直接进行串口数据的读取,在windows和linux系统中,设备被虚拟为文件,只需要利用系统提供的API函数即可进行串口数据的发送和读取。三、使用串口类进行串口操作。在此只介绍windows环境下利用串口类编程的方式。CSerialPort是比较好用的串口类。它提供如下的串口操作方法:void WriteToPort(char* string, int len); 串口初始化成功后,调用此函数即可向串口发送数据。为了避免串口缓冲所带来的延时,可以开启串口的冲刷机制。3 下位机中的数据接收和协议解析 下位机接收数据也有两种方式,一、等待接收,处理器一直查询串口状态,来判断是否接收到数据。二、中断接收。两种方法的优缺点在此前的一篇关于串口通信的文章中详细讨论过。得出的结论是采用中断接收的方法比较好。 数据包的解析过程可以设置到不同的位置。如果协议比较简单,整个系统只是处理一些简单的命令,那么可以直接把数据包的解析过程放入到中断处理函数中,当收到正确的数据包的时候,置位相应的标志,在主程序中再对命令进行处理。如果协议稍微复杂,比较好的方式是将接收的数据存放于缓冲区中,主程序读取数据后进行解析。也有两种方式交叉使用的,比如一对多的系统中,首先在接收中断中解析“连接”命令,连接命令接收到后主程序进入设置状态,采用查询的方式来解析其余的协议。 以下给出具体的实例。在这个系统中,串口的命令非常简单。所有的协议全部在串口中断中进行。数据包的格式如下:0x55, 0xAA, 0x7E, 0x12, 0xF0, 0x02, 0x23, 0x45, SUM, XOR, 0x0D 其中0x55, 0xAA, 0x7E为数据帧的帧头,0x0D为帧尾,0x12为设备的目的地址,0xF0为源地址,0x02为数据长度,后面接着两个数据0x23, 0x45,从目的地址开始结算累加、异或校验和,到数据的最后一位结束。 协议解析的目的,首先判断数据包的完整性,正确性,然后提取数据类型,数据等数据,存放起来用于主程序处理。代码如下:if(state_machine = 0) /协议解析状态机 if(rcvdat = 0x55) /接收到帧头第一个数据 state_machine = 1; else state_machine = 0; /状态机复位else if(state_machine = 1) if(rcvdat = 0xAA) /接收到帧头第二个数据 state_machine = 2; else state_machine = 0; /状态机复位else if(state_machine = 2) if(rcvdat = 0x7E) /接收到帧头第三个数据 state_machine = 3; else state_machine = 0; /状态机复位else if(state_machine = 3) sumchkm = rcvdat; /开始计算累加、异或校验和 xorchkm = rcvdat; if(rcvdat = m_SrcAdr) /判断目的地址是否正确 state_machine = 4; else state_machine = 0;else if(state_machine = 4) sumchkm += rcvdat; xorchkm = rcvdat; if(rcvdat = m_DstAdr) /判断源地址是否正确 state_machine = 5; else state_machine = 0; else if(state_machine = 5) lencnt = 0; /接收数据计数器 rcvcount = rcvdat; /接收数据长度 sumchkm += rcvdat; xorchkm = rcvdat; state_machine = 6;else if(state _machine = 6 | state _machine = 7) m_ucDatalencnt+ = rcvdat; /数据保存 sumchkm += rcvdat; xorchkm = rcvdat; if(lencnt = rcvcount) /判断数据是否接收完毕 state_machine = 8; else state_machine = 7;else if(state_machine = 8) if(sumchkm = rcvdat) /判断累加和是否相等 state_machine = 9; else state_machine = 0;else if(state_machine = 9) if(xorchkm = rcvdat) /判断异或校验和是否相等 state_machine = 10; else state_machine = 0;else if(state_machine = 10) if(0x0D = rcvdat) /判断是否接收到帧尾结束符 retval = 0xaa; /置标志,表示一个数据包接收到 state_machine = 0; /复位状态机 此过程中,使用了一个变量state_machine作为协议状态机的转换状态,用于确定当前字节处于一帧数据中的那个部位,同时在接收过程中自动对接收数据进行校验和处理,在数据包接收完的同时也进行了校验的比较。因此当帧尾结束符接收到的时候
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025人力资源管理聘用合同书范本
- 2025关于泉州市房地产代理合同(乙种本)
- 2025年甘肃省平凉华亭市山寨回族乡招聘行政村村文书模拟试卷(含答案详解)
- 2025广东农信社校园招聘考前自测高频考点模拟试题及答案详解(典优)
- 《2025年以自有车辆抵债合同》
- 2025江苏苏州市轨道交通集团有限公司专业化青年人才定岗特选人员考前自测高频考点模拟试题及答案详解(全优)
- 2025年三环集团留学生招聘考前自测高频考点模拟试题(含答案详解)
- 2025福建省梧凤文旅集团有限公司招聘1名工作人员模拟试卷及完整答案详解
- 2025辽宁工程技术大学招聘高层次人才216人考前自测高频考点模拟试题含答案详解
- 2025年辉南县补录1名乡镇、街道派驻消防文员模拟试卷及答案详解(新)
- 2025年建筑施工安全教育试题及答案
- 桩基质量管理制度
- 口腔颌面外科缝合技术要点
- 2025至2030中国军用导航仪器行业市场深度研究与战略咨询分析报告
- 2025年科创板开户试题及答案
- 西宁市供热管理暂行办法
- 中职导游课程课件
- 静脉血栓护理课件
- 精神科护理学练习题
- 造口患者叙事护理
- 中医学专业职业生涯规划书2300字数
评论
0/150
提交评论