51单片机 | 实现SMC1602液晶屏显示实例

2023-03-24  

LCD1602
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  • 1602的意思是每行显示16个字符,一共可以显示两行。如果是12232液晶(图形型液晶)则表示由122列32行组成,即共有122*32个点

  • p.s.注意使用温度,通常液晶的工作范围为0~+55℃,存储温度范围为-22~+60℃。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
引脚情况:


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
基本操作时序:

状态 输入 输出
读状态 RS=0R/W=1E=1 D0~D7=状态字
读数据 RS=1R/W=1E=1 D0~D7=数据
写指令 RS=0R/W=0E=1D0~D7=指令码E=1
写数据 RS=1R/W=0E=1D0~D7=数据E=1
    状态 输入 输出
    读状态 RS=0R/W=1E=1 D0~D7=状态字
    读数据 RS=1R/W=1E=1 D0~D7=数据
    写指令 RS=0R/W=0E=1D0~D7=指令码E=1
    写数据 RS=1R/W=0E=1D0~D7=数据E=1


      状态 输入 输出
      读状态 RS=0R/W=1E=1 D0~D7=状态字
      读数据 RS=1R/W=1E=1 D0~D7=数据
      写指令 RS=0R/W=0E=1D0~D7=指令码E=1
      写数据 RS=1R/W=0E=1D0~D7=数据E=1


        状态 输入 输出
        读状态 RS=0R/W=1E=1 D0~D7=状态字
        读数据 RS=1R/W=1E=1 D0~D7=数据
        写指令 RS=0R/W=0E=1D0~D7=指令码E=1
        写数据 RS=1R/W=0E=1D0~D7=数据E=1


          状态 输入 输出
          读状态 RS=0R/W=1E=1 D0~D7=状态字
          读数据 RS=1R/W=1E=1 D0~D7=数据
          写指令 RS=0R/W=0E=1D0~D7=指令码E=1
          写数据 RS=1R/W=0E=1D0~D7=数据E=1


          状态 输入 输出
          读状态 RS=0R/W=1E=1 D0~D7=状态字
          读数据 RS=1R/W=1E=1 D0~D7=数据
          写指令 RS=0R/W=0E=1D0~D7=指令码E=1
          写数据 RS=1R/W=0E=1D0~D7=数据E=1
            状态 输入 输出
            读状态 RS=0R/W=1E=1 D0~D7=状态字
            读数据 RS=1R/W=1E=1 D0~D7=数据
            写指令 RS=0R/W=0E=1D0~D7=指令码E=1
            写数据 RS=1R/W=0E=1D0~D7=数据E=1


              状态 输入 输出
              读状态 RS=0R/W=1E=1 D0~D7=状态字
              读数据 RS=1R/W=1E=1 D0~D7=数据
              写指令 RS=0R/W=0E=1D0~D7=指令码E=1
              写数据 RS=1R/W=0E=1D0~D7=数据E=1


                状态 输入 输出
                读状态 RS=0R/W=1E=1 D0~D7=状态字
                读数据 RS=1R/W=1E=1 D0~D7=数据
                写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                写数据 RS=1R/W=0E=1D0~D7=数据E=1


                  状态 输入 输出
                  读状态 RS=0R/W=1E=1 D0~D7=状态字
                  读数据 RS=1R/W=1E=1 D0~D7=数据
                  写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                  写数据 RS=1R/W=0E=1D0~D7=数据E=1


                  状态 输入 输出
                  读状态 RS=0R/W=1E=1 D0~D7=状态字
                  读数据 RS=1R/W=1E=1 D0~D7=数据
                  写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                  写数据 RS=1R/W=0E=1D0~D7=数据E=1
                    状态 输入 输出
                    读状态 RS=0R/W=1E=1 D0~D7=状态字
                    读数据 RS=1R/W=1E=1 D0~D7=数据
                    写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                    写数据 RS=1R/W=0E=1D0~D7=数据E=1


                      状态 输入 输出
                      读状态 RS=0R/W=1E=1 D0~D7=状态字
                      读数据 RS=1R/W=1E=1 D0~D7=数据
                      写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                      写数据 RS=1R/W=0E=1D0~D7=数据E=1


                        状态 输入 输出
                        读状态 RS=0R/W=1E=1 D0~D7=状态字
                        读数据 RS=1R/W=1E=1 D0~D7=数据
                        写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                        写数据 RS=1R/W=0E=1D0~D7=数据E=1


                          状态 输入 输出
                          读状态 RS=0R/W=1E=1 D0~D7=状态字
                          读数据 RS=1R/W=1E=1 D0~D7=数据
                          写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                          写数据 RS=1R/W=0E=1D0~D7=数据E=1


                            状态 输入 输出
                            读状态 RS=0R/W=1E=1 D0~D7=状态字
                            读数据 RS=1R/W=1E=1 D0~D7=数据
                            写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                            写数据 RS=1R/W=0E=1D0~D7=数据E=1


                            状态 输入 输出
                            读状态 RS=0R/W=1E=1 D0~D7=状态字
                            读数据 RS=1R/W=1E=1 D0~D7=数据
                            写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                            写数据 RS=1R/W=0E=1D0~D7=数据E=1
                              状态 输入 输出
                              读状态 RS=0R/W=1E=1 D0~D7=状态字
                              读数据 RS=1R/W=1E=1 D0~D7=数据
                              写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                              写数据 RS=1R/W=0E=1D0~D7=数据E=1


                                状态 输入 输出
                                读状态 RS=0R/W=1E=1 D0~D7=状态字
                                读数据 RS=1R/W=1E=1 D0~D7=数据
                                写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                                写数据 RS=1R/W=0E=1D0~D7=数据E=1


                                  状态 输入 输出
                                  读状态 RS=0R/W=1E=1 D0~D7=状态字
                                  读数据 RS=1R/W=1E=1 D0~D7=数据
                                  写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                                  写数据 RS=1R/W=0E=1D0~D7=数据E=1


                                    状态 输入 输出
                                    读状态 RS=0R/W=1E=1 D0~D7=状态字
                                    读数据 RS=1R/W=1E=1 D0~D7=数据
                                    写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                                    写数据 RS=1R/W=0E=1D0~D7=数据E=1


                                      状态 输入 输出
                                      读状态 RS=0R/W=1E=1 D0~D7=状态字
                                      读数据 RS=1R/W=1E=1 D0~D7=数据
                                      写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                                      写数据 RS=1R/W=0E=1D0~D7=数据E=1


                                      状态 输入 输出
                                      读状态 RS=0R/W=1E=1 D0~D7=状态字
                                      读数据 RS=1R/W=1E=1 D0~D7=数据
                                      写指令 RS=0R/W=0E=1D0~D7=指令码E=1
                                      写数据 RS=1R/W=0E=1D0~D7=数据E=1


                                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                      RAM内部映射:80个字节


                                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                      状态字说明://状态字反应了当前液晶屏的情况,当STA7为1时说明显示器正在忙碌状态,不可进行操作

                                      • STA0~STA6表示当前地址指针的数值

                                      • STA7表示读/写使能,=1表示进制,=0表示允许


                                      p.s.原则上每次对控制器读写操作之前都必须进行读写检测,确保STA7=0,实际操作中由于单片机操作速度慢于液晶控制的反应速度,可以不进行读写检测而只进行简短的延时。

                                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                      数据指针设置:
                                      用户可以通过以下的数据地址指针访问内部的80个字节RAM,用来设置数据地址
                                      80H+地址码(0~27H,40~67H)
                                      例:对第一个地址进行操作,0x80+0x01
                                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                      其他指令码:

                                      01H 显示清屏(数据指针清零,所有显示清零)
                                      02H 显示回车(数据指针清零)


                                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                      初始化:

                                      • 显示模式设置:38H


                                      • 显示开/关及光标设置


                                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                      读写操作时序:

                                      • 读操作


                                      • 写操作


                                      • 操作时间参数


                                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                      操作方式:

                                      • 对LCD的操作可以分为数据和指令两部分。

                                      • 通过操作RS,R/W,E,执行四种操作:读状态,读数据,写指令,写数据

                                      • D0~D7用来输入输出指令码和数据

                                      ————————————————————————————————————————————
                                      LCD1602使用实例:
                                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                      设计要求:
                                      使用LCD1602显示两行字符,显示两行字,两个按键控制着显示或清屏

                                      动图封面


                                      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                      设计思路:

                                      • 初始化液晶显示屏 //参照上文"初始化"

                                        • 打开使能

                                        • 指令码操作

                                          • 设置16*2显示,5*7点阵,8位数据结构

                                          • 开显示,显示光标,不闪烁

                                          • 读写完字符后地址指针+1,光标+1,整屏显示不移动

                                          • 清屏

                                          • 设置地址显示的首字符



                                      • 初始化中断

                                        • 打开中断

                                        • 外部中断0和1


                                      • 死循环等待中断

                                      • 按键中断

                                        • 按键"显示"

                                          • 循环写入数据(字符数组)

                                          • 指令"换行"

                                          • 循环写入第二行数据


                                        • 按键"清屏"

                                          • 指令"清屏"



                                      • 子函数 //参照上文"读写操作时序表"

                                        • 写数据

                                        • 写指令

                                       1 #include

                                       2 typedef unsigned char uchar;

                                       3 sbit en = P3 ^ 4;

                                       4 sbit rs = P3 ^ 5;

                                       5 uchar code table1[] =

                                       6 {

                                       7     "SMC1602 0x01..."

                                       8 };

                                       9 uchar code table2[] =

                                      10 {

                                      11     "      Hugh Dong."

                                      12 };

                                      13 void Delay(uchar m)

                                      14 {

                                      15     uchar i, j;

                                      16     for (i = m; i > 0; --i)

                                      17         for (j = 110; j > 0; --j);

                                      18 }

                                      19 /* 写数据 */

                                      20 void write_date(uchar date)

                                      21 {

                                      22     //参考写操作时序图

                                      23     rs = 1; //RS高电平,写数据

                                      24     P2 = date; //写入数据,对应时序图t_SP2数据建立

                                      25     Delay(5);

                                      26     en = 1; //打开使能,给E一个高脉冲,开始写入数据

                                      27     Delay(5);

                                      28     en = 0; //关闭使能,写入数据完成

                                      29 }

                                      30 /* 写指令 */

                                      31 void write_com(uchar com)

                                      32 {

                                      33     //基本原理同写数据

                                      34     rs = 0; //RS低电平,写指令

                                      35     P2 = com;

                                      36     Delay(5);

                                      37     en = 1;

                                      38     Delay(5);

                                      39     en = 0;

                                      40 }

                                      41 /* 初始化LCD */

                                      42 void Init()

                                      43 {

                                      44     en = 1;

                                      45     write_com(0x38); //00111000 设置16*2显示,5*7点阵,8位数据接口

                                      46     write_com(0x0E); //00001110 开显示,显示光标,不闪烁

                                      47     write_com(0x06); //00000110 读写字符后地址指针+1,光标+1,屏幕不移动

                                      48     write_com(0x01); //清屏

                                      49     write_com(0x80 + 0x01); //设置数据地址指针从第一个开始

                                      50 }

                                      51 int main()

                                      52 {

                                      53     /* 初始化LCD */

                                      54     Init();

                                      55     Delay(100);

                                      56     /* 初始化中断 */

                                      57     EA = 1;

                                      58     EX0 = 1;

                                      59     EX1 = 1;

                                      60     /* 死循环 */

                                      61     while(1);

                                      62 }

                                      63 void Display()interrupt 0 using 1

                                      64 {

                                      65     uchar i;

                                      66     for (i = 0; i < 16; ++i) //遍历逐个写入第一行数据

                                      67     {

                                      68         write_date(table1[i]);

                                      69         Delay(20);

                                      70     }

                                      71     write_com(0x02); //换行

                                      72     write_com(0x80 + 0x40); //数据地址指针指向第二行

                                      73     for(i = 0; i < 16; ++i) //逐个遍历写入第二行数据

                                      74     {

                                      75         write_date(table2[i]);

                                      76         Delay(20);

                                      77     }

                                      78 }

                                      79 void Clear() interrupt 1 using 1

                                      80 {

                                      81     write_com(0x01);

                                      82 }


                                      文章来源于:电子工程世界    原文链接
                                      本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。