历史上的今天
返回首页

历史上的今天

今天是:2026年03月24日(星期二)

正在发生

2023年03月24日 | 51单片机 | 实现SMC1602液晶屏显示实例

2023-03-24 来源:zhihu

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

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

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

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


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

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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


                                      状态输入输出
                                      读状态RS=0R/W=1E=1D0~D7=状态字
                                      读数据RS=1R/W=1E=1D0~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 }


                                      推荐阅读

                                      史海拾趣

                                      Consolidated Wire公司的发展小趣事

                                      随着业务的不断发展,Consolidated Wire公司开始积极拓展国内外市场。公司加大了市场推广力度,通过参加行业展会、举办技术研讨会等方式提升品牌知名度。同时,公司还积极开拓海外市场,与国际知名企业建立合作关系,实现了业务的全球化布局。这些举措不仅提升了公司的市场份额,也增强了公司在电子行业的影响力。

                                      Advanced Optoelectronic Technology Corp公司的发展小趣事

                                      在光电技术领域,AOTC始终保持领先地位。公司不断推出创新产品,如高效能的光电传感器、智能照明系统等,这些产品不仅提升了人们的生活品质,还推动了整个电子行业的变革。AOTC的技术创新得到了业界的广泛认可,公司逐渐成为了行业的领军企业。

                                      Hsuan Mao Technology Co公司的发展小趣事

                                      在追求经济效益的同时,AOTC也积极履行社会责任。公司注重环保和可持续发展,采用环保材料和节能技术生产产品,降低对环境的影响。此外,公司还积极参与公益事业,支持教育、科研等领域的发展,为社会做出了积极贡献。

                                      这些故事虽然是虚构的,但它们反映了一个电子行业中公司可能经历的一些典型发展阶段和挑战。在真实情况中,公司的发展路径会受到市场环境、技术变革、竞争态势等多种因素的影响。

                                      Ethertronics公司的发展小趣事

                                      在光电技术领域,AOTC始终保持领先地位。公司不断推出创新产品,如高效能的光电传感器、智能照明系统等,这些产品不仅提升了人们的生活品质,还推动了整个电子行业的变革。AOTC的技术创新得到了业界的广泛认可,公司逐渐成为了行业的领军企业。

                                      DREMEL公司的发展小趣事

                                      为了进一步扩大市场份额,Dremio公司积极寻求与电子行业的跨界合作。他们与一家知名电子设备制造商达成战略合作,共同开发了一款集成了Dremio数据处理技术的智能设备。这款设备能够实时收集和分析设备使用数据,为企业提供更精准的市场分析和产品优化建议。通过这一合作,Dremio成功将技术应用于电子设备的全生命周期管理,进一步巩固了其在市场中的地位。

                                      Alcatel-Lucent公司的发展小趣事

                                      随着全球化的趋势日益明显,Dremio公司开始积极拓展国际市场。他们制定了详细的国际化战略,包括在海外市场设立分支机构、与当地企业建立合作关系、参加国际展会等。这些举措不仅提高了Dremio公司在国际市场的知名度,也为其带来了更多的商业机会。通过国际化战略的实施,Dremio公司的业务规模不断扩大,品牌影响力也日益增强。

                                      请注意,以上故事均基于虚构,旨在展示一个类似Dremio公司在电子行业中的可能发展路径和故事。如有需要,请进一步核实相关事实和数据。

                                      问答坊 | AI 解惑

                                      单片机的内部、外部结构(一)

                                      单片机的内部、外部结构(一) 一、单片机的外部结构 拿到一块芯片,想要使用它,首先必须要知道怎样连线,我们用的一块称之为89C51的芯片,下面我们就看一下如何给它连线。 1、 电源:这当然是必不可少的了。单片机使用的是5V电源,其中正极接40引 ...…

                                      查看全部问答>

                                      什么是LED洗墙灯

                                      replyreload += \',\' + 373247;Timson,如果您要查看本帖隐藏内容请回复…

                                      查看全部问答>

                                      请教AddDevice函数是做什么用的呀?为什么文件系统过滤驱动AddDevice函数?

                                      向高手请教 请教AddDevice函数是做什么用的呀?为什么文件系统过滤驱动AddDevice函数?…

                                      查看全部问答>

                                      问个奇怪的问题,关于SetLocalTime

                                      我用的是三星arm2440,ce5.0,我发现一个奇怪的问题,机器重启后,第一次调用SetLocalTime设置时间不对,设置的时间是一个默认值2008-1,但是以后再调用SetLocalTime就不会出现这个问题了,请问这是什么原因,是ce的一个bug,SetLocalTime对应的应 ...…

                                      查看全部问答>

                                      菜鸟弱问:关于uart和mclk

                                      在option.h中 mclk=320000000这个值是根据什么确定的呢? 如果对它进行修改,会发生什么影响? 另外,在uart传输数据的时候,收发双方如何保证自己这边的频率与对方差不多? 当我们在ulcon中设定了某种祯格式,对方如何知道?如何检错? 我 ...…

                                      查看全部问答>

                                      关于多个GPRS MODEM同时拨号的问题?

                                      我电脑两个串口上连接两个GPRS MODEM同时拨号上网,默认情况下是使用一个连接.我想在程序中控制两个连接怎么同时使用呀,即有的数据通过一个连接发送出去,另外一些数据通过另外一个连接发送出去呀,应该怎么办呀,请各位帮忙.非常感谢呀!…

                                      查看全部问答>

                                      求教关于lis3lv02dq加速度计的问题!

                                                                       我打算用这个芯片测量倾角。现在能从芯片里读出数来了,但读出来的数据没看明白,我是采用12位精度的。当x轴竖直向 ...…

                                      查看全部问答>

                                      IBM宣布开发授权,促进嵌入式的发展

                                             由于缺乏高端SoC芯片技术,国内IC设计企业在嵌入式CPU开发上一直处于落后状态。可喜的是,随着全球半导体产业的技术转移及自身的努力,近年来国内已涌现出一些嵌入式CPU开发优势企业。下面就由福州卓跃教育具 ...…

                                      查看全部问答>

                                      关于CY7C68013中官方例程CYStream的一点解释

                                      我在使用CYSteam例程来测速速度的时候一直出现了一个问题,下载固件程序后,在设备管理器中能够看到该驱动已经正常安装了,但是在console或者是官方提供的CYSteam中无法识别。一直以为是驱动的程序的问题。但是我利用购买的开发板就没有这个问题。 ...…

                                      查看全部问答>