找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机LCD1602汉字显示中文及详细注释 显示年月日汉字

[复制链接]
跳转到指定楼层
楼主
1602是液晶显示内容,汉字显示对于初学者来说,有较大难度,我在学习过程中对前人的程序做了详细注释。希望可以帮助到列位黑友。




需要等1分钟左右才显示
单片机源程序如下:
  1. /*************************************************************************
  2. 程序功能:在LCD上显示2013年08月21日
  3.           I Love Mcu
  4.           Author
  5.           x x x
  6. ******************头文件声明**********************************************/
  7. #include <reg51.h>
  8. #include <intrins.h>
  9. /*********************************端口定义**********************************/
  10. sbit rs=  P3^0;
  11. sbit rw = P3^1;
  12. sbit en = P3^2;
  13. sbit busy=P0^7;
  14. /********************************显示数据表*********************************/
  15. unsigned char day[] = {0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00}; //日的字符表
  16. unsigned char month[]={0x1f,0x11,0x1d,0x11,0x1d,0x11,0x11,0x00}; //月的字符表                                     //月的字符表
  17. unsigned char year[] ={0x40,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02}; //年的字符表
  18. unsigned char time[] ={"20130821"};
  19. unsigned char code1[]={"I Love Mcu"};
  20. unsigned char author[]={"Author"};
  21. unsigned char name[]={"X X X"};
  22. /*****************************************************************************
  23. 函数功能:LCD延时子程序
  24. *****************************************************************************/
  25. void Delay(unsigned char x)
  26. {
  27.    int i,j;
  28.    for(i=x;i>0;i--)
  29.      for(j=110;j>0;j--);
  30. }
  31. /*****************************************************************************
  32. 函数功能:测试LCD状态是否忙碌
  33. 检测原因:单片机处理速度较快,而LCD的处理速度较慢
  34. *****************************************************************************/
  35. bit lcd_check_busy()
  36. {
  37.         P0=0Xff;
  38.         rs = 0;//只要设置了rs=0,rw=1,就是要读BF位
  39.         rw = 1;
  40.         en = 0;
  41.         _nop_(); //这三行的作用是进行一个空操作,读BF数值,然后使能输出BF值
  42.         en=1;
  43.         return busy; //如果LCD忙,就返回忙(BF=1)
  44. }
  45. /*****************************************************************************
  46. 函数功能:写指令到LCD子程序
  47. *****************************************************************************/
  48. void lcd_wcmd(unsigned char cmd)
  49. {
  50.     while(lcd_check_busy()); //判断LCD是否忙碌,忙才写。我曾经改成!lcd_check_busy(),无法正常显示
  51.         rs = 0;   //写指令(只要rs = 0,rw = 0就是写指令)
  52.         rw = 0;
  53.         en = 1;
  54.         P0 = cmd;
  55.         _nop_();
  56.         en = 0;
  57. }
  58. /*****************************************************************************
  59. 函数功能:写数据到LCD子程序
  60. *****************************************************************************/
  61. void lcd_wdat(unsigned char dat)
  62. {
  63.         while(lcd_check_busy()); //判断LCD是否忙碌,忙才写
  64.         rs = 1;  //写数据(只要rs = 1,rw = 0就是写指令)
  65.         rw = 0;
  66.         en = 1;
  67.         P0 = dat;//先使能,才能读dat数据
  68.         _nop_();
  69.         en = 0;
  70. }
  71. /*****************************************************************************
  72. 函数功能:设定显示位置子程序
  73. *****************************************************************************/
  74. void lcd_pos(unsigned char pos)
  75. {
  76.         lcd_wcmd(pos | 0x80);//DDRAM地址设置,0x80=1000 0000,N = 1,分两行显示,
  77. }                        //首行A6-A0=00H-2FH|pos值,次行A6-A0 = 40H-67H|pos值
  78. /*****************************************************************************
  79. 函数功能:LCD初始化子程序(有个疑问,初始化程序,为什么显示开关不直接设为0x0c?
  80.                           是不是因为要先全部关闭,才能清屏?)
  81. *****************************************************************************/
  82. void lcd_init()  // 以下指令名lcd_wcmd只是有个名字而已,0x38等才是关键
  83. {
  84.         lcd_wcmd(0x38);    //功能设置:8位数据,双行显示,5*7点阵
  85.         lcd_wcmd(0x08);    //显示开关设置:显示关闭,无光标,不闪烁--先关闭
  86.         lcd_wcmd(0x01);    //清屏
  87.         lcd_wcmd(0x06);    //输入方式设置:光标自动增一
  88.         Delay(100);
  89.         lcd_wcmd(0x0c);    //显示开关设置:显示开启,无光标,不闪烁--再开启
  90. }
  91. /****************************************************************************
  92. 函数功能:建立年月日字符
  93. *****************************************************************************/
  94. void lcd_setup()    //先建立年月日字符
  95. {
  96.         unsigned int i;
  97.         lcd_wcmd(0x40);   //功能设置P0=0x40=0010 0000,4位,一行显示,5*7点阵显示
  98.         for(i=0;i<8;i++)
  99.         {
  100.         lcd_wdat(year[i]);
  101.         }
  102.     Delay(1000);
  103.         lcd_wcmd(0x48);
  104.         for(i=0;i<8;i++)
  105.         {
  106.                 lcd_wdat(month[i]);
  107.         }
  108.         Delay(1000);
  109.         lcd_wcmd(0x56);
  110.         for(i=0;i<8;i++)
  111.         {
  112.                 lcd_wdat(day[i]);
  113.         }
  114.         Delay(1000);
  115. }
  116. /*****************************************************************************
  117. 函数功能:主程序
  118. *****************************************************************************/
  119. void main(void)
  120. {
  121.         unsigned char i;
  122.         lcd_init();               //初始化LCD
  123.     lcd_setup();              //建立字符
  124.         while(1)
  125.         {
  126.             lcd_pos(0x00);            
  127.                 for(i=0;i<4;i++)
  128.                 {
  129.                         lcd_wdat(time[i]);     //显示2013
  130.                 }

  131.                 lcd_pos(0x05);             //设置起始地址是0x05,0x05|0x80=0x85
  132.                 lcd_wdat(0x00);            //写指令,P0=0x00
  133.          
  134.                 lcd_pos(0x07);  //设置起始地址是0x07,0x05|0x80=0x87
  135.                 for(i=4;i<6;i++)
  136.                 {
  137.                         lcd_wdat(time[i]);     //显示08
  138.             Delay(1000);
  139.                 }
  140.          
  141.                 lcd_pos(0x0a);             //设置起始地址是0x0a,0x0a|0x80=0x8a
  142.                 lcd_wdat(0x01);            //写数据,P0=0x01
  143.         
  144.                 lcd_pos(0x0c);            //设置起始地址是0x0c,0x0c|0x80=0x8c
  145.                 for(i=6;i<8;i++)
  146.                 {
  147.                         lcd_wdat(time[i]);    //显示21
  148.             Delay(1000);
  149.                 }
  150.                 lcd_pos(0x0f);            //设置起始地址是0x0f,0x0f|0x80=0x8f
  151.                 lcd_wdat(0x02);           //写数据,P0=0x02
  152.            
  153.                 lcd_pos(0x43);            //设置起始地址是0x43,0x43|0x80=0xc3           
  154.                 for(i=0;i<10;i++)
  155.                 {
  156.                         lcd_wdat(code1[i]); //显示I Love Mcu
  157.                Delay(1000);
  158.                 }
  159.                 for(i=0;i<17;i++)
  160.                 {
  161.                         lcd_wcmd(0x18); //0001 1000显示字符平移一个字符位(0001),
  162.                         Delay(1000);    //显示字符整体左移1位(1000)
  163.                 }                  
  164.                 lcd_wcmd(0x01);     //清屏      
  165.                  

  166.                 lcd_pos(0x05);
  167.                 for(i=0;i<6;i++)
  168.                 {
  169.                         Delay(10);
  170.                         lcd_wdat(author[i]);
  171.                 }

  172.                 lcd_pos(0x41);
  173.                 for(i=0;i<13;i++)
  174.                 {
  175.                         Delay(10);
  176.                         lcd_wdat(name[i]);
  177.                 }

  178.                 Delay(10);
  179.                 lcd_wcmd(0x01);
  180.         }
  181. }
复制代码

所有资料51hei提供下载(有问题的问题):
1602LCD显示详细注释.zip (864.6 KB, 下载次数: 116)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:753618 发表于 2020-6-10 19:31 | 显示全部楼层
可以显示,但是要过一段时间,具体原因我不清楚。
回复

使用道具 举报

板凳
ID:753618 发表于 2020-6-11 20:02 | 显示全部楼层
是的,需要等一分钟左右,具体原因不清楚。开始怀疑是写指令和数据时判断LCD忙的条件有误,改为非忙后,反而无法显示汉字。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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