登录|立即注册|使用QQ帐号登录
论坛 > 51单片机
发帖|
看17331|回32|收藏
楼主 ID:421451 只看他
2019-2-18 18:56

本人单片机小白,第一次发帖,这是我做的51单片机串口通信和LCD1602结合的一个程序设计,掉过几个坑,前后共花费了两天的时间。附件里面是程序源代码,自己写的代码,请大家多多指教。之所以写这个帖子,一个算是做一个总结,另一个是写出自己曾经踩到的误区,希望能帮助到其他人。


视频:
0.png

本人使用的是STC89C52普中的开发板。

需要实现的效果:在液晶上显示从PC机串口上下发的数据,超屏后清屏并将多余字符从头显示。


总体思路:代码是采用多文件写的,更体现模块化设计,在查找修改错误时更加方便。由于将LCD1602设置为两行显示,一行显示16个字节,两行共32个字节,因此设置一个receivedata[32]的数组,用于存放上位机发送置单片机接收缓存区SBUF的数据,再将数组内容运用LCD1602writedata(uchar)函数,使其能在LCD1602液晶屏上显示。通过数组下标或重新设置一个变量统计液晶屏幕上已显示的字节数,当字节数为16的倍数且不为32的倍数时换行,当字节数为32的倍数时清屏,将多余字符从头显示。



误区一:LCD1602writedata(uchar)函数放入中断函数。

QQ图片20190218175143.png

将会遇到的问题:上位机发送字符串,例如123456,LCD1602上只会显示12,缺少3456.这个问题一直困扰了好久,以为是串口通信中断代码函数的错误,导致单片机未能完整接收字符串内容。然而,你可以将划线处注释掉,接着加入:

代码:

  1. SBUF =receivedate[num];
  2.    while(!TI);
  3.    TI=0;
在串口通信助手软件上,你会发现上位机发送的数据,单片机就能完整地发送回来。貌似是存在函数之间的某种冲突,也有可能是代码本身存在着其他错误导致的。总之,LCD1602writedata(uchar)函数最好放在主函数里面。将其移至主函数里面时,不要忘了在中断里面做一个标示,例如flag = 1之类的,使中断完成之后,主函数if(flag)判断语句接收到flag=1为真后,才执行LCD1602writedata(uchar)函数。不然,由于while(1)这个大循环里面,只有一个光秃秃的LCD1602writedata(uchar)函数,你的LCD1602液晶屏上会不断的写入某一字符。


误区二:数组下标num,将num++放入主函数中,企图通过LCD1602初始化设置的指令——每增加一字符,光标自动右移来实现数组数据的显示,且未注意num值在中断结束时的值(因对串口中断不完全理解导致)。

QQ图片20190218181029.png

将会遇到的问题:上位机发送字符,LCD1602上总是只会在同一处地方显示一位字节。需要将num++移回中断,数组接收下标增加要在中断中完成,只要一有中断信号就会触发,中断函数它不会在主函数里面等num++,之后再去响应中断信号,中断就是一个连续的过程,可以说是中间没有停顿的一次性将接受缓冲区SBUF里面的数据都存放到数组中,然而,将num++放入中断函数中,若不加注意,这又牵扯到我原本程序中的另一个错误,未注意num中断结束时的值,即主函数中LCDwritedata(receivedate[num])执行时,num并不等于0的。即数据并不是从头开始输出到LCD液晶屏上。这里就需要使用一个for循环函数。



误区三:未注意数组下标的值和for循环次数n的值,或者说逻辑不清晰,例如原本的错误代码:

QQ图片20190218183301.png

将会遇到的问题:例如输入1234,上位机第一次发送,LCD1602显示正常,第二次发送,LCD1602显示1234会重复两边,第三次发送,LCD1602显示1234会重复三遍,以此类推。。。。。。原因是num = 0放错位置,中断中的num++会使num值不断增加,然而n==32的判定值也会是num=0几乎如同天方夜谭,我在这里就犯了逻辑混乱的错误,静下来重新再理一遍就会发现问题,重新定义一个变量total,专门用来计数已经在LCD液晶屏上显示过的字节总数,不再依靠数组下标来判断什么时候换行,什么时候清屏。

误区三错误效果演示:

[已上传至附件]



单片机的学习结果是充满欢乐的,但过程是痛苦的,尤其是遇到问题,百度搜索也找不到自己想要的答案。希望这篇贴文能填补一些空缺,帮助到需要帮助的人。


全部资料51hei下载地址:


误区三错误效果演示.rar (4.89 MB)
(下载次数: 114, 2019-2-18 22:34 上传)

下载积分: 黑币 -5


串口通信LCD1602.rar (41.27 KB)
(下载次数: 397, 2019-2-18 17:21 上传)

下载积分: 黑币 -5




沙发 ID:421451 只看他
2019-9-21 23:31

引用:

我在地铁吃闸机 发表于 2019-9-18 15:02
想知道
SBUF =receivedate[num];
   while(!TI);

好久没用51了,没记错的话,应该是等待发送缓冲区内的数据发送完成,如果不完成,TI位的值一直为0,0取反就是1,while(1)一直在这个空循环里面重复,等待完成,发送完成TI会置1,1取反就是0,也就是while(0),跳出这个循环。
板凳 ID:421451 只看他
2019-9-21 23:46

引用:

吴国太真大 发表于 2019-8-11 20:53
这个程序确实能实现上述功能,但是串口助手接受的数据会出现丢失数据的现象,跟这两句语句有关//while(!TI) ...

好久没用51了,当时学51是为了向32过渡,刚想起这个论坛,登录看看,就看到有7个新评论了,哈哈。找找原来51的代码,由于重整了系统,数据转移时弄没了。记不清我当时有没有注意过会发生这种问题,好像测试的时候,注重点都放在1602了。这个代码写的还是不满意,因为1602显示字符的速度太慢了,一个一个往外冒,后来也试着优化,感觉速度提不上去还是选择实现的方法本身问题,时间复杂度太高。如果移植到32上,用12864,可能会快些。7月份用32做过一个类似电子书的东西,上位机发送数据,12864来显示,支持上下翻页。思路和51这个程序有点类似,再加上32的运算速度是1ns一句指令,一发就显示~~~转眼接触单片机大半年了,时间过得真快。
地板 ID:421451 只看他
2019-9-21 23:48

引用:

17863025410 发表于 2019-8-31 14:45
全部程序还有吗,我想借鉴一下

。。。今年暑假重整了系统,拷贝D盘数据的时候,32的代码留下来了,51的好像弄丢了,我刚在D盘找了找,没找到。只剩这个论坛还有份记录了,抱歉~
5# ID:486156 只看他
2019-3-14 19:52
咋么用的,我的显示不了
6# ID:486156 只看他
2019-3-14 19:59
不能用啊
7# ID:390642 只看他
2019-3-14 22:13
下载 看看   谢谢分享
8# ID:421451 只看他
2019-3-24 15:00

引用:

呀呀呀呀呀呀米 发表于 2019-3-14 19:52
咋么用的,我的显示不了

什么地方用不了?。。。。
9# ID:421451 只看他
2019-3-24 15:01

啥地方用不了啊?求告知,我传的时候就是自己板子上面跑了能运行的那个文件。。。。
10# ID:421451 只看他
2019-3-24 15:04
有问题的,可以加我企鹅号,14号的评论,我竟然今天才发现,23333
11# ID:598751 只看他
2019-8-11 20:53
这个程序确实能实现上述功能,但是串口助手接受的数据会出现丢失数据的现象,跟这两句语句有关//while(!TI);//TI = 0;加上就好了。
12# ID:544565 只看他
2019-8-15 16:18
试了下,是可以,跟8楼说的一样
13# ID:92746 只看他
2019-8-18 15:02
下载 看看   谢谢分享
14# ID:601871 只看他
2019-8-21 10:55
很给力
15# ID:605801 只看他
2019-8-31 14:45
全部程序还有吗,我想借鉴一下
16# ID:451441 只看他
2019-9-5 10:11
好东西,正好可以借鉴一下
17# ID:600837 只看他
2019-9-18 15:02
想知道
SBUF =receivedate[num];
   while(!TI);
   TI=0;
这行代码里面,while(!TI)这句能不能给解释下。。
18# ID:688451 只看他
2020-2-25 21:20
里面的hex文件能正确运行,但是c文件是错的,运行的时候LCD不显示
19# ID:699241 只看他
2020-2-29 16:53
大佬 我想问下
20# ID:699241 只看他
2020-2-29 16:55
我想问下 ,温度数据是怎样存放SBUF中再发送给电脑的,这部分弄了很久都没弄好
21# ID:421451 只看他
2020-3-3 18:22

引用:

牛逼的屌 发表于 2020-2-25 21:20
里面的hex文件能正确运行,但是c文件是错的,运行的时候LCD不显示

不会吧。。。。。。这么玄学?我记得我去年没有没传错啊。能运行又不显示。。。到底是行还是不行
22# ID:421451 只看他
2020-3-3 18:30

引用:

710253949 发表于 2020-2-29 16:55
我想问下 ,温度数据是怎样存放SBUF中再发送给电脑的,这部分弄了很久都没弄好

原来是你,哈哈。我把这个问题关键部分的代码贴出来。

代码:

  1.         SBUF=(temp % 10000 / 1000)+ '0';
  2.         while(!TI);       //是否发送完成
  3.         TI=0;
  4.         SBUF=(temp % 1000 / 100) + '0';
  5.         while(!TI);       //是否发送完成
  6.         TI=0;
  7.         SBUF=(temp %  100 / 10) + '0';
  8.         while(!TI);       //是否发送完成
  9.         TI=0;
  10.         SBUF=(temp %  10 / 1)  + '0';
  11.         while(!TI);       //是否发送完成
  12.         TI=0;
23# ID:130345 只看他
2020-4-3 11:19
谢谢楼主分享
24# ID:711622 只看他
2020-4-14 20:59
显示乱码
25# ID:745437 只看他
2020-5-25 19:29
给力  我想了解一下
26# ID:421451 只看他
2020-6-11 10:39

同样的开发板?
27# ID:851981 只看他
2020-12-2 21:41
想看看原理图
28# ID:706762 只看他
2020-12-6 19:20
不知楼主能不能发个串口接受12864显示的程序
29# ID:768564 只看他
2020-12-10 12:48
楼主的帖子很给力,非常棒
30# ID:421451 只看他
2020-12-11 14:56

引用:

谭天说地 发表于 2020-12-6 19:20
不知楼主能不能发个串口接受12864显示的程序

之后在STM32做过,现在看来不难,也就是实现两个外设驱动,一个串口能正常收发,一个12864能正常显示。这两个模块单独弄都没问题了,剩下的也就是逻辑上面的整合去满足需求了。隐约记得我当时做的STM32一个任务是类似一个MP4电子书那种,能前后翻页。
31# ID:991519 只看他
2021-12-13 09:53
我也遇到这样问题
32# ID:991519 只看他
2021-12-13 09:54
解决了
33# ID:1124069 只看他
2024-6-6 15:16
初学,感谢!

51黑电子论坛

Powered by Discuz! X3.1

首页|标准版|触屏版|电脑版