lcd1602如何自定义汉字(verilog)
今天一鼓作气,再研究了一下如何用LCD1602自定义汉字
1、用字模软件获取汉字所对应的数据(因为嫌麻烦所以直接用了网上一个帖子里有关“电”的数据,如下:04,1f,15,1f,15,15,1f,04,07)帖子链接:http://www.51hei.com/mcu/3696.html
2、主要知识点
(1)lcd1602的11个指令集与lcd1602的基本显示,前两篇文章已经详细说过,链接如下
http://www.cnblogs.com/aslmer/p/5801363.html
http://www.cnblogs.com/aslmer/p/5819422.html
(2)DDRAM 与 CGRAM 的区别,根据数据手册知道我们可以定义8个汉字,具体更多知识点请自己百度。
(3)主要的两个指令 Set CGRAM Address 、 Write data to RAM 。
module lcd_1602_driver(
clk ,
rst_n ,
lcd_en ,
lcd_rw ,
lcd_rs ,
lcd_data );
input clk ;
input rst_n ; output lcd_en ;
output lcd_rw ;
output lcd_rs ;
output [:] lcd_data;
wire clk ;
wire rst_n ;
wire lcd_en ;
wire lcd_rw;
reg [:] lcd_data;
reg lcd_rs ;
reg [:] c_state ;
reg [:] n_state ;
wire [:] row_1;
wire write_flag;
//wire [127:0] row_2;
assign row_1 ="i am liu xiao yi" ;
//assign row_2 ="happy everyday !";
//----------------------------------------------------------------------
//initialize
//first step is waitng more than 20 ms.
parameter TIME_20MS = 1000_000 ; //20000000/20=1000_000
//parameter TIME_15MS = 9'h100 ; //just for test
parameter TIME_500HZ= 100_000 ; //
//parameter TIME_500HZ= 4'hf; //just for test
//use gray code 这里本来用的是格雷码,但是由于增添了两个状态,就随机写了f1,f2这两个数字。
parameter IDLE= 'h00 ;
parameter SET_FUNCTION= 'h01 ;
parameter DISP_OFF= 'h03 ;
parameter DISP_CLEAR= 'h02 ;
parameter ENTRY_MODE= 'h06 ;
parameter DISP_ON = 'h07 ;
parameter ROW1_ADDR= 'h05 ;
//----------------------修改1,增添这两个状态
parameter CGRAM_ADDR = 'hf1;
parameter CGRAM_DATA = 'hf2;
//-----------------------
parameter ROW1_0= 'h04 ;
parameter ROW1_1= 'h0C ;
parameter ROW1_2= 'h0D ;
parameter ROW1_3= 'h0F ;
parameter ROW1_4= 'h0E ;
parameter ROW1_5= 'h0A ;
parameter ROW1_6= 'h0B ;
parameter ROW1_7= 'h09 ;
parameter ROW1_8= 'h08 ;
parameter ROW1_9= 'h18 ;
parameter ROW1_A= 'h19 ;
parameter ROW1_B= 'h1B ;
parameter ROW1_C= 'h1A ;
parameter ROW1_D= 'h1E ;
parameter ROW1_E= 'h1F ;
parameter ROW1_F= 'h1D ; parameter ROW2_ADDR= 'h1C ;
parameter ROW2_0= 'h14 ;
parameter ROW2_1= 'h15 ;
parameter ROW2_2= 'h17 ;
parameter ROW2_3= 'h16 ;
parameter ROW2_4= 'h12 ;
parameter ROW2_5= 'h13 ;
parameter ROW2_6= 'h11 ;
parameter ROW2_7= 'h10 ;
parameter ROW2_8= 'h30 ;
parameter ROW2_9= 'h31 ;
parameter ROW2_A= 'h33 ;
parameter ROW2_B= 'h32 ;
parameter ROW2_C= 'h36 ;
parameter ROW2_D= 'h37 ;
parameter ROW2_E= 'h35 ;
parameter ROW2_F= 'h34 ; reg [:] cnt_20ms ;
always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
cnt_20ms<=;
end
else if(cnt_20ms == TIME_20MS -)begin
cnt_20ms<=cnt_20ms;
end
else
cnt_20ms<=cnt_20ms + ;
end
wire delay_done = (cnt_20ms==TIME_20MS-)? 'b1 : 1'b0 ;
//----------------------------------------------------------------------
//500ns lcd1602工作在500HZ,因此此处要分频
reg [:] cnt_500hz;
always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
cnt_500hz <= ;
end
else if(delay_done==)begin
if(cnt_500hz== TIME_500HZ - )
cnt_500hz<=;
else
cnt_500hz<=cnt_500hz + ;
end
else
cnt_500hz<=;
end assign lcd_en = (cnt_500hz>(TIME_500HZ-)/)? 'b0 : 1'b1; //下降沿
assign write_flag = (cnt_500hz==TIME_500HZ - ) ? 'b1 : 1'b0 ; //set_function ,display off ,display clear ,entry mode set
//----------------------------------------------------------------------
always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
c_state <= IDLE ;
end
else if(write_flag==) begin
c_state<= n_state ;
end
else
c_state<=c_state ;
end //-------------------------修改2 因为自定义一个汉字需要写8次地址并且给8次数据,所以用num和num1来控制。
reg [:]num,num1;
always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
num<=;
end
else if(c_state== CGRAM_ADDR&&write_flag) begin
if(num==)
num<=;
else
num<=num+'b1;
end
else
num<=num;
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
num1<=;
end
else if(c_state== CGRAM_DATA&&write_flag) begin
if(num1==)
num1<=;
else
num1<=num1+'b1;
end
else
num1<=num1;
end //------------------------------------------------------------ always @(*)begin
case (c_state)
IDLE: n_state = SET_FUNCTION ;
SET_FUNCTION: n_state = DISP_OFF ;
DISP_OFF: n_state = DISP_CLEAR ;
DISP_CLEAR: n_state = ENTRY_MODE ;
ENTRY_MODE: n_state = DISP_ON ;
DISP_ON : n_state = CGRAM_ADDR ;
//------------------------------------------------ 修改3 当8个数据都写进相应地址里的时候,状态机才跳到ROW1_ADDR状态
CGRAM_ADDR: n_state = CGRAM_DATA ; // 8'hfe;
CGRAM_DATA: if(num1==)
n_state = ROW1_ADDR;
else
n_state= CGRAM_ADDR;
//------------------------------------------------
ROW1_ADDR: n_state = ROW1_0 ;
ROW1_0: n_state = ROW1_1 ;
ROW1_1: n_state = ROW1_2 ;
ROW1_2: n_state = ROW1_3 ;
ROW1_3: n_state = ROW1_4 ;
ROW1_4: n_state = ROW1_5 ;
ROW1_5: n_state = ROW1_6 ;
ROW1_6: n_state = ROW1_7 ;
ROW1_7: n_state = ROW1_8 ;
ROW1_8: n_state = ROW1_9 ;
ROW1_9: n_state = ROW1_A ;
ROW1_A: n_state = ROW1_B ;
ROW1_B: n_state = ROW1_C ;
ROW1_C: n_state = ROW1_D ;
ROW1_D: n_state = ROW1_E ;
ROW1_E: n_state = ROW1_F ;
ROW1_F: n_state = ROW2_ADDR ; ROW2_ADDR: n_state = ROW2_0 ;
ROW2_0: n_state = ROW2_1 ;
ROW2_1: n_state = ROW2_2 ;
ROW2_2: n_state = ROW2_3 ;
ROW2_3: n_state = ROW2_4 ;
ROW2_4: n_state = ROW2_5 ;
ROW2_5: n_state = ROW2_6 ;
ROW2_6: n_state = ROW2_7 ;
ROW2_7: n_state = ROW2_8 ;
ROW2_8: n_state = ROW2_9 ;
ROW2_9: n_state = ROW2_A ;
ROW2_A: n_state = ROW2_B ;
ROW2_B: n_state = ROW2_C ;
ROW2_C: n_state = ROW2_D ;
ROW2_D: n_state = ROW2_E ;
ROW2_E: n_state = ROW2_F ;
ROW2_F: n_state = ROW1_ADDR ;
default: n_state = n_state ;
endcase
end assign lcd_rw = ;
always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
lcd_rs <= ; //order or data 0: order 1:data
end
else if(write_flag == )begin
if((n_state==SET_FUNCTION)||(n_state==DISP_OFF)||
(n_state==DISP_CLEAR)||(n_state==ENTRY_MODE)||
(n_state==DISP_ON ) ||(n_state==ROW1_ADDR)||
(n_state==ROW2_ADDR)||(n_state==CGRAM_ADDR))begin //修改4
lcd_rs<= ;
end
else begin
lcd_rs<= ;
end
end
else begin
lcd_rs<=lcd_rs;
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
lcd_data<= ;
end
else if(write_flag)begin
case(n_state) IDLE: lcd_data <= 'hxx;
SET_FUNCTION: lcd_data <= 'h38; //2*16 5*8 8位数据
DISP_OFF: lcd_data <= 'h08;
DISP_CLEAR: lcd_data <= 'h01;
ENTRY_MODE: lcd_data <= 'h06;
DISP_ON : lcd_data <= 'h0c; //显示功能开,没有光标,且不闪烁,
// ------------------------------------修改5
CGRAM_ADDR: begin
case(num)
: lcd_data <= 'h40;
: lcd_data <= 'h41;
: lcd_data <= 'h42;
: lcd_data <= 'h43;
: lcd_data <= 'h44;
: lcd_data <= 'h45;
: lcd_data <= 'h46;
: lcd_data <= 'h47;
endcase
end CGRAM_DATA: begin
case(num1)
: lcd_data <= 'h04;
: lcd_data <= 'h1f;
: lcd_data <= 'h15;
: lcd_data <= 'h1f;
: lcd_data <= 'h15;
: lcd_data <= 'h1f;
: lcd_data <= 'h04;
: lcd_data <= 'h07;
endcase
end
//-------------------------------------修改6第一行显示 i am liu xiao yi 第二行全部显示汉字电
ROW1_ADDR: lcd_data <= 'h80; //00+80
ROW1_0: lcd_data <= row_1 [:];
ROW1_1: lcd_data <= row_1 [:];
ROW1_2: lcd_data <= row_1 [:];
ROW1_3: lcd_data <= row_1 [: ];
ROW1_4: lcd_data <= row_1 [ : ];
ROW1_5: lcd_data <= row_1 [ : ];
ROW1_6: lcd_data <= row_1 [ : ];
ROW1_7: lcd_data <= row_1 [ : ];
ROW1_8: lcd_data <= row_1 [ : ];
ROW1_9: lcd_data <= row_1 [ : ];
ROW1_A: lcd_data <= row_1 [ : ];
ROW1_B: lcd_data <= row_1 [ : ];
ROW1_C: lcd_data <= row_1 [ : ];
ROW1_D: lcd_data <= row_1 [ : ];
ROW1_E: lcd_data <= row_1 [ : ];
ROW1_F: lcd_data <= row_1 [ : ]; ROW2_ADDR: lcd_data <= 'hc0; //40+80
ROW2_0: lcd_data <='h00; //电
ROW2_1: lcd_data <='h00;
ROW2_2: lcd_data <='h00;
ROW2_3: lcd_data <='h00;
ROW2_4: lcd_data <='h00;
ROW2_5: lcd_data <='h00;
ROW2_6: lcd_data <='h00;
ROW2_7: lcd_data <='h00;
ROW2_8: lcd_data <='h00;
ROW2_9: lcd_data <='h00;
ROW2_A: lcd_data <='h00;
ROW2_B: lcd_data <='h00;
ROW2_C: lcd_data <='h00;
ROW2_D: lcd_data <='h00;
ROW2_E: lcd_data <='h00;
ROW2_F: lcd_data <='h00;
endcase
end
else
lcd_data<=lcd_data ;
end endmodule
4、显示结果

转载请注明出处:http://www.cnblogs.com/aslmer/p/5819868.html
lcd1602如何自定义汉字(verilog)的更多相关文章
- LCD1602显示中文汉字
小子在西藏 2011-11-25编写 特别说明笔者是上面的作者,感谢那些原意分享知识的人.时隔5年我又看到了笔者当年写的东西,我想这期间还有许许多多的人 今天写在博客上,愿更多后来者可以学习. LCD ...
- LCD1602写自定义字符的Verilog源码
开发工具:Quartus II 9.1: 仿真软件:Questa Sim 10.0c: 硬件平台:Terasic DE2-115(EP2C35F672C6): 外设:hd44780控制器lcd1602 ...
- [FPGA]浅谈LCD1602字符型液晶显示器(Verilog)
目录 概述 LCD1602 LCD1602是什么? LCD1602的管脚 RS_数据/命令选择 E_使能 D0-D7 LCD1602有个DDRAM LCD1602还有个CGROM 指令集 清屏 进入模 ...
- verilog写的LCD1602 显示
在读本文之前,请先阅读 LCD1602 的 datasheet(百度到处都是) ,熟悉有关的11条指令集. LCD1602的11个指令集链接 http://www.cnblogs.com/aslmer ...
- [FPGA] Verilog 燃气灶控制器的设计与实现
燃气灶控制器的设计与实现 一.引述 本次实验所用可编程器件型号为MAXII EPM1270T144C5(其引脚表见本人另一博文:可编程实验板EPM1270T144C5使用说明),通过可编程实验板实现一 ...
- Atiti attilax主要成果与解决方案与案例rsm版 v4
Atiti attilax主要成果与解决方案与案例rsm版 v4 版本历史记录1 1. ##----------主要成果与解决方案与 参与项目1 ###开发流程与培训系列1 #-----组织运营与文 ...
- Atiti attilax主要成果与解决方案与案例rsm版 v2
Atiti attilax主要成果与解决方案与案例rsm版 v2 1. ##----------主要成果与解决方案与 参与项目1 ###开发流程与培训系列1 #-----组织运营与文化建设系列1 # ...
- Atiti attilax主要成果与解决方案与案例rsm版
Atiti attilax主要成果与解决方案与案例rsm版 1. ##----------主要成果与解决方案与 参与项目1 ###开发流程系列1 ###架构系列 (au1 ###编程语言系列与架构系 ...
- iOS-高仿通讯录之商品索引排序搜索
概述 TableView添加右侧索引, 将数据按照索引分组排序, 并添加搜索功能且在搜索界面复用当前页面. 详细 代码下载:http://www.demodashi.com/demo/10696.ht ...
随机推荐
- [转]C#中StreamReader读取中文出现乱码
摘自:C#中StreamReader读取中文出现乱码 原因是自Windows 2000之后的操作系统在文件处理时默认编码采用Unicode所以.NET文件的默认编码也是Unicode.除非另外指定,S ...
- 安装express
就目前来说安装express需要走几个步骤,要不就会出现在检查版本的时候就会出现,expres不是内部的命令或者是这种 安装的步骤: 1. 先是输入npm install -g express-gen ...
- CSS样式表优化
前几天公司要模仿一家客户的网站模板来为另一客户新建一个模板,说白了就是换个数据源,然后样式表再小修小改一下就行了.但通过浏览器控制台下载素材时,发现这个网站开发的挺专业的,单就样式表而言,代码工整,注 ...
- Android(java)学习笔记94: SurfaceView使用
1. SurfaceView简介 在一般的情况下,应用程序的View都是在相同的GUI线程(UI主线程)中绘制的.这个主应用程序线程同时也用来处理所有的用户交互(例如,按钮单击或者文本输入). ...
- Unix系统中常用的信号含义
http://blog.csdn.net/u012349696/article/details/50687462 编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ...
- modprobe与insmod的区别
linux设备驱动有两种加载方式insmod和modprobe,下面谈谈它们用法上的区别1.insmod一次只能加载特定的一个设备驱动,且需要驱动的具体地址.写法为: insmod dr ...
- 网络编程——TCP协议和通信
第1章 TCP通信 TCP通信同UDP通信一样,都能实现两台计算机之间的通信,通信的两端都需要创建socket对象. 区别在于,UDP中只有发送端和接收端,不区分客户端与服务器端,计算机之间可以任意地 ...
- HTML第四章:初始css
CSS样式: 一.为什么要使用CSS;可以让页面更美观.有利于开发速度. 二.什么是CSS:全称cascading style shee ...
- JT∕T 905 -2014 出租汽车服务管理信息系统的相关协议研究
出租汽车服务管理信息系统(JT∕T 905 -2014) 国家的相关技术要求2014年7月正式出台,总体有四部分, 第 1 部分:总体技术要求: 第 2 部分:运营专用设备: 第 3 部分 ...
- Mycat高可用解决方案三(读写分离)
Mycat高可用解决方案三(读写分离) 一.系统部署规划 名称 IP 主机名称 配置 192.168.199.112 mycat01 2核/2G Mysql主节点 192.168.199.110 my ...