• 如何为编程爱好者设计一款好玩的智能硬件(七)——LCD1602点阵字符型液晶显示模块驱动封装(上)


    当前进展:

    一、我的构想:如何为编程爱好者设计一款好玩的智能硬件(一)——即插即用、积木化、功能重组的智能硬件模块构想

    二、别人家的孩子:如何为编程爱好者设计一款好玩的智能硬件(二)——别人是如何设计硬件积木的!

    三、MCU选型:如何为编程爱好者设计一款好玩的智能硬件(三)——该选什么样的MCU呢?

    四、温湿度传感器DHT11驱动封装(上):如何为编程爱好者设计一款好玩的智能硬件(四)——初尝试·把温湿度给收集了(上)!

    五、温湿度传感器DHT11驱动封装(中):如何为编程爱好者设计一款好玩的智能硬件(五)——初尝试·把温湿度给收集了(中)!

    六、温湿度传感器DHT11驱动封装(下):如何为编程爱好者设计一款好玩的智能硬件(六)——初尝试·把温湿度给收集了(下)!

    七、点阵字符型液晶显示模块LCD1602驱动封装(上)

      

      前几节我们封装好了一个可以采集数据的传感器驱动,接下来两节将介绍一个非常简单的LCD液晶屏,即显示模块的驱动封装。——有采集有显示,才好!考虑刚开始,所以本节介绍一种最常用的液晶屏:LCD1602

    · 模块简介

      该模块总共有16个引脚,显示字符为16X2行。1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大小写、常用符号和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母'A'的代码是41H,显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母'A'了。因为1602识别的是ASCII码,可以直接用ASCII码直接赋值。

    引脚及功能

      456为控制线,DB0~7为8位数据线,3为为调节对比度的(过小会导致文本不清晰,过大会导致背景掩盖文本)

           

     

    驱动器接口说明(HD44780)

      无论是TFTLCDOLCD等都会有一个驱动器,简单理解就是屏幕和控制CPU直接的一个桥梁,该桥梁规定发送什么格式的命令能达到某种效果~此外,一般这种驱动对于类似的显示器时相似的!这里用的是HD44780驱动芯片。

    1、基本操作时序:

    1.1 读状态:输入:RS=L,RW=H,E=H            输出:D0~D7=状态字
    1.2 写状态:输入:RS=L,RW=L,D0~D7=指令码,E=高脉冲  输出:无
    1.3 读数据:输入:RS=H,RW=H,E=H            输出:D0~D7=数据
    1.4 写数据:输入:RS=H,RW=L,D0~D7=数据,E=高脉冲   输出:无

    2、状态字说明:

       注:对控制器每次进行读写操作之前,都必须进行读写检测,确保STA7为0

    3、RAM地址映射图

      控制器内部带80X8位(80字节)的RAM缓冲区,对应下图关系为:(因为这个是16X2行的,所以只用了其中一部分)

     4、指令说明

      显示模式设置:    00111000  设置16X2显示,5X7点阵,8位数据接口

      显示开关光标设置:  00001DCB  D=1 开显示;D=0 关显示

                         C=1 显示光标;C=0 不显示光标

                         B=1 光标闪烁;B=0 光标不闪

                 000001NS  N=1 当读或者写一个字符后地址指针加一,且光标加一

                         N=0 当读或者写一个字符后地址指针减一,且光标减一

                         S=1 当写一个字符,整屏显示左移(N=1)或右移(N=0),以得到光标不移动而整个屏幕移动的效果

                         S=0 当写一个字符,整个屏幕不移动

      数据控制:      控制器内部设有一个数据地址指针,用户可通过它们来访问内部全部80字节RAM

      数据指针设置:    80H+地址码(0-27H,40H-67H) 

      其他设置:      01H      显示清屏

                 02H      显示回车

      初始化过程(复位过程):      ① 延时15ms

                        ② 写指令38H(不检测忙信号)

                        ③ 延时5ms

                        ④ 写指令38H(不检测忙信号)                  

                            ⑤ 延时5ms

                              ⑥ 写指令38H(不检测忙信号)

                            ⑦ (以后每次写指令、读/写数据操作之前均需要忙检测信号)

                            ⑧ 写指令38H:显示模式设置

                            ⑨ 写指令08H:显示关闭

                            © 写指令01H:显示清屏

                            ® 写指令06H:显示光标移动设置

                            〇 写指令0CH:显示开及光标设置

    常用链接方式

    时序图

    读操作时序图

      

    写操作时序图

     

    时序参数表

     

    · 基于51平台的DEMO

    下面是基于51平台LCD1602显示静态文本的例子,其连线按照“引脚与功能”左图的方式进行连接,效果如下:

    注:看下面代码,注意重点看我加粗的地方~不同颜色表示不同功能块的部分~

      1 /**********************BST-V51实验开发板例程************************
      2 *  平台:BST-V51 + Keil U3 + STC89C52
      3 *  名称:1602基本驱动的代码
      4 *  公司:深圳市亚博软件开发有限公司
      5 *  淘宝:bstmcu.taobao.com
      6 *  日期:2012-8-12
      7 *  晶振:11.0592MHZ
      8 *  说明:免费开源,不提供源代码分析.
      9 ******************************************************************/
     10 
     11 //实验目的:
     12 /*-----------------------------------------------
     13   名称:LCD1602
     14   内容:通过标准程序静态显示字符
     15   引脚定义如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK
     16 ------------------------------------------------*/
     17 
     18 
     19 #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
     20 #include<intrins.h>
     21 
     22 sbit RS = P1 ^ 0; //定义端口
     23 sbit RW = P1 ^ 1;
     24 sbit EN = P2 ^ 5;
     25 
     26 
     27 #define RS_CLR RS=0
     28 #define RS_SET RS=1
     29 
     30 #define RW_CLR RW=0
     31 #define RW_SET RW=1
     32 
     33 #define EN_CLR EN=0
     34 #define EN_SET EN=1
     35 
     36 #define DataPort P0
     37 
     38 /*------------------------------------------------
     39  uS延时函数,含有输入参数 unsigned char t,无返回值
     40  unsigned char 是定义无符号字符变量,其值的范围是
     41  0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
     42  长度如下 T=tx2+5 uS
     43 ------------------------------------------------*/
     44 void DelayUs2x(unsigned char t)
     45 {
     46     while(--t);
     47 }
     48 /*------------------------------------------------
     49  mS延时函数,含有输入参数 unsigned char t,无返回值
     50  unsigned char 是定义无符号字符变量,其值的范围是
     51  0~255 这里使用晶振12M,精确延时请使用汇编
     52 ------------------------------------------------*/
     53 void DelayMs(unsigned char t)
     54 {
     55 
     56     while(t--)
     57     {
     58         //大致延时1mS
     59         DelayUs2x(245);
     60         DelayUs2x(245);
     61     }
     62 }
     63 /*------------------------------------------------
     64               判忙函数
     65 ------------------------------------------------*/
     66 bit LCD_Check_Busy(void)//蓝色的几个忙检测、写数据和写命令是根据上面《驱动器接口说明》中的第一条和读写时序图写成的
     67 {
     68     DataPort = 0xFF;
     69     RS_CLR;
     70     RW_SET;
     71     EN_CLR;
     72     _nop_();
     73     EN_SET;
     74     return (bit)(DataPort & 0x80);
     75 }
     76 /*------------------------------------------------
     77               写入命令函数
     78 ------------------------------------------------*/
     79 void LCD_Write_Com(unsigned char com)
     80 {
     81     while(LCD_Check_Busy()); //忙则等待
     82     RS_CLR;
     83     RW_CLR;
     84     EN_SET;
     85     DataPort = com;
     86     _nop_();
     87     EN_CLR;
     88 }
     89 /*------------------------------------------------
     90               写入数据函数
     91 ------------------------------------------------*/
     92 void LCD_Write_Data(unsigned char Data)
     93 {
     94     while(LCD_Check_Busy()); //忙则等待
     95     RS_SET;
     96     RW_CLR;
     97     EN_SET;
     98     DataPort = Data;
     99     _nop_();
    100     EN_CLR;
    101 }
    102 
    103 /*------------------------------------------------
    104                 清屏函数
    105 ------------------------------------------------*/
    106 void LCD_Clear(void)
    107 {
    108     LCD_Write_Com(0x01);
    109     DelayMs(5);
    110 }
    111 /*------------------------------------------------
    112               写入字符串函数
    113 ------------------------------------------------*/
    114 void LCD_Write_String(unsigned char x, unsigned char y, unsigned char *s)
    115 {
    116     if (y == 0)
    117     {
    118         LCD_Write_Com(0x80 + x);     //表示第一行
    119     }
    120     else
    121     {
    122         LCD_Write_Com(0xC0 + x);      //表示第二行
    123     }
    124     while (*s)
    125     {
    126         LCD_Write_Data( *s);
    127         s ++;
    128     }
    129 }
    130 /*------------------------------------------------
    131               写入字符函数
    132 ------------------------------------------------*/
    133 void LCD_Write_Char(unsigned char x, unsigned char y, unsigned char Data)
    134 {
    135     if (y == 0)//根据Y的值确定显示在哪一行,不同行RAM地址不一样
    136     {
    137         LCD_Write_Com(0x80 + x);
    138     }
    139     else
    140     {
    141         LCD_Write_Com(0xC0 + x);
    142     }
    143     LCD_Write_Data( Data);
    144 }
    145 /*------------------------------------------------和《4、指令说明》的启动阶段描述一样
    146               初始化函数
    147 ------------------------------------------------*/
    148 void LCD_Init(void)
    149 {
    150     LCD_Write_Com(0x38);    /*显示模式设置*/
    151     DelayMs(5);
    152     LCD_Write_Com(0x38);
    153     DelayMs(5);
    154     LCD_Write_Com(0x38);
    155     DelayMs(5);
    156     LCD_Write_Com(0x38);
    157     LCD_Write_Com(0x08);    /*显示关闭*/
    158     LCD_Write_Com(0x01);    /*显示清屏*/
    159     LCD_Write_Com(0x06);    /*显示光标移动设置*/
    160     DelayMs(5);
    161     LCD_Write_Com(0x0C);    /*显示开及光标设置*/
    162 }
    163 
    164 /*------------------------------------------------
    165                     主函数
    166 ------------------------------------------------*/
    167 void main(void)
    168 {
    169     LCD_Init();
    170     LCD_Clear();//清屏
    171     while (1)
    172     {
    173         LCD_Write_Char(7, 0, 'o');
    174         LCD_Write_Char(8, 0, 'k');
    175         LCD_Write_String(1, 1, "Hard Work");
    176         while(1);
    177     }
    178 }

    小结&接下来计划:

      下一节将把LCD1602的驱动改写成便于移植的版本,同时讨论一些稍微炫一点的效果——滚动、光标等待等。两周内计划是:再研究一个按键的驱动、一个通信的驱动之后就着手写我们的“X-积木”OS了。

    @beautifulzzzz

      2015-9-20 持续更新中~

  • 相关阅读:
    【splunk】数据输入-文件目录 导入失败
    【linux】tar压缩不包含路径
    【python】已安装模块提示ImportError: No module named
    【splunk】用正则表达式提取字段
    【python】xsspider零碎知识点
    【scrapy】资料
    【splunk】一些查询例子
    【docker】将容器中数据拷贝到主机
    【linux】ubuntu下crontab无效解决方法
    Flink – metrics V1.2
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/4823971.html
Copyright © 2020-2023  润新知