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

  • SingleYork
  • LV5工程师
  • |      2017-02-10 11:18:27
  • 浏览量 8619
  • 回复:13
本帖最后由 SingleYork 于 2017-2-11 09:02 编辑 bg4.png

单片机跟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 再也不用担心我闪退了!https://bbs.icxbk.com/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就讲到这里了,小伙伴们若还有其他问题可以跟帖留言,最后给大家奉上仿真源文件及程序的源代码。

仿真源文件:

程序源代码:

  • 0
  • 收藏
  • 举报
  • 分享
我来回复

登录后可评论,请 登录注册

所有回答 数量:4
cawyai23 2017-03-05
貌似C可以进行字符串对比,那样应该也可以吧?
0   回复
举报
发布
SingleYork 回复 2017-03-06
是可以,但是首先还是得正确收到数据,对吧?:)
0   回复
举报
_落雪千寒灬 回复 2017-04-19
对我们新手有很大帮助 给楼主点个赞!
0   回复
举报
2016大圣 2017-03-01
给楼主点个赞!
0   回复
举报
发布
秦时茗月 2017-02-28
恩恩。不错加精
0   回复
举报
发布
xd940940 2017-02-17
谢谢,楼主给力!!!!!
0   回复
举报
发布
x
收藏成功!点击 我的收藏 查看收藏的全部帖子