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

    显示效果:

    图片显示待续。

      

  • 相关阅读:
    Windows Azure Cloud Service (14) 使用Windows Azure诊断收集日志记录数据
    Windows Azure Cloud Service (13) 用Visual Studio 2010 将应用程序部署到Windows Azure平台
    Windows Azure Cloud Service (15) 多个VM Instance场景下如何处理ASP.NET Session
    Windows Azure Storage (5) Windows Azure Drive
    Windows Azure Storage (7) 使用工具管理Windows Azure Storage
    SQL Azure(二) SQL Azure vs SQL Server
    webbrowser的自动提交
    提取视频的背景声音的软件
    Listview列排序的bug原因
    两个奇怪的问题
  • 原文地址:https://www.cnblogs.com/wen2376/p/3308620.html
Copyright © 2011-2022 走看看