zoukankan      html  css  js  c++  java
  • LCD12864 液晶显示-汉字及自定义显示(并口)

      LCD12864带字库,型号:CM12864-12.其相关数据手册可以在百度中搜索“ST7920 系列中文图形液晶模块使用说明书”,里面有详细的介绍。这里就不在多描述。

    其原理简图:(我们只需关心接口部分)

    接口定义:这里注意V0,我一开始就栽倒这,网上搜到的资料中,这PIN可以悬空或接个滑动电阻,程序检查好多遍,没有发现问题,就是不显示,接到3.3V上也不行,后来把V0直接接到5V上,就可以正常显示。在这提醒大家数据手册仅供参考,具体还是以自己的实物为主。避免走没必要的弯路。

    管脚号

    管脚名称

    电平

    管脚功能描述

    1

    VSS

    0V

    电源地

    2

    VCC

    5V

    电源正

    3

    V0

    -

    对比度(亮度)调整.(直接接到5V上最靠谱)

    4

    RS(CS)

    H/L

    RS=“H”,表示DB7——DB0为显示数据

    RS=“L”,表示DB7——DB0为显示指令数据

    5

    R/W(SID)

    H/L

    R/W=“H”,E=“H”,数据被读到DB7——DB0

    R/W=“L”,E=“H→L”, DB7——DB0的数据被写到IR或DR

    6

    E(SCLK)

    H/L

    使能信号

    7

    DB0

    H/L

    三态数据线

    8

    DB1

    H/L

    三态数据线

    9

    DB2

    H/L

    三态数据线

    10

    DB3

    H/L

    三态数据线

    11

    DB4

    H/L

    三态数据线

    12

    DB5

    H/L

    三态数据线

    13

    DB6

    H/L

    三态数据线

    14

    DB7

    H/L

    三态数据线

    15

    PSB

    H/L

    H:8位或4位并口方式,L:串口方式

    16

    NC

    -

    空脚

    17

    /RESET

    H/L

    复位端,低电平有效(悬空或接到5V都可以)

    18

    VOUT

    -

    LCD驱动电压输出端(悬空)

    19

    A

    VDD

    背光源正端(+5V)

    20

    K

    VSS

    背光源负端(0V)

    ST7920数据手册中,提到每次在写命令之前都要判断LCD是否处于空闲状态,是为0,否则为1,本次试验全过程只写不读,为了避开LCD忙的状态,可以采取隔断时间写一次命令或数据。在指令表中,可以看到每个命令执行的时间,这里注意,除清除显示和地址归位,网上有不同的说法,有的说是1.6ms,有的4.6ms外,其他命令执行时间都是72us,不管怎么样,我们还是取最大值更为靠谱,4.6ms取个整数,好听点的6ms吧。当然可以取比这个更大(LCD在显示数据时,是一个接一个的显示出来,就可以察觉到,取的越大,显示速度就越慢),看自己的决定了。利用FPGA分频,产生一个周期6ms的时钟,给LCD的E管脚,进行控制写数据或命令。在8为并口写操作时序图中,DB0~DB7是在E为高时,写入数据。

    知道了何时给LCD写数据或命令,还得知道如何把自己想要显示的东西显示在LCD屏幕上,这点也不难:

    第一得知道中文字行的编码,可以查国标GB2312,来调用CGROM字库,比如"文:CEC4、少:C9D9、清:C7E5“。或可以下载“汉字十六进制转换工具”软件直接生成。

    第二得知道显示文字的地址该如何设置,就是一个文字我可以摆在第一行的开头或结尾或其他行。如下图示。

    第三若自带的库中没有你想要的东西时,可以自己定义,比如代码中的星星月亮组合图标,库中没有,那么我们可以自己定义(组合图标的编码可以用字模软件进行提取)。自定义字符具体操作,先设定CGRAM存储地址,其次把该组合图标的编码数据放置到该地址中,在设置该图标在LCD屏幕显示的位置,最后连续写两次数据(注意写的是数据不是命令,我也被这东东栽倒一次),先写高8it,后写低8bit,就可以了。此时知道写这数据到底是啥数据。那么就得理解0x0000,0x0002,0x0004,0x0006这四种编码.至于这四种编码有什么区别,我也不是很明白,在程序中,0x0000和0x0006没发现有区别,显示正常;0x0002,在星星的左上角有个小点;0x0004显示乱码。

    第四半宽字型,数据手册中写的是”半宽字型ROM(HCGROM),总共提供126 个西文字型(16×8 点阵)“,应该就是英文字符。程序中的"LCD12864"。

    在写代码之前理清思路,程序的流程该如何跑,写起代码来也比较顺手。如下图。前面设置好频率后,每步中的延时就不用在考虑了。

    代码:(使用并口,只有写)

    LCD12864.v

      1 module LCD12864(
      2                     //input 
      3                     sys_clk,
      4                     rst_n,
      5                     
      6                     //output 
      7                     lcd_rs,
      8                     lcd_rw,
      9                     lcd_en,
     10                     lcd_data,
     11                     lcd_psb
     12                 );
     13 input sys_clk;// 50MHZ
     14 input rst_n;
     15 
     16 output lcd_rs;//H:data    L:command
     17 output lcd_rw;//H:read module    L:write module
     18 output lcd_en;//H active
     19 output [7:0] lcd_data;
     20 output lcd_psb;//H:parallel    module    L:SPI module
     21 
     22 /***************************************************/
     23 parameter T3MS = 18'd149_999;
     24 parameter    IDLE           = 4'd0,
     25             INIT_FUN_SET1 = 4'd1,
     26             INIT_FUN_SET2 = 4'd2,
     27             INIT_DISPLAY  = 4'd3,
     28             INIT_CLEAR       = 4'd4,
     29             INIT_DOT_SET  = 4'd5,
     30             SET_DDRAM      = 4'd6,
     31             WRITE_DATA1      = 4'd7,
     32             INIT_FUN_SET3 = 4'd8,
     33             SET_CGRAM     = 4'd9,
     34             WRITE_DATA2   = 4'd10,
     35             SET_DDRAM2    = 4'd11,
     36             SET_CUSTOM_L  = 4'd12,
     37             SET_CUSTOM_H  = 4'd13,
     38             STOP          = 4'd14;
     39 /***************************************************/
     40 //产生周期为6MS的lcd_clk给LCD
     41 reg [17:0] cnt;
     42 reg lcd_clk;
     43 always @(posedge sys_clk or negedge rst_n)
     44 if(!rst_n) begin
     45     cnt <= 18'd0;
     46     lcd_clk <= 1'b0;
     47 end
     48 else if(cnt == T3MS)begin
     49     cnt <= 18'd0;
     50     lcd_clk <= ~lcd_clk;
     51 end
     52 else
     53     cnt <= cnt + 1'b1;
     54 /***************************************************/
     55 reg lcd_rs;
     56 always @(posedge lcd_clk or negedge rst_n)
     57 if(!rst_n)
     58     lcd_rs <= 1'b0;
     59 else if((state == WRITE_DATA1) || (state == WRITE_DATA2)|| (state == SET_CUSTOM_H) || (state == SET_CUSTOM_L))
     60     lcd_rs <= 1'b1;        //写数据模式
     61 else
     62     lcd_rs <= 1'b0;        //写命令模式
     63 /***************************************************/
     64 reg [3:0] state;
     65 reg [7:0] lcd_data;
     66 reg [6:0] num;
     67 reg en;
     68 always @(posedge lcd_clk or negedge rst_n)
     69 if(!rst_n) begin
     70     state <= IDLE;
     71     lcd_data <= 8'hzz;
     72     en <= 1'b1;
     73     num <= 6'd0;
     74 end    
     75 else
     76     case(state)
     77         IDLE: 
     78         begin
     79             state <= INIT_FUN_SET1;
     80             lcd_data <= 8'hzz;
     81             en <= 1'b1;
     82         end
     83         
     84         INIT_FUN_SET1: 
     85         begin
     86             lcd_data <= 8'h30;    //功能设定
     87             state <= INIT_FUN_SET2;
     88         end 
     89         
     90         INIT_FUN_SET2:
     91         begin
     92             lcd_data <= 8'h30;    //功能设定
     93             state <= INIT_DISPLAY;
     94         end
     95             
     96         INIT_DISPLAY:
     97         begin
     98             lcd_data <= 8'h0c;    //显示设定
     99             state <= INIT_CLEAR;
    100         end
    101             
    102         INIT_CLEAR:
    103         begin
    104             lcd_data <= 8'h01;    //清屏
    105             state <= INIT_DOT_SET;
    106         end
    107         
    108         INIT_DOT_SET:
    109         begin
    110             lcd_data <= 8'h06;    //进入点设定
    111             state <= SET_DDRAM;
    112         end
    113         
    114         SET_DDRAM:
    115         begin
    116             if(num == 7'd0)
    117                 lcd_data <= 8'h81;//1 line
    118             else if(num == 7'd12)
    119                 lcd_data <= 8'h92;//2 line
    120             else if(num == 7'd18)
    121                 lcd_data <= 8'h8a;//3 line
    122             else if(num == 7'd26)
    123                 lcd_data <= 8'h99;//4 line
    124                 
    125             state <= WRITE_DATA1;
    126         end
    127         
    128         WRITE_DATA1:
    129         begin
    130             if(num <= 7'd11) begin   
    131                 num <= num + 1'b1;
    132                 lcd_data <= dis_data;
    133                 if(num == 7'd11)
    134                     state <= SET_DDRAM;
    135                 else
    136                     state <= WRITE_DATA1;
    137             end
    138             else if( num > 7'd11 && num <= 7'd17) begin
    139                 num <= num + 1'b1;
    140                 lcd_data <= dis_data;
    141                 if(num == 7'd17)
    142                     state <= SET_DDRAM;
    143                 else
    144                     state <= WRITE_DATA1;
    145             end
    146             else if(num > 7'd17 && num <= 7'd25) begin
    147                 num <= num + 1'b1;
    148                 lcd_data <= dis_data;
    149                 if(num == 7'd25)
    150                     state <= SET_DDRAM;
    151                 else
    152                     state <= WRITE_DATA1;
    153             end
    154             else if(num > 7'd25 && num <= 7'd33) begin
    155                 num <= num + 1'b1;
    156                 lcd_data <= dis_data;
    157                 if(num == 7'd33)
    158                     state <= INIT_FUN_SET3;
    159                 else
    160                     state <= WRITE_DATA1;
    161             end
    162         end
    163         
    164         INIT_FUN_SET3:    
    165         begin
    166             lcd_data <= 8'h30;//功能设定
    167             state <= SET_CGRAM;
    168         end
    169         
    170         SET_CGRAM:
    171         begin
    172             lcd_data <= 8'h40;//设定CGRAM字符的位置
    173             state <= WRITE_DATA2;
    174         end
    175         
    176         WRITE_DATA2:
    177         begin
    178             if(num >= 7'd34 && num <= 7'd65) begin 
    179                 num <= num + 1'b1;
    180                 lcd_data <= dis_data;
    181                 state <= WRITE_DATA2;
    182             end
    183             else begin
    184                 num <= 7'd0;
    185                 state <= SET_DDRAM2;
    186             end
    187         end
    188         
    189         SET_DDRAM2:
    190         begin
    191             lcd_data <= 8'h9e;    //4line
    192             state <= SET_CUSTOM_H;//设置自定义显示字符编码
    193         end
    194         
    195         SET_CUSTOM_H:
    196         begin
    197             lcd_data <= 8'h00;//高8bit
    198             state <= SET_CUSTOM_L;
    199         end
    200         
    201         SET_CUSTOM_L:
    202         begin
    203             lcd_data <= 8'h06;//低8bit 00:正常 02:星星左上角多了一小点 04:显示的是乱码 06:显示也正常
    204             state <= STOP;
    205         end
    206         
    207         STOP: 
    208         begin
    209             en <= 1'b0;//显示完了,lcd_e就一直拉为低
    210             state <= STOP;
    211         end
    212         
    213         default: state <= IDLE;
    214     endcase
    215 /***************************************************/
    216 reg [7:0] dis_data;
    217 always @(posedge sys_clk or negedge rst_n)
    218 if(!rst_n)
    219     dis_data <= 8'hzz;
    220 else
    221     case(num)
    222     //1 Line 81位置显示 欢迎访问博客
    223     7'd0   :    dis_data <= 8'hbb; 
    224     7'd1   :    dis_data <= 8'hb6; 
    225     7'd2   :    dis_data <= 8'hd3; 
    226     7'd3   :    dis_data <= 8'had; 
    227     7'd4   :    dis_data <= 8'hb7; 
    228     7'd5   :    dis_data <= 8'hc3; 
    229     7'd6   :    dis_data <= 8'hce; 
    230     7'd7   :    dis_data <= 8'hca; 
    231     7'd8   :    dis_data <= 8'hb2; 
    232     7'd9   :    dis_data <= 8'ha9; 
    233     7'd10  :    dis_data <= 8'hbf; 
    234     7'd11  :    dis_data <= 8'hcd; 
    235     //2Line    92位置显示 文少清     
    236     7'd12  :    dis_data <= 8'hce; 
    237     7'd13  :    dis_data <= 8'hc4; 
    238     7'd14  :    dis_data <= 8'hc9; 
    239     7'd15  :    dis_data <= 8'hd9; 
    240     7'd16  :    dis_data <= 8'hC7; 
    241     7'd17  :    dis_data <= 8'he5; 
    242     //3Line 8a位置显示 LCD12864   
    243     7'd18  :    dis_data <=  "L";  
    244     7'd19  :    dis_data <=  "C";  
    245     7'd20  :    dis_data <=  "D";  
    246     7'd21  :    dis_data <=  "1";  
    247     7'd22  :    dis_data <=  "2";  
    248     7'd23  :    dis_data <=  "8";  
    249     7'd24  :    dis_data <=  "6";  
    250     7'd25  :    dis_data <=  "4";  
    251     //4Line 99位置显示 谢谢! 
    252     7'd26  :    dis_data <= 8'hd0; 
    253     7'd27  :    dis_data <= 8'hbb; 
    254     7'd28  :    dis_data <= 8'hd0; 
    255     7'd29  :    dis_data <= 8'hbb; 
    256     7'd30  :    dis_data <= 8'ha3; 
    257     7'd31  :    dis_data <= 8'ha1; 
    258     7'd32  :    dis_data <= " ";   //这两次空格可以不写的
    259     7'd33  :    dis_data <= " ";   
    260     //4line 9e位置显示星星月亮                            
    261     7'd34  :    dis_data <= 8'h08;
    262     7'd35  :    dis_data <= 8'h20;
    263     7'd36  :    dis_data <= 8'h1c;
    264     7'd37  :    dis_data <= 8'h10;
    265     7'd38  :    dis_data <= 8'h1c;
    266     7'd39  :    dis_data <= 8'h1c;
    267     7'd40  :    dis_data <= 8'hff;
    268     7'd41  :    dis_data <= 8'h9e;
    269     7'd42  :    dis_data <= 8'h7f;
    270     7'd43  :    dis_data <= 8'h1e;
    271     7'd43  :    dis_data <= 8'h1c;
    272     7'd45  :    dis_data <= 8'h1f;
    273     7'd46  :    dis_data <= 8'h3e;
    274     7'd47  :    dis_data <= 8'h1f;
    275     7'd48  :    dis_data <= 8'h3e;
    276     7'd49  :    dis_data <= 8'h1f;
    277     7'd50  :    dis_data <= 8'h77;
    278     7'd51  :    dis_data <= 8'h1f;
    279     7'd52  :    dis_data <= 8'h41;
    280     7'd53  :    dis_data <= 8'h3f;
    281     7'd54  :    dis_data <= 8'h00;
    282     7'd55  :    dis_data <= 8'h7e;
    283     7'd56  :    dis_data <= 8'h00;
    284     7'd57  :    dis_data <= 8'hfe;
    285     7'd58  :    dis_data <= 8'h83;
    286     7'd59  :    dis_data <= 8'hfc;
    287     7'd60  :    dis_data <= 8'h7f;
    288     7'd61  :    dis_data <= 8'hf8;
    289     7'd62  :    dis_data <= 8'h3f;
    290     7'd63  :    dis_data <= 8'hf0;
    291     7'd64  :    dis_data <= 8'h0f;
    292     7'd65  :    dis_data <= 8'hc0;
    293     default:    dis_data <= 8'h00;
    294     endcase 
    295 /***************************************************/
    296 assign lcd_rw = 1'b0;//只有写模式
    297 assign lcd_psb = 1'b1;//并口模式
    298 assign lcd_en = en ?  lcd_clk : 1'b0;
    299 /***************************************************/
    300 endmodule
    View Code

    显示效果:

    图片显示待续。

      

  • 相关阅读:
    Java 对象的封装,继承,抽象,接口写法
    python 3.7 方向键乱码
    yocto doc
    为什么要使用yocto
    ltp-ddt的makefile结构
    Git 常用命令列表
    Makefile依赖关系中的竖线“|”
    makefile 双冒号规则
    ltp makefile 解析
    makefile 变量展开
  • 原文地址:https://www.cnblogs.com/wen2376/p/3308620.html
Copyright © 2011-2022 走看看