找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2528|回复: 2
打印 上一主题 下一主题
收起左侧

关于单片机串口通讯内容在1602液晶上显示的问题

[复制链接]
跳转到指定楼层
楼主
ID:367937 发表于 2018-11-22 21:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
自己写了一段将单片机串口控制led灯亮灭,然后在LCD显示灯状态的程序。现有一下问题,向各位坛友请教:1.1602查忙程序,在下面程序130行中,只要我加入了带忙检测的清屏语句,LCD就不显示,但我串口调试助手还是能接收到返回值(例如ok_1)。而且在我显示字符串函数中(72行)加入忙检测,LCD也不能正常显示字符。(本人对查忙函数存在意义还是不怎么明白,只知道需要查忙来确定LCD是否在写入数据,防止数据丢失)
2.在我字符串定义中(13-15行),如果我在后面加上感叹号(如“uchar code error[]="error!";"),则我在串口助手中发送02之后,1602正常显示,串口助手正常收到返回值ok_2,但无法之后再次发送数据,就像串口中断没有再次打开一样,无论我在串口助手中发送什么,LCD以及串口助手都得不到返回值。但是,如果我缩短数组长度(如“uchar code error[]="er!";"),则程序正常运行(据我测试,两个字母加一个感叹号是上限了,像off!就已经出现跟error!一样的问题)。
希望有大神能给我解答,感激不尽。

单片机代码:
  1. #include <reg52.h>
  2. #include <stdio.h>

  3. #define uint  unsigned int
  4. #define uchar unsigned char
  5. #define PORT P2

  6. sbit RS=P3^5;                                                                   //寄存器选择位  
  7. sbit RW=P3^6;                                                                          //读写选择位
  8. sbit EN=P3^7;                                                                          //使能位
  9. sbit LED=P3^4;

  10. uchar code led_on[]="on";
  11. uchar code led_off[]="off";
  12. uchar code error[]="error";

  13. uchar a,flag_uart,flag_led;

  14. void delay_us(uchar n)                                                  //微秒级别的延时  
  15. {  
  16.         while(n--);  
  17. }  
  18.   
  19. void delay_ms(uint x)                                                          //延时1ms  
  20. {  
  21.         uint i,j;  
  22.         for(i=x;i>0;i--)  
  23.                 for(j=114;j>0;j--);  
  24. }  

  25. void lcd_write_command(uchar command)                        //写命令函数
  26. {
  27.         RS=0;
  28.         RW=0;
  29.         PORT=command;
  30.         EN=1;
  31.         delay_us(5);
  32.         EN=0;
  33. }

  34. void lcd_write_data(uchar dat)                                        //写数据函数
  35. {
  36.         RS=1;
  37.         RW=0;
  38.         PORT=dat;
  39.         EN=1;
  40.         delay_us(5);
  41.         EN=0;
  42. }

  43. void lcd_check_busy()                                                        //查忙函数
  44. {
  45.         RS=0;
  46.         RW=1;
  47.         PORT=0xFF;                                                                        //51IO口拉高,准备读状态
  48.         EN=1;
  49.         while(PORT & 0x01);
  50.         EN=0;
  51. }

  52. void lcd_write_command_busy(uchar command)                //带查忙的写命令函数
  53. {
  54.         lcd_check_busy();
  55.         RS=0;
  56.         RW=0;
  57.         PORT=command;
  58.         EN=1;
  59.         delay_us(5);
  60.         EN=0;
  61. }

  62. void lcd_write_str(uchar x,uchar y,uchar *p)        //显示字符串函数
  63. {
  64.         if(x==0)
  65.                 lcd_write_command_busy(0x80+y);                        //x=0 第一行显示
  66.         else
  67.                 lcd_write_command_busy(0xC0+y);                        //x=1 第二行显示
  68.         while(*p)
  69.         {
  70.                
  71.                 lcd_write_data(*p);                                                //显示字符串
  72.                 p++;
  73.         }
  74. }

  75. void lcd_init()
  76. {
  77.         delay_ms(15);
  78.         lcd_write_command(0x38);
  79.         delay_ms(5);
  80.         lcd_write_command(0x38);
  81.         delay_ms(5);
  82.         lcd_write_command(0x38);
  83.         lcd_write_command_busy(0x38);
  84.         lcd_write_command_busy(0x0C);                                //开显示,关光标,光标不显示
  85.         lcd_write_command_busy(0x01);                                //清屏
  86.         lcd_write_command_busy(0x06);                                //地址指针+1,光标右移
  87. }

  88. void uart_init()
  89. {
  90.         TMOD = 0x20;
  91.         TH1  = 0xfd;
  92.         TL1  = 0xfd;
  93.         TR1  = 1;
  94.         SCON = 0x50;
  95.         EA   = 1;
  96.         ES   = 1;
  97.         
  98. }

  99. void main()
  100. {
  101.         uchar *p;
  102.         p="Light:";
  103.         lcd_init();
  104.         uart_init();
  105.         while(1)
  106.         {
  107.                 lcd_write_str(0,0,p);
  108.                 if(flag_uart==1)
  109.                 {
  110.                         flag_uart=0;
  111.                         ES=0;
  112.                         TI=1;
  113.                         switch(flag_led)
  114.                         {
  115.                                 case 0:
  116.                                         LED=0;
  117.                                         //lcd_write_command_busy(0x01);        //清屏
  118.                                         lcd_write_str(0,0,p);
  119.                                         lcd_write_str(1,5,led_off);
  120.                                         printf("ok_0\n");
  121.                                         break;
  122.                                 case 1:
  123.                                         LED=1;
  124.                                         //lcd_write_command_busy(0x01);        //清屏
  125.                                         lcd_write_str(0,0,p);
  126.                                         lcd_write_str(1,5,led_on);
  127.                                         printf("ok_1\n");
  128.                                         break;
  129.                                 case 2:
  130.                                         lcd_write_str(1,5,error);
  131.                                         printf("ok_2\n");
  132.                                         break;
  133.                         }
  134.                         while(!TI);
  135.                         TI=0;
  136.                         ES=1;
  137.                 }
  138.         }
  139. }

  140. void ser() interrupt 4
  141. {
  142.         RI=0;
  143.         a=SBUF;
  144.         flag_uart=1;
  145.         if (a==0)
  146.                 flag_led=0;
  147.         else if(a==1)
  148.                         flag_led=1;
  149.                 else
  150.                         flag_led=2;
  151. }
复制代码

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:396960 发表于 2018-11-23 09:44 | 只看该作者
main里的第一个 TI =1;干嘛用的??你置一的话,是会进入中断服务函数的? 你的中断服务函数里只对RI操作。。。

那想象下,中断-------flag_uart = 1;------main------检测flag_uart =1 后 flag_uart = 0; 然后 TI =1-------中断----------flag_uart =1 .............死循环吧???

好好调下。
回复

使用道具 举报

板凳
ID:367937 发表于 2018-11-23 16:11 | 只看该作者
phang 发表于 2018-11-23 09:44
main里的第一个 TI =1;干嘛用的??你置一的话,是会进入中断服务函数的? 你的中断服务函数里只对RI操作。 ...

谢谢回答,我已经调试好了,是清屏指令之后需要一定的延迟来给1602的反应时间。TI=1并没有多大意义,进中断时由RI控制的吧,
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表