发新帖

[原创] 单片机与PC通信之单片机接收字符串详解!

[复制链接]
发表于 2017-2-10 11:18:27
| 6776 查看 | 13 回复
本帖最后由 SingleYork 于 2017-2-11 09:02 编辑

单片机跟PC通信相信大家都有接触,比如,PC通过发送不同指令来让单片机执行不同的动作:


当PC发送一个字符‘A’,然后单片机亮个红灯;

当PC发送一个字符‘B’,然后单片机亮个绿灯;

当PC发送一个字符‘C’,然后单片机亮个黄灯;


大家对这种操作肯定不陌生,因为很多教材上都有讲到,但是如果PC发送一个‘A1’,要让单片机把三个灯全灭了,该怎么处理呢?


也许有些人会认为,发送‘A’跟‘A1’不是同样的操作么?之前是if(SBUF=='A')的时候让“LED_R=0”就好了,如果换成‘A1’就直接改成if(SBUF=='A1')的时候让“LED_R=0”不就好了么?哦,不对,A1应该是个字符串,应该用双引号,所以应该是if(SBUF=="A1")!


纳尼?这样就真的没有问题了么?


我们应该不难发现,A是一个字符,而A1是一个字符串。对51单片机有一定了解的小伙伴肯定知道,串口接收的SBUF寄存器是一个8位的寄存器,也就是说,它每次只能接收一个8位的数据,而一个字符A就已经占了8位了,而且每次接收到新的数据的时候,会把之前SBUF里面的数据刷新掉,那么,实际上接收“A1”这个字符串的时候,SBUF里面接收到的数据肯定不可能是A1了。那么,究竟要如何做,才能实现接收到“A1”这么一个字符串呢?


这不,昨天在QQ群里面看到一小伙伴在问一个问题,那就是单片机如何接收字符串,也就是如何将接收的'A'改成接收“A1”。当时给了一个思路,是用一个数组去保存接收到的数据,然后在判断数组里面的元素。但是貌似这个小伙伴还没有搞定,这不,今天在论坛里面又看到了这位小伙伴的求助帖。那么好吧,为了能让更多的小伙伴都能知道怎么实现这个功能,笔者SingleYork就来灌灌水吧,同时会用Proteus仿真出结果进行验证。


以下内容仅供参考,若讲的不对,请勿口水,如有更好的方法法,欢迎跟帖回复!


首先,要在电脑上仿真的话,我们需要安装Proteus仿真软件,笔者SingleYork用的是8.3版本,稳定无闪退,安装方式请看本菜科普帖(含软件下载地址):Proteus 8.3 WIN7 64 再也不用担心我闪退了!http://www.ickey.cc/community/forum.php?mod=viewthread&tid=26281(出处: ICKEYBBS)



另外,在电脑上模拟串口的话,还需要一个软件,那就是Virtual Serial Port Driver,这个软件百度里面很容易找到,也可以从笔者SingleYork给的附件中下载:



最后一个软件,就是串口助手了,这个就可以随便用哪个串口助手就好了,笔者SingleYork这里有好几个串口助手,看大家喜欢哪个就下载哪个吧:



软件全部安装好后,那就可以开始建立仿真了。笔者SingleYork以红、黄、绿三个指示灯为例:

1、  当单片机从PC端收到“m1”时,红灯亮,其他两个灯灭;

2、  当单片机从PC端收到“m2”时,绿灯亮,其他两个灯灭;

3、  当单片机从PC端收到“m3”时,黄灯亮,其他两个灯灭;

4、  当单片机从PC端收到“m4”时,三个灯全灭;


根据以上功能,我们建立了如下仿真:



也许很多小伙伴看到这里会怀疑,为什么连最小系统也没有呢?笔者SingleYork会告诉你:为了节约时间,笔者SingleYork偷懒了一下,省掉了一些电路,其实在仿真里面是可以省掉一些外围电路的,在实际应用中,可不能这么干哟!


细心的小伙伴们或许还会发现几个问题:纳尼?!单片机上的RXD和TXD跟PC上的RXD和TXD直连起来了,不是应该交叉的么?!确定这样没有问题么?而且单片机跟PC通信时,中间不是应该还有个RS232芯片(TTL电平转232电平)么?



说到底,还是笔者SingleYork偷懒了,省掉了一些仿真不需要的电路!因为这里笔者SingleYork要讲的重点不是单片机外围电路部分,而是如何实现上面提到的功能。另外,单片机上的RXD直接连到了PC上的RXD,而不是交叉,这里主要是因为用的虚拟串口的缘故,如果用的是硬件串口,可不能这么干哟!好吧,就不要纠结这些问题了吧,咱们还是回到重点部分。


首先,我们双击单片机,将仿真时晶振的频率跟程序中的晶振频率设置成一致:11.0592MHZ,同时将编译好的HEX文件加载进去:



接下来,我们设置仿真串口的一些参数:



这里的串口号大家根据自己电脑上实际的虚拟串口号去设置,由于笔者SingleYork电脑上的虚拟串口好是COM2和COM6这一组,故而选择了COM2:



上述参数设置完成后,我们就可以打开串口助手了,同样,把波特率、停止位之类的参数设置成跟程序一致:



细心的小伙伴可能会发现了一个问题,这里的COM号笔者SingleYork选的是COM6,而刚才仿真里面我们设置的是COM2,是我看错了,还是笔者SingleYork弄错了?好吧,不用怀疑你的眼睛,也不用怀疑笔者SingleYork的智商,两个都没有错,这也是用的虚拟串口的问题。其实虚拟串口COM2和COM6这两东西吧,我们可以这样去理解:COM2可以认为是PC上的COM口,而COM6可以理解为是单片机上的串口,我们用串口调试助手当作单片机来给仿真电路发送数据,而这里的仿真电路就相当于是PC了。也许笔者SingleYork说的不是很对,但是大家可以这么去理解吧,不然大脑要死机了,哈哈!


硬件模拟部分搭建好之后,那么笔者SingleYork再来跟大家分析一下代码部分吧。


首先,我们定义了三个指示灯:LED_R、LED_G、LED_Y,同时定义了一个数组用于保存接收到的数据,至于这个数组的长度,大家可以根据实际情况去定义,本菜这里定义的长度是10,实际上我们这里只需要用到2个字节长度就好了。



串口配置的部分笔者SingleYork就不再啰嗦了,教材上一大把。这里笔者SingleYork重点要跟大家讲讲中断接收部分。思路是这样的:首先将串口收到的数据存放到一个名为table的数组里面,然后再来判断数组里面的元素是不是符合要求,若符合要求,则执行相应的动作,动作执行完成后将数组里面的内容清空,等待下一次接收数据。具体代码如下:



接下来,我们就要来验证结果了,我们打开仿真电路,开始仿真,同时也打开串口助手,准备发送数据。


首先,我们发送“m1”,看实验结果(红灯亮了):



接下来,我们发送“m2”,看实验结果(绿灯亮了):



接下来,继续发送“m3”,看实验结果(黄灯亮了):



最后,我们发送“m4”,看实验结果(三个灯都灭了):



我们可以看到,实验结果跟我们预期的一致,说明我们的程序是可行的。当然,笔者SingleYork给的实现方法不一定是最好的,相信还有很多小伙伴能想出更多更好的办法来实现上述功能,欢迎大家跟帖回复!

好了,关于单片机如何接收字符串的问题笔者SingleYork就讲到这里了,小伙伴们若还有其他问题可以跟帖留言,最后给大家奉上仿真源文件及程序的源代码。


仿真源文件:



程序源代码:



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

评分

参与人数 6 +34 收起 理由
donatello + 1
new world + 1
突然的自我 + 20 很给力!学习了
LiuYang + 1
qq1328512480 + 1
静水竹林 + 10 很给力!

查看全部评分

我要点赞 9

举报

待业青年

Rank: 1

发表于 2017-2-17 11:15:55
谢谢,楼主给力!!!!!
我要点赞 0

举报

发表于 2017-2-28 16:28:44
恩恩。不错加精
我要点赞 0

举报

发表于 2017-3-1 08:05:38
给楼主点个赞!
我要点赞 0

举报

初级技术员

Rank: 3Rank: 3

发表于 2017-3-5 22:35:07
貌似C可以进行字符串对比,那样应该也可以吧?
我要点赞 0

举报

发表于 2017-3-6 08:21:01
cawyai23 发表于 2017-3-5 22:35
貌似C可以进行字符串对比,那样应该也可以吧?

是可以,但是首先还是得正确收到数据,对吧?
我要点赞 0

举报

发表于 2017-4-19 10:49:06
对我们新手有很大帮助 给楼主点个赞!
我要点赞 0

举报

发表于 2017-4-20 08:19:57
_落雪千寒灬 发表于 2017-4-19 10:49
对我们新手有很大帮助 给楼主点个赞!

感谢支持……
我要点赞 0

举报

发表于 2017-4-27 15:50:03
新手,学习了,感谢分享……
我要点赞 0

举报

发表于 2017-5-11 18:01:02
新手  学习了   哈哈  
我要点赞 0

举报

您需要登录后才可以回帖 登录 | 立即注册