zoukankan      html  css  js  c++  java
  • 51单片机学习笔记(郭天祥版)(8)——1602液晶

    右边那个用于插入1602,左边那个电位器(滑动变阻器)用于调节液晶的对比度,转动后,字符的颜色会发生深浅变化。

    这样插上去,插反了容易把液晶烧坏。

    1602:1行可以显示16个字符,一共两行。

    还有1601,0801,0802,12864,12232、320240、320640。

    12864:图形液晶,横着有128个点,竖着有64个点。要让显示东西,控制矩阵内这些任何的点就会显示图形或汉字。如果是带字库的液晶,写字的时候,直接把汉字赋给液晶的数据口,这些字体就能出来。

    1602只能显示数字和字符,即数字、英文字母、符号,所有的asc码,不能显示汉字。

    这种液晶就是两色,还有带有灰度值得,可以显示出动画,还有wei 彩的、真彩的就是彩色液晶,也可以由单片机驱动。


    液晶比数码管有意思多了,而且比数码管简单。

    1602有好几种接口,这里是并行接口。

    3VL就是液晶对比度调节。

    4RS液晶写数据之前要先接收命令,表示他要干什么,命令是要让液晶内部进行一些设置,数据就是直接要显示的数据。首先命令在什么位置显示什么东西,就像光标闪烁就是命令。H电平接收数据,L电平接收命令。

    5RW读写数据,液晶可以写数据,也可以从里面读数据。今天简化一下,就不读数据了。

    D0~D7,8位数据口。

    15~16不接背光就不亮了。

    设计电路板才需要考虑尺寸,所以不看了。

    控制器接口这是液晶内部。

    要读当前状态是否允许写,比如上一个状态还没有显示出来又写了一个,这就不行,数据会丢失。这是高速操作用的。

    我们只看写,1.2:RS=L(选中了命令,命令就是指令),RW=L(写),D0~D7指令码(后面讲,D0~D7可以送指令也可以送数据,由RS决定),E=高脉冲前者为高脉冲,后者为低脉冲。输出就不管了。

    1.3也是读,就不看了。

    1.4:RS=H(选中数据),RW=L(写),D0~D7(数据),E=高脉冲。

    数字芯片要读懂时序图。

    读的就不看了,看写的。

    能看到许多都是两条线,那是因为一个是写,一个是读。

    我们只看写的,首先RS,RW变低,过一段时间,再给E一个高脉冲,持续一段时间,再拉为低电平,持续一段时间,再将RS、RW变回高。具体写程序再看。

    延时多少时间,要看时序参数:

    不同厂家操作时序不一样,这里郭天祥说按照长沙太阳人公司(就是上面这些内容的出处)的不能正常工作.....然后看了英文原版的。

     

    我们可以不检测,我们做个延时,等他忙完,在进行第二个操作,可以省不少事情,不至于程序写的麻烦。

    看到省略号后面还有,视频中字符是从右侧慢慢移到左边的,实际上就是写到了后面,先全部写完,有一个整屏移动指令,就全都移动出来了。还有别的方向的。但是省略号后面那些不在显示范围内。

    5*7点阵:其实每个字符是由5行7列的点阵组成的

    要显示东西,肯定要让D=1,光标显示关闭等会我们分别试试看看效果。

    N=1,每写一个字节,地址指针自动加1,下一次直接写数据就可以了,N=0,就是倒着往前写。

    80字节RAM:00~67。

    数据指针,也是指令,要先设置数据指到什么位置,然后再写数据,不能直接写0-27,前面要有个80H+,80H+1地址就是01,80H就是00。

    我们写的时候不按照这个,按照自己的方法。

    1602和51单片机的接口

    这里中间74LS00那里不看,可能是自动写入方法。RD和WR第二功能还没讲,用的时候自己看。

        

    15、16背光,加了一个10Ω电阻,怕直接加5V电压后电流过大把芯片烧坏,用它限流。

    D0~D7数据口接了P0口,6接口是使能端,接了P3.4。然后5这个IO口和我们的不一样,因为这里只写,所以视频中直接接了低电平,4是数据命令选择端,接了P3.5,3是偏压信号,接地,液晶显示需要负电压,并用滑动变阻器调节,电压就会变化,内部对比度就会变化。


    接下来程序,我们先把光标写出来

    注意D0~D7连接着数码管的,写数据时,数码管也会变,实验板是usb供电,同时把数码管和液晶打开,功耗会过大,usb供电电流比较小,功耗不够,液晶就会不亮,所以我们把数码管全部关端,把锁存端关闭就可以。

    然后就照着下面的图写就可以了

    这里我先尝试按照视频中的电路接法,用的仿真,把RW接地。由于RW一直为低,所以就不需要tSP1的等待时间了

     1 #include<reg51.h>
     2 
     3 #define uchar unsigned char
     4 #define uint unsigned int
     5     
     6 sbit DUAN=P2^6;
     7 sbit WEI=P2^7;
     8 sbit lcden=P3^4;
     9 sbit lcdrs=P3^5;
    10 //sbit lcdrw=P3^6;
    11 
    12 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
    13 //                    0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F   无显示
    14 
    15 void Delay1ms();
    16 void delay(int n);
    17 void write_com(uchar com);
    18 void write_data(uchar date);
    19 void init();
    20 
    21 void main()
    22 {
    23     init();
    24     while(1);
    25 }
    26 void write_com(uchar com)
    27 {
    28     //写命令
    29     lcdrs=0;//数据命令选择端,选择命令
    30     P0=com;//送指令
    31     delay(5);
    32     lcden=1;
    33     delay(5);
    34     lcden=0;
    35 }
    36 void write_data(uchar date)
    37 {
    38     //写数据
    39     lcdrs=1;//数据命令选择端,选择数据
    40     P0=date;//送数据
    41     delay(5);
    42     lcden=1;
    43     delay(5);
    44     lcden=0;
    45 }
    46 void init()
    47 {
    48     //第一步关闭数码管两个锁存器
    49     DUAN=0;
    50     WEI=0;
    51     //第二步初始化液晶
    52     lcden=0;//使能
    53     write_com(0x38);//模式初始化
    54     write_com(0x0f);//开显示,显示光标,光标闪烁
    55     write_com(0x06);//光标+1,不整屏移动了
    56     
    57 }
    58 void delay(int n)
    59 {
    60     while(n--)
    61     {
    62         Delay1ms();
    63     }
    64 }
    65 void Delay1ms()        //@12.000MHz
    66 {
    67     unsigned char i, j;
    68 
    69     i = 2;
    70     j = 239;
    71     do
    72     {
    73         while (--j);
    74     } while (--i);
    75 }

    代码是成功的,我们也可以让光标不闪烁,即将0x0f改为0x0e;

    但是会发现,前面有一个黑块,这这么回事?

    本以为没有初始化光标,所以在init中write_com(0x06)后面加了一个write_com(0x80);结果不行,光标没了...

    可能是一开始有数据,我们先清屏一下,加上write_com(0x01)

     1 #include<reg51.h>
     2 
     3 #define uchar unsigned char
     4 #define uint unsigned int
     5     
     6 sbit DUAN=P2^6;
     7 sbit WEI=P2^7;
     8 sbit lcden=P3^4;
     9 sbit lcdrs=P3^5;
    10 //sbit lcdrw=P3^6;
    11 
    12 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
    13 //                    0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F   无显示
    14 
    15 void Delay1ms();
    16 void delay(int n);
    17 void write_com(uchar com);
    18 void write_data(uchar date);
    19 void init();
    20 
    21 void main()
    22 {
    23     init();
    24     while(1);
    25 }
    26 void write_com(uchar com)
    27 {
    28     //写命令
    29     lcdrs=0;//数据命令选择端,选择命令
    30     P0=com;//送指令
    31     delay(5);
    32     lcden=1;
    33     delay(5);
    34     lcden=0;
    35 }
    36 void write_data(uchar date)
    37 {
    38     //写数据
    39     lcdrs=1;//数据命令选择端,选择数据
    40     P0=date;//送数据
    41     delay(5);
    42     lcden=1;
    43     delay(5);
    44     lcden=0;
    45 }
    46 void init()
    47 {
    48     //第一步关闭数码管两个锁存器
    49     DUAN=0;
    50     WEI=0;
    51     //第二步初始化液晶
    52     lcden=0;//使能
    53     write_com(0x38);//模式初始化
    54     write_com(0x0f);//开显示,显示光标,光标闪烁
    55     write_com(0x06);//光标+1,不整屏移动了
    56     write_com(0x01);//显示清零,数据指针清零
    57     write_com(0x80);//数据地址指针初始化00
    58     
    59 }
    60 void delay(int n)
    61 {
    62     while(n--)
    63     {
    64         Delay1ms();
    65     }
    66 }
    67 void Delay1ms()        //@12.000MHz
    68 {
    69     unsigned char i, j;
    70 
    71     i = 2;
    72     j = 239;
    73     do
    74     {
    75         while (--j);
    76     } while (--i);
    77 }

    光标有了,接下来可以写数据了,我们先写一个1

     1 #include<reg51.h>
     2 
     3 #define uchar unsigned char
     4 #define uint unsigned int
     5     
     6 sbit DUAN=P2^6;
     7 sbit WEI=P2^7;
     8 sbit lcden=P3^4;
     9 sbit lcdrs=P3^5;
    10 //sbit lcdrw=P3^6;
    11 
    12 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
    13 //                    0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F   无显示
    14 
    15 void Delay1ms();
    16 void delay(int n);
    17 void write_com(uchar com);
    18 void write_data(uchar date);
    19 void init();
    20 
    21 void main()
    22 {
    23     init();
    24     write_data('1');
    25     while(1);
    26 }
    27 void write_com(uchar com)
    28 {
    29     //写命令
    30     lcdrs=0;//数据命令选择端,选择命令
    31     P0=com;//送指令
    32     delay(5);
    33     lcden=1;
    34     delay(5);
    35     lcden=0;
    36 }
    37 void write_data(uchar date)
    38 {
    39     //写数据
    40     lcdrs=1;//数据命令选择端,选择数据
    41     P0=date;//送数据
    42     delay(5);
    43     lcden=1;
    44     delay(5);
    45     lcden=0;
    46 }
    47 void init()
    48 {
    49     //第一步关闭数码管两个锁存器
    50     DUAN=0;
    51     WEI=0;
    52     //第二步初始化液晶
    53     lcden=0;//使能
    54     write_com(0x38);//模式初始化
    55     write_com(0x0e);//开显示,显示光标,光标闪烁
    56     write_com(0x06);//光标+1,不整屏移动了
    57     write_com(0x01);//显示清零,数据指针清零
    58     write_com(0x80);//数据地址指针初始化00
    59     
    60 }
    61 void delay(int n)
    62 {
    63     while(n--)
    64     {
    65         Delay1ms();
    66     }
    67 }
    68 void Delay1ms()        //@12.000MHz
    69 {
    70     unsigned char i, j;
    71 
    72     i = 2;
    73     j = 239;
    74     do
    75     {
    76         while (--j);
    77     } while (--i);
    78 }

    成功并且光标后移1位

    如果我们直接写write_com(1)

    那么显示就不对。

    这里可以看一个手册

    这里给出了每个字符对应的16进制数,即asc值。

    这就是各个字符的16进制编码,从图中可以看到1的是31,a是41,之前串口通信的时候我们也看到过。

    我们写'1'就是给了1的asc

    如果我们直接给了0x31,那么也是输出1

    如果我们想多输入几个,那么主函数如下

    1 void main()
    2 {
    3     init();
    4     write_data('1');
    5     delay(20);
    6     write_data('b');
    7     while(1);
    8 }

    接下来我们写两行,第一行:I LIKE MCU!  第二行:123456789,那么为了简便,我们要用到循环,不过有的人可能会这么写:

     1 #include<reg51.h>
     2 
     3 #define uchar unsigned char
     4 #define uint unsigned int
     5     
     6 sbit DUAN=P2^6;
     7 sbit WEI=P2^7;
     8 sbit lcden=P3^4;
     9 sbit lcdrs=P3^5;
    10 //sbit lcdrw=P3^6;
    11 
    12 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
    13 //                    0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F   无显示
    14 uchar code Table[]="I LIKE MCU!";
    15 uchar code Table1[]="123456789";
    16 void Delay1ms();
    17 void delay(int n);
    18 void write_com(uchar com);
    19 void write_data(uchar date);
    20 uchar num=0;
    21 void init();
    22 
    23 void main()
    24 {
    25     init();
    26     for(num=0;num<11;num++)
    27     {
    28         write_data(Table[num]);
    29         delay(5);
    30     }
    31     for(num=0;num<9;num++)
    32     {
    33         write_data(Table1[num]);
    34         delay(5);
    35     }
    36     while(1);
    37 }
    38 void write_com(uchar com)
    39 {
    40     //写命令
    41     lcdrs=0;//数据命令选择端,选择命令
    42     P0=com;//送指令
    43     delay(5);
    44     lcden=1;
    45     delay(5);
    46     lcden=0;
    47 }
    48 void write_data(uchar date)
    49 {
    50     //写数据
    51     lcdrs=1;//数据命令选择端,选择数据
    52     P0=date;//送数据
    53     delay(5);
    54     lcden=1;
    55     delay(5);
    56     lcden=0;
    57 }
    58 void init()
    59 {
    60     //第一步关闭数码管两个锁存器
    61     DUAN=0;
    62     WEI=0;
    63     //第二步初始化液晶
    64     lcden=0;//使能
    65     write_com(0x38);//模式初始化
    66     write_com(0x0e);//开显示,显示光标,光标闪烁
    67     write_com(0x06);//光标+1,不整屏移动了
    68     write_com(0x01);//显示清零,数据指针清零
    69     write_com(0x80);//数据地址指针初始化00
    70     
    71 }
    72 void delay(int n)
    73 {
    74     while(n--)
    75     {
    76         Delay1ms();
    77     }
    78 }
    79 void Delay1ms()        //@12.000MHz
    80 {
    81     unsigned char i, j;
    82 
    83     i = 2;
    84     j = 239;
    85     do
    86     {
    87         while (--j);
    88     } while (--i);
    89 }

    一行哪有那么多字符额...

    所以我们要换行

     1 #include<reg51.h>
     2 
     3 #define uchar unsigned char
     4 #define uint unsigned int
     5     
     6 sbit DUAN=P2^6;
     7 sbit WEI=P2^7;
     8 sbit lcden=P3^4;
     9 sbit lcdrs=P3^5;
    10 //sbit lcdrw=P3^6;
    11 
    12 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
    13 //                    0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F   无显示
    14 uchar code Table[]="I LIKE MCU!";
    15 uchar code Table1[]="123456789";
    16 void Delay1ms();
    17 void delay(int n);
    18 void write_com(uchar com);
    19 void write_data(uchar date);
    20 uchar num=0;
    21 void init();
    22 
    23 void main()
    24 {
    25     init();
    26     for(num=0;num<11;num++)
    27     {
    28         write_data(Table[num]);
    29         delay(5);
    30     }
    31     write_com(0x80+0x40);//换行,第一行0-27H,第二行40H-60H
    32     for(num=0;num<9;num++)
    33     {
    34         write_data(Table1[num]);
    35         delay(5);
    36     }
    37     while(1);
    38 }
    39 void write_com(uchar com)
    40 {
    41     //写命令
    42     lcdrs=0;//数据命令选择端,选择命令
    43     P0=com;//送指令
    44     delay(5);
    45     lcden=1;
    46     delay(5);
    47     lcden=0;
    48 }
    49 void write_data(uchar date)
    50 {
    51     //写数据
    52     lcdrs=1;//数据命令选择端,选择数据
    53     P0=date;//送数据
    54     delay(5);
    55     lcden=1;
    56     delay(5);
    57     lcden=0;
    58 }
    59 void init()
    60 {
    61     //第一步关闭数码管两个锁存器
    62     DUAN=0;
    63     WEI=0;
    64     //第二步初始化液晶
    65     lcden=0;//使能
    66     write_com(0x38);//模式初始化
    67     write_com(0x0e);//开显示,显示光标,光标闪烁
    68     write_com(0x06);//光标+1,不整屏移动了
    69     write_com(0x01);//显示清零,数据指针清零
    70     write_com(0x80);//数据地址指针初始化00
    71     
    72 }
    73 void delay(int n)
    74 {
    75     while(n--)
    76     {
    77         Delay1ms();
    78     }
    79 }
    80 void Delay1ms()        //@12.000MHz
    81 {
    82     unsigned char i, j;
    83 
    84     i = 2;
    85     j = 239;
    86     do
    87     {
    88         while (--j);
    89     } while (--i);
    90 }

    如果想让每一个字符出现的慢一点,就把delay加长。

    接下来我们让所有字符从右往左移动出来。

    之前的不全,少了这个指令

    cursor光标,display shift显示移动

    在不改变DD RAM的情况下,他会移动光标或显示

     00:光标左移

    01:光标右移

    10:显示左移,光标跟随显示移动

    11:显示右移

    写一条指令移动一下

    首先我们就不能写在00了,就要从10开始

     1 #include<reg51.h>
     2 
     3 #define uchar unsigned char
     4 #define uint unsigned int
     5     
     6 sbit DUAN=P2^6;
     7 sbit WEI=P2^7;
     8 sbit lcden=P3^4;
     9 sbit lcdrs=P3^5;
    10 //sbit lcdrw=P3^6;
    11 
    12 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
    13 //                    0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F   无显示
    14 uchar code Table[]="I LIKE MCU!";
    15 uchar code Table1[]="123456789";
    16 void Delay1ms();
    17 void delay(int n);
    18 void write_com(uchar com);
    19 void write_data(uchar date);
    20 uchar num=0;
    21 void init();
    22 
    23 void main()
    24 {
    25     init();
    26     for(num=0;num<11;num++)
    27     {
    28         write_data(Table[num]);
    29         delay(5);
    30     }
    31     write_com(0x80+0x53);//换行,第一行0-27H,第二行40H-60H
    32     for(num=0;num<9;num++)
    33     {
    34         write_data(Table1[num]);
    35         delay(5);
    36     }
    37     for(num=0;num<16;num++)
    38     {
    39         write_com(0x1c);//显示左移1次
    40         delay(100);
    41     }
    42     while(1);
    43 }
    44 void write_com(uchar com)
    45 {
    46     //写命令
    47     lcdrs=0;//数据命令选择端,选择命令
    48     P0=com;//送指令
    49     delay(5);
    50     lcden=1;
    51     delay(5);
    52     lcden=0;
    53 }
    54 void write_data(uchar date)
    55 {
    56     //写数据
    57     lcdrs=1;//数据命令选择端,选择数据
    58     P0=date;//送数据
    59     delay(5);
    60     lcden=1;
    61     delay(5);
    62     lcden=0;
    63 }
    64 void init()
    65 {
    66     //第一步关闭数码管两个锁存器
    67     DUAN=0;
    68     WEI=0;
    69     //第二步初始化液晶
    70     lcden=0;//使能
    71     write_com(0x38);//模式初始化
    72     write_com(0x0e);//开显示,显示光标,光标闪烁
    73     write_com(0x06);//光标+1,不整屏移动了
    74     write_com(0x01);//显示清零,数据指针清零
    75     write_com(0x80+0x10);//数据地址指针初始化10
    76     
    77 }
    78 void delay(int n)
    79 {
    80     while(n--)
    81     {
    82         Delay1ms();
    83     }
    84 }
    85 void Delay1ms()        //@12.000MHz
    86 {
    87     unsigned char i, j;
    88 
    89     i = 2;
    90     j = 239;
    91     do
    92     {
    93         while (--j);
    94     } while (--i);
    95 }

    怪异,视频中是0x10,我的必须是0x1c,方向和上面的数据手册相反,下次实验板试试好了

    仿真用0x1c,单片机用0x18

  • 相关阅读:
    [原创]什么是安全性测试
    [原创]如何有效的考核测试人员
    [原创]MySql官方压力测试工具Mysqlslap
    [原创软件测试工作技能
    [原创]如何有效构建测试环境
    [原创]常见系统测试类型总结
    [原创]Kjava手机顽童模拟器
    [原创]浅谈测试人员提交缺陷记录
    [原创]Windows/Unix 资源性能计数器
    [原创]戴明PDCA方法
  • 原文地址:https://www.cnblogs.com/IceHowe/p/10712884.html
Copyright © 2011-2022 走看看