找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10850|回复: 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忙的条件有误,改为非忙后,反而无法显示汉字。
回复

使用道具 举报

地板
ID:319868 发表于 2021-5-23 11:42 | 只看该作者
上面各位遇到的问题我解决了,没有用忙判断。楼主有两个错误,一是写命令和写数据时序有问题,二是中文写入地址有问题,所以楼主的“日”字显示不出来,“年”地址是0x40,“月”地址是0x48,“日”地址应该是0x50,而不是0x56,因为是十六进制。代码如下:
/*************************************************************************
3ìDò1|Äü£oÔúLCDéÏÏÔê¾2013Äê08ÔÂ21èÕ
          I Love Mcu
          Author
          x x x
******************í·ÎļtéùÃ÷**********************************************/
#include <reg51.h>
#include <intrins.h>
/*********************************¶Ë¿ú¶¨òå**********************************/
sbit rs=  P3^5;
sbit rw = P3^6;
sbit en = P3^4;
sbit busy=P1^7;
/********************************ÏÔê¾êy¾Y±í*********************************/
unsigned char day[]={0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00}; //èÕμÄ×Ö·û±í
unsigned char month[]={0x1f,0x11,0x1d,0x11,0x1d,0x11,0x11,0x00}; //ÔÂμÄ×Ö·û±í
unsigned char year[] ={0x40,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02}; //ÄêμÄ×Ö·û±í
unsigned char one[]={0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00};//ò»
unsigned char two[]={0x00,0x00,0x0E,0x00,0x1F,0x00,0x00,0x00};//¶t
unsigned char three[]={0x00,0x1F,0x00,0x0E,0x00,0x1F,0x00,0x00};//èy
unsigned char time[] ={"20130821"};
unsigned char code1[]={"I Love Mcu"};
unsigned char author[]={"Author"};
unsigned char name[]={"X X X"};
/*****************************************************************************
oˉêy1|Äü:LCDÑóê±×ó3ìDò
*****************************************************************************/
void Delay(unsigned char x)
{
   int i,j;
   for(i=x;i>0;i--)
     for(j=110;j>0;j--);
}
/*****************************************************************************
oˉêy1|Äü£o2aêÔLCD×′ì¬êÇ·ñÃ|Âμ
¼ì2aÔ-òò£oμ¥Ƭ»ú′|àíËù¶è½Ï¿ì£¬¶øLCDμÄ′|àíËù¶è½ÏÂy
*****************************************************************************/
//bit lcd_check_busy()
//{
//        P1=0Xff;
//        rs = 0;//Ö»òaéèÖÃáËrs=0,rw=1,¾íêÇòa¶áBFλ
//        rw = 1;
//        en = 0;
//        _nop_(); //ÕaèyDDμÄ×÷óÃêǽøDDò»¸ö¿Õ2ù×÷£¬¶áBFêyÖ죬è»oóê1Äüêä3öBFÖμ
//        en=1;
//        return busy; //èç1ûLCDÃ|£¬¾í·μ»ØÃ|(BF=1)
//}
/*****************************************************************************
oˉêy1|Äü:D′Ö¸áîμ½LCD×ó3ìDò
*****************************************************************************/
void lcd_wcmd(unsigned char cmd)
{
//  while(lcd_check_busy()); //ÅD¶ÏLCDêÇ·ñÃ|Â죬Ã|2ÅD′¡£ÎòÔø¾-¸Ä3飡lcd_check_busy()£¬ÎT·¨Õy3£ÏÔê¾
        rs = 0;   //D′Ö¸áî(Ö»òars = 0,rw = 0¾íêÇD′Ö¸áî)
        rw = 0;
        en = 1;
        P1 = cmd;
        _nop_();
        Delay(5);
        en = 0;
}
/*****************************************************************************
oˉêy1|Äü:D′êy¾Yμ½LCD×ó3ìDò
*****************************************************************************/
void lcd_wdat(unsigned char dat)
{
//        while(lcd_check_busy()); //ÅD¶ÏLCDêÇ·ñÃ|Â죬Ã|2ÅD′
        rs = 1;  //D′êy¾Y(Ö»òars = 1,rw = 0¾íêÇD′Ö¸áî)
        rw = 0;
        en = 1;
        P1 = dat;//Ïèê1Äü£¬2ÅÄü¶ádatêy¾Y
        _nop_();
        Delay(5);
        en = 0;
}
/*****************************************************************************
oˉêy1|Äü:é趨ÏÔê¾Î»ÖÃ×ó3ìDò
*****************************************************************************/
void lcd_pos(unsigned char pos)
{
        lcd_wcmd(pos | 0x80);//DDRAMμØÖ·éèÖã¬0x80=1000 0000£¬N = 1,·Öá½DDÏÔê¾£¬
        Delay(50);
}                        //ê×DDA6-A0=00H-2FH|posÖ죬′ÎDDA6-A0 = 40H-67H|posÖμ
/*****************************************************************************
oˉêy1|Äü:LCD3õê¼»ˉ×ó3ìDò£¨óD¸öòéÎ꣬3õê¼»ˉ3ìDò£¬Îaê2Ã′ÏÔ꾿a1Ø2»Ö±½óéèÎa0x0c£¿
                          êÇ2»êÇòòÎaòaÏèè«2¿1رÕ£¬2ÅÄüÇåÆ᣿£©
*****************************************************************************/
void lcd_init()  // òÔÏÂÖ¸áîÃûlcd_wcmdÖ»êÇóD¸öÃû×Ö¶øòÑ£¬0x38μè2ÅêÇ1ؼü
{
        lcd_wcmd(0x38);    //1|ÄüéèÖão8λêy¾Y£¬Ë«DDÏÔê¾£¬5*7μãÕó
        lcd_wcmd(0x08);    //ÏÔ꾿a1ØéèÖãoÏÔê¾1رÕ£¬ÎT1a±ê£¬2»éá˸--Ïè1رÕ
        lcd_wcmd(0x01);    //ÇåÆá
        lcd_wcmd(0x06);    //êäèë·½ê½éèÖão1a±ê×Ô¶ˉÔöò»
        Delay(100);
        lcd_wcmd(0x0c);    //ÏÔ꾿a1ØéèÖãoÏÔ꾿aÆô£¬ÎT1a±ê£¬2»éá˸--Ôù¿aÆô
}
/****************************************************************************
oˉêy1|Äü£o½¨á¢ÄêÔÂèÕ×Ö·û
*****************************************************************************/
void lcd_setup()    //Ï轨á¢ÄêÔÂèÕ×Ö·û
{
        unsigned int i;
        lcd_wcmd(0x40);   //1|ÄüéèÖÃP0=0x40=0010 0000£¬4룬ò»DDÏÔê¾£¬5*7μãÕóÏÔê¾
        for(i=0;i<8;i++)
        {
    lcd_wdat(year[i]);
                Delay(50);
        }
       
        lcd_wcmd(0x48);
        for(i=0;i<8;i++)
        {
                lcd_wdat(month[i]);
                Delay(50);
        }
       
        lcd_wcmd(0x50);
        for(i=0;i<8;i++)
        {
                lcd_wdat(day[i]);
                Delay(50);
        }
       
        lcd_wcmd(0x58);
        for(i=0;i<8;i++)
        {
                lcd_wdat(one[i]);
                Delay(50);
        }
       
        lcd_wcmd(0x60);
        for(i=0;i<8;i++)
        {
                lcd_wdat(two[i]);
                Delay(50);
        }
       
        lcd_wcmd(0x68);
        for(i=0;i<8;i++)
        {
                lcd_wdat(day[i]);
                Delay(50);
        }
}
/*****************************************************************************
oˉêy1|Äü:Ö÷3ìDò
*****************************************************************************/
void main(void)
{
        unsigned char i;
        lcd_init();               //3õê¼»ˉLCD
  lcd_setup();              //½¨á¢×Ö·û
        while(1)
        {
          lcd_pos(0x00);
                for(i=0;i<4;i++)
                {
                        lcd_wdat(time[i]);     //ÏÔê¾2013
                }

                lcd_pos(0x04);             //éèÖÃÆeê¼μØÖ·êÇ0x05£¬0x05|0x80=0x85
                lcd_wdat(0x00);            //D′Ö¸áP0=0x00
               
                lcd_pos(0x06);  //éèÖÃÆeê¼μØÖ·êÇ0x07£¬0x05|0x80=0x87
                for(i=4;i<6;i++)
                {
                        lcd_wdat(time[i]);     //ÏÔê¾08
                }
         
                lcd_pos(0x09);             //éèÖÃÆeê¼μØÖ·êÇ0x0a£¬0x0a|0x80=0x8a
                lcd_wdat(0x01);            //D′êy¾Y£¬P0=0x01
               
                lcd_pos(0x0b);            //éèÖÃÆeê¼μØÖ·êÇ0x0c£¬0x0c|0x80=0x8c
                for(i=6;i<8;i++)
                {
                        lcd_wdat(time[i]);    //ÏÔê¾21
                }
               
                lcd_pos(0x0e);            //éèÖÃÆeê¼μØÖ·êÇ0x0f£¬0x0f|0x80=0x8f
                lcd_wdat(0x02);           //D′êy¾Y£¬P0=0x02
               
                lcd_pos(0x43);            //éèÖÃÆeê¼μØÖ·êÇ0x43£¬0x43|0x80=0xc3  
                for(i=0;i<10;i++)
                {
                        lcd_wdat(code1[i]); //ÏÔê¾I Love Mcu
                }
//               
//                for(i=0;i<17;i++)
//                {
//                        lcd_wcmd(0x18); //0001 1000ÏÔê¾×Ö·ûƽòÆò»¸ö×Ö·ûλ(0001)£¬
//                        Delay(50);    //ÏÔê¾×Ö·ûÕûìå×óòÆ1λ(1000)
//                }                  
//                lcd_wcmd(0x01);     //ÇåÆá
//                Delay(50);
//                 
//                lcd_pos(0x05);
//                Delay(50);
//                for(i=0;i<6;i++)
//                {
//                        lcd_wdat(author[i]);
//                        Delay(50);
//                }

//                lcd_pos(0x41);
//                Delay(50);
//                for(i=0;i<13;i++)
//                {
//                        lcd_wdat(name[i]);
//                        Delay(50);
//                }

//                Delay(10);
//                lcd_wcmd(0x01);
        }
}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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