- 1、本文档共21页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
八 串口通讯 如何提高数据位
本帖最后由 jianhong_wu 于 2013-2-13 17:39 编辑第八节:串口通讯之如何提取数据尾(1)? ?? ???开场白:上两节都介绍了如何提取数据头,这节将介绍如何提取数据尾(鸿哥发明的词)。数据头是指有效数据在关键字的后面,而数据尾恰恰相反,是指有效数据在关键字的前面,这两种方式实战中使用非常频繁,我在这里介绍我自己常用的思路,我很少参考别人的东西,这些东西都是我原创,不知道其他的牛人是怎么编的,如有雷同,纯属巧合。(2)功能需求:? ?? ?? ? 无论是单片机还是上位机,最好在固定协议前多发送一个填充的无效字节0x00,因为硬件原因,第一个字节往往容易丢失。? ?? ?? ???通讯协议:XX YY??EB 00 55?? ?? ?? ???其中后三位 EB 00 55就是我所说的数据尾,它的有效数据XX YY在数据尾的前面。? ?? ?? ?任意时刻,从电脑“串口调试助手”上位机收到的一堆数据中,只要此数据中包含关键字EB 00 55 ,并且此关键字前面两个字节的数据XX YY 分别为01 02,那么就往上位机发送“eb??00 aa”表示确认,同时蜂鸣器叫一声。否则,往上位机发送“eb??00 55”表示出错。(3)硬件原理:把单片机串口通讯的那两个引脚经过一个MAX3232之后直接跟电脑的9针串口通讯。我发现很多朋友会选MAX232这个芯片,而我本人更加推荐用MAX3232。因为MAX232只支持5V,不是宽压的,而MAX3232不但支持5V,还支持3V。每个人的记忆力都很宝贵,用232串口我只选MAX3232,不管它是用5V工作还是3V工作。就像74系列的芯片,我的心中只有你(74HC)没有它(74LS),一样的道理,74HC是宽压,74LS不是宽压。(4)源码适合的单片机:PIC18f4520,晶振为22.1184MHz,波特率115200(5)源代码讲解如下:#includepic18.h? ?? ?? ?//包含芯片相关头文件//补充说明:吴坚鸿程序风格是这样的,凡是输出IO后缀都是_dr,凡是输入的//IO后缀都//是_sr#define??beep_dr??LATA2??//蜂鸣器输出//补充说明:吴坚鸿程序风格是这样的,凡是做延时计数阀值的常量//前缀都用cnt_表示。#define cnt_voice_time? ?150??//蜂鸣器响的声音长短的延时阀值#define cnt_send? ?300? ?? ?? ?? ?//确保接收缓冲区没有继续接收数据,是变量//send_cnt的溢出阀值Void usart_service();? ?? ???//串口通讯服务程序,放在main函数里unsigned char asy_recieve();??//把串口缓冲区的数据一个个提取出来void eusart_send(unsigned char t_data); //串口发送一个字节的数据Void Buf_clear() ;??//把余下的缓冲区清零void Delay11(unsigned int MS); //延时函数//补充说明:吴坚鸿程序风格是这样的,凡是计数器延时的变量//后缀都用_cnt表示。unsigned int voice_time_cnt;? ?? ???//蜂鸣器响的声音长短的计数延时unsigned int send_cnt=0;? ?? ?? ?? ?//一串数据从上位机发过来的时候,他们每个字节之间//的延时间隔很短,如果他们的延时间隔一旦超过了这个send_cnt变量的延时,那么就////认为他们的一串数据已经发送完毕//补充说明:吴坚鸿程序风格是这样的,凡是涉及统计数量的变量//后缀都用_total表示。unsigned int RCREG_total;? ?? ?? ?? ?//统计串口缓冲区已经收了多少个数据unsigned int RCREG_read_total;? ?//统计已经从串口缓冲区读出了多少个数据//补充说明:吴坚鸿程序风格是这样的,凡是用来更新的标识变量,比如液晶刷屏,或者有新接收的串口数据更新等等,后缀一律用_update表示Unsigned char send_update=0;??//一旦有数据从上位机发送过来,就会引发串口接收中////断,在串口中断里,我把send_update=1表示目前正在接收数据,警告单片机先不要//猴急,等串口中断把所有从上位机连续发送过来的一堆数据接收完,再处理。那么什么///时候才知道发送的数据已经发送完毕了呢?用send_cnt识别。因为在串口中断里,我///每次都会把send_cnt=0,而在main
文档评论(0)