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

 module LCD12864(
//input
sys_clk,
rst_n, //output
lcd_rs,
lcd_rw,
lcd_en,
lcd_data,
lcd_psb
);
input sys_clk;// 50MHZ
input rst_n; output lcd_rs;//H:data L:command
output lcd_rw;//H:read module L:write module
output lcd_en;//H active
output [:] lcd_data;
output lcd_psb;//H:parallel module L:SPI module /***************************************************/
parameter T3MS = 'd149_999;
parameter IDLE = 'd0,
INIT_FUN_SET1 = 'd1,
INIT_FUN_SET2 = 'd2,
INIT_DISPLAY = 'd3,
INIT_CLEAR = 'd4,
INIT_DOT_SET = 'd5,
SET_DDRAM = 'd6,
WRITE_DATA1 = 'd7,
INIT_FUN_SET3 = 'd8,
SET_CGRAM = 'd9,
WRITE_DATA2 = 'd10,
SET_DDRAM2 = 'd11,
SET_CUSTOM_L = 'd12,
SET_CUSTOM_H = 'd13,
STOP = 'd14;
/***************************************************/
//产生周期为6MS的lcd_clk给LCD
reg [:] cnt;
reg lcd_clk;
always @(posedge sys_clk or negedge rst_n)
if(!rst_n) begin
cnt <= 'd0;
lcd_clk <= 'b0;
end
else if(cnt == T3MS)begin
cnt <= 'd0;
lcd_clk <= ~lcd_clk;
end
else
cnt <= cnt + 'b1;
/***************************************************/
reg lcd_rs;
always @(posedge lcd_clk or negedge rst_n)
if(!rst_n)
lcd_rs <= 'b0;
else if((state == WRITE_DATA1) || (state == WRITE_DATA2)|| (state == SET_CUSTOM_H) || (state == SET_CUSTOM_L))
lcd_rs <= 'b1; //写数据模式
else
lcd_rs <= 'b0; //写命令模式
/***************************************************/
reg [:] state;
reg [:] lcd_data;
reg [:] num;
reg en;
always @(posedge lcd_clk or negedge rst_n)
if(!rst_n) begin
state <= IDLE;
lcd_data <= 'hzz;
en <= 'b1;
num <= 'd0;
end
else
case(state)
IDLE:
begin
state <= INIT_FUN_SET1;
lcd_data <= 'hzz;
en <= 'b1;
end INIT_FUN_SET1:
begin
lcd_data <= 'h30; //功能设定
state <= INIT_FUN_SET2;
end INIT_FUN_SET2:
begin
lcd_data <= 'h30; //功能设定
state <= INIT_DISPLAY;
end INIT_DISPLAY:
begin
lcd_data <= 'h0c; //显示设定
state <= INIT_CLEAR;
end INIT_CLEAR:
begin
lcd_data <= 'h01; //清屏
state <= INIT_DOT_SET;
end INIT_DOT_SET:
begin
lcd_data <= 'h06; //进入点设定
state <= SET_DDRAM;
end SET_DDRAM:
begin
if(num == 'd0)
lcd_data <= 'h81;//1 line
else if(num == 'd12)
lcd_data <= 'h92;//2 line
else if(num == 'd18)
lcd_data <= 'h8a;//3 line
else if(num == 'd26)
lcd_data <= 'h99;//4 line state <= WRITE_DATA1;
end WRITE_DATA1:
begin
if(num <= 'd11) begin
num <= num + 'b1;
lcd_data <= dis_data;
if(num == 'd11)
state <= SET_DDRAM;
else
state <= WRITE_DATA1;
end
else if( num > 'd11 && num <= 7'd17) begin
num <= num + 'b1;
lcd_data <= dis_data;
if(num == 'd17)
state <= SET_DDRAM;
else
state <= WRITE_DATA1;
end
else if(num > 'd17 && num <= 7'd25) begin
num <= num + 'b1;
lcd_data <= dis_data;
if(num == 'd25)
state <= SET_DDRAM;
else
state <= WRITE_DATA1;
end
else if(num > 'd25 && num <= 7'd33) begin
num <= num + 'b1;
lcd_data <= dis_data;
if(num == 'd33)
state <= INIT_FUN_SET3;
else
state <= WRITE_DATA1;
end
end INIT_FUN_SET3:
begin
lcd_data <= 'h30;//功能设定
state <= SET_CGRAM;
end SET_CGRAM:
begin
lcd_data <= 'h40;//设定CGRAM字符的位置
state <= WRITE_DATA2;
end WRITE_DATA2:
begin
if(num >= 'd34 && num <= 7'd65) begin
num <= num + 'b1;
lcd_data <= dis_data;
state <= WRITE_DATA2;
end
else begin
num <= 'd0;
state <= SET_DDRAM2;
end
end SET_DDRAM2:
begin
lcd_data <= 'h9e; //4line
state <= SET_CUSTOM_H;//设置自定义显示字符编码
end SET_CUSTOM_H:
begin
lcd_data <= 'h00;//高8bit
state <= SET_CUSTOM_L;
end SET_CUSTOM_L:
begin
lcd_data <= 'h06;//低8bit 00:正常 02:星星左上角多了一小点 04:显示的是乱码 06:显示也正常
state <= STOP;
end STOP:
begin
en <= 'b0;//显示完了,lcd_e就一直拉为低
state <= STOP;
end default: state <= IDLE;
endcase
/***************************************************/
reg [:] dis_data;
always @(posedge sys_clk or negedge rst_n)
if(!rst_n)
dis_data <= 'hzz;
else
case(num)
//1 Line 81位置显示 欢迎访问博客
'd0 : dis_data <= 8'hbb;
'd1 : dis_data <= 8'hb6;
'd2 : dis_data <= 8'hd3;
'd3 : dis_data <= 8'had;
'd4 : dis_data <= 8'hb7;
'd5 : dis_data <= 8'hc3;
'd6 : dis_data <= 8'hce;
'd7 : dis_data <= 8'hca;
'd8 : dis_data <= 8'hb2;
'd9 : dis_data <= 8'ha9;
'd10 : dis_data <= 8'hbf;
'd11 : dis_data <= 8'hcd;
//2Line 92位置显示 文少清
'd12 : dis_data <= 8'hce;
'd13 : dis_data <= 8'hc4;
'd14 : dis_data <= 8'hc9;
'd15 : dis_data <= 8'hd9;
'd16 : dis_data <= 8'hC7;
'd17 : dis_data <= 8'he5;
//3Line 8a位置显示 LCD12864
'd18 : dis_data <= "L";
'd19 : dis_data <= "C";
'd20 : dis_data <= "D";
'd21 : dis_data <= "1";
'd22 : dis_data <= "2";
'd23 : dis_data <= "8";
'd24 : dis_data <= "6";
'd25 : dis_data <= "4";
//4Line 99位置显示 谢谢!
'd26 : dis_data <= 8'hd0;
'd27 : dis_data <= 8'hbb;
'd28 : dis_data <= 8'hd0;
'd29 : dis_data <= 8'hbb;
'd30 : dis_data <= 8'ha3;
'd31 : dis_data <= 8'ha1;
'd32 : dis_data <= " "; //这两次空格可以不写的
'd33 : dis_data <= " ";
//4line 9e位置显示星星月亮
'd34 : dis_data <= 8'h08;
'd35 : dis_data <= 8'h20;
'd36 : dis_data <= 8'h1c;
'd37 : dis_data <= 8'h10;
'd38 : dis_data <= 8'h1c;
'd39 : dis_data <= 8'h1c;
'd40 : dis_data <= 8'hff;
'd41 : dis_data <= 8'h9e;
'd42 : dis_data <= 8'h7f;
'd43 : dis_data <= 8'h1e;
'd43 : dis_data <= 8'h1c;
'd45 : dis_data <= 8'h1f;
'd46 : dis_data <= 8'h3e;
'd47 : dis_data <= 8'h1f;
'd48 : dis_data <= 8'h3e;
'd49 : dis_data <= 8'h1f;
'd50 : dis_data <= 8'h77;
'd51 : dis_data <= 8'h1f;
'd52 : dis_data <= 8'h41;
'd53 : dis_data <= 8'h3f;
'd54 : dis_data <= 8'h00;
'd55 : dis_data <= 8'h7e;
'd56 : dis_data <= 8'h00;
'd57 : dis_data <= 8'hfe;
'd58 : dis_data <= 8'h83;
'd59 : dis_data <= 8'hfc;
'd60 : dis_data <= 8'h7f;
'd61 : dis_data <= 8'hf8;
'd62 : dis_data <= 8'h3f;
'd63 : dis_data <= 8'hf0;
'd64 : dis_data <= 8'h0f;
'd65 : dis_data <= 8'hc0;
default: dis_data <= 'h00;
endcase
/***************************************************/
assign lcd_rw = 'b0;//只有写模式
assign lcd_psb = 'b1;//并口模式
assign lcd_en = en ? lcd_clk : 'b0;
/***************************************************/
endmodule

显示效果:

图片显示待续。

  

LCD12864 液晶显示-汉字及自定义显示(并口)的更多相关文章

  1. LCD12864 液晶显示-汉字及自定义显示(串口)

    在网上找了许久,发现FPGA用串口驱动LCD12864程序很少,基本上没有.刚开始窃喜,中间郁闷,最后还是高兴,为什么这样说呢!头一回在没有参考程序的情况下,完全是照时序图写(自信),中间调试过程遇到 ...

  2. Siteserver-stl:searchOutput(搜索结果)自定义显示样式

    stl:searchOutput 自定义显示样式 自定义搜索提交表单需要在<stl:searchOutput>中嵌入显示搜索结果的标签,必须包含的标签 有<stl:pageConte ...

  3. TreeView 自定义显示checkbox

    本项目需要对TreeView进行定制,要求比较简单,主要要求如下: Winform中TreeView控件默认只支持所有级别的CheckBox显示或者不显示,不能控制制定Level的树节点显示 效果如下 ...

  4. SharePoint 2013 关于自定义显示列表表单的bug

    1.在SharePoint 2013中,我们隐藏列表Dispform页面的ListFormWebPart部件,转而使用自定义显示列表表单进行展示,因为这样更容易定制我们需要的显示: 2.之后发现文件夹 ...

  5. Protege汉字不能正常显示问题

    在Protege5.0中有下面的问题: 点击uses,汉字不能正常显示. 在qq群里面问到,可以通过设置label的方式,在对类,子类命名成英语的,点击annotations,在label中设置汉字名 ...

  6. LR脚本自定义显示Controller虚拟用户状态

    在场景监控的过程中,想知道场景运行时Vusers的运行状态以及每一个Vuser虚拟用户在本次场景运行的过程共迭代了多少次,那么就需要在VuGen脚本中自定义显示虚拟用户状态信息. 代码如下: stat ...

  7. ToastCustom【自定义显示风格的Toast】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 基于系统Toast的自定义显示风格的Toast. 效果图 代码分析 ToastCustom类基于系统Toast,不是继承Toast, ...

  8. Myeclipse和 eclipse中的控制台汉字横着显示修改

    Myeclipse和 eclipse中的控制台汉字横着显示问题的修改 如图: 同一种字体有两种显示方式,比如微软雅黑和@微软雅黑,前一种汉字是竖着显示,后一种汉字是横着显示. 修改方法: prefer ...

  9. piwik获取访客头像,自定义显示访问者头像(URL)和描述(标题和替代)

    访客头像 自定义显示访问者头像(URL)和描述(标题和替代) 链接地址:https://plugins.matomo.org/VisitorAvatar#description

随机推荐

  1. LeetCode OJ 98. Validate Binary Search Tree

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  2. linux下编译安装apache

    在linux(CentOS6.5)上安装Apache,要首先确保以下程序事先安装 apr:The mission of the Apache Portable Runtime (APR) projec ...

  3. error: invalid 'asm': invalid operand for code 'w'

    google 出结果 http://stackoverflow.com/questions/15623609/including-curl-into-the-android-aosp ........ ...

  4. 5.1 timestamp数据类型默认值

    5.1 不支持同一张表中有多个tmiestamp类型字段的默认值为current_time,  5.6版本无此问题

  5. 关于spring的注解方式注入默认值(转) -- 首字母小写

    1.是首字母小写 比如 UserAction对应的id是userAction 可以通过ApplicationContext 对象的act.getBean("userAction") ...

  6. position的absolute与fixed共同点与不同点

    这个问题面试被问到过~~ A:共同点: 1.改变行内元素的呈现方式,display被置为block: 2.让元素脱离普通流,不占据空间: 3.默认会覆盖到非定位元素上   B不同点: absolute ...

  7. Mishka and Interesting sum

    Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes input ...

  8. mysql 修改 添加 删除 表字段

    添加表的字段    alter table 表名  add  字段名  字段的类型 例子:        alter table table1 add transactor varchar(10) n ...

  9. UIWebView 使用要注意的几点

    UIWebView 使用要注意的几点 最近有客户希望将移动端统一使用HTML5来完成,在iOS端就要用到UIWebView.遇到了以下三个主要问题: 加载HTTPS页面 不像Safari可以弹出弹框问 ...

  10. java 对象的上转型对象(父类)

    Example5_10.java class 类人猿 { void crySpeak(String s) { System.out.println(s); } } class People exten ...