首页 > 代码库 > lcd1602如何自定义汉字(verilog)
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 。
3、在上篇文章的基础上修改代码如下:
难点就在状态机的控制,重点修改部分都用红色标注
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 [7:0] lcd_data;wire clk ;wire rst_n ;wire lcd_en ;wire lcd_rw;reg [7:0] lcd_data;reg lcd_rs ;reg [7:0] c_state ;reg [7:0] n_state ;wire [127:0] 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_15MS = 1000_000 ; //20000000/20=1000_000//parameter TIME_15MS = 9‘h100 ; //just for testparameter TIME_500HZ= 100_000 ; ////parameter TIME_500HZ= 4‘hf; //just for test//use gray codeparameter IDLE= 8‘h00 ; parameter SET_FUNCTION= 8‘h01 ;parameter DISP_OFF= 8‘h03 ;parameter DISP_CLEAR= 8‘h02 ;parameter ENTRY_MODE= 8‘h06 ;parameter DISP_ON = 8‘h07 ;parameter ROW1_ADDR= 8‘h05 ;//----------------------修改1,增添这两个状态parameter CGRAM_ADDR = 8‘hf1;parameter CGRAM_DATA = http://www.mamicode.com/8‘hf2;//-----------------------parameter ROW1_0= 8‘h04 ;parameter ROW1_1= 8‘h0C ;parameter ROW1_2= 8‘h0D ;parameter ROW1_3= 8‘h0F ;parameter ROW1_4= 8‘h0E ;parameter ROW1_5= 8‘h0A ;parameter ROW1_6= 8‘h0B ;parameter ROW1_7= 8‘h09 ;parameter ROW1_8= 8‘h08 ;parameter ROW1_9= 8‘h18 ;parameter ROW1_A= 8‘h19 ;parameter ROW1_B= 8‘h1B ;parameter ROW1_C= 8‘h1A ;parameter ROW1_D= 8‘h1E ;parameter ROW1_E= 8‘h1F ;parameter ROW1_F= 8‘h1D ;parameter ROW2_ADDR= 8‘h1C ;parameter ROW2_0= 8‘h14 ;parameter ROW2_1= 8‘h15 ;parameter ROW2_2= 8‘h17 ;parameter ROW2_3= 8‘h16 ;parameter ROW2_4= 8‘h12 ;parameter ROW2_5= 8‘h13 ;parameter ROW2_6= 8‘h11 ;parameter ROW2_7= 8‘h10 ;parameter ROW2_8= 8‘h30 ;parameter ROW2_9= 8‘h31 ;parameter ROW2_A= 8‘h33 ;parameter ROW2_B= 8‘h32 ;parameter ROW2_C= 8‘h36 ;parameter ROW2_D= 8‘h37 ;parameter ROW2_E= 8‘h35 ;parameter ROW2_F= 8‘h34 ;reg [19:0] cnt_15ms ;always @(posedge clk or negedge rst_n)begin if(rst_n==1‘b0)begin cnt_15ms<=0; end else if(cnt_15ms == TIME_15MS -1)begin cnt_15ms<=cnt_15ms; end else cnt_15ms<=cnt_15ms + 1 ;endwire delay_done = (cnt_15ms==TIME_15MS-1)? 1‘b1 : 1‘b0 ;//----------------------------------------------------------------------//500nsreg [19:0] cnt_500hz;always @(posedge clk or negedge rst_n)begin if(rst_n==1‘b0)begin cnt_500hz <= 0; end else if(delay_done==1)begin if(cnt_500hz== TIME_500HZ - 1) cnt_500hz<=0; else cnt_500hz<=cnt_500hz + 1 ; end else cnt_500hz<=0;endassign lcd_en = (cnt_500hz>(TIME_500HZ-1)/2)? 1‘b0 : 1‘b1; //下降沿assign write_flag = (cnt_500hz==TIME_500HZ - 1) ? 1‘b1 : 1‘b0 ;//set_function ,display off ,display clear ,entry mode set//----------------------------------------------------------------------always @(posedge clk or negedge rst_n)begin if(rst_n==1‘b0)begin c_state <= IDLE ; end else if(write_flag==1) begin c_state<= n_state ; end else c_state<=c_state ;end//-------------------------修改2 因为自定义一个汉字需要写8次地址并且给8次数据,所以用num和num1来控制。reg [2:0]num,num1;always @(posedge clk or negedge rst_n)begin if(rst_n==1‘b0)begin num<=0; end else if(c_state== CGRAM_ADDR&&write_flag) begin if(num==7) num<=0; else num<=num+8‘b1; end else num<=num;endalways @(posedge clk or negedge rst_n)begin if(rst_n==1‘b0)begin num1<=0; end else if(c_state== CGRAM_DATA&&write_flag) begin if(num1==7) num1<=0; else num1<=num1+8‘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==7) 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 = 0; always @(posedge clk or negedge rst_n)begin if(rst_n==1‘b0)begin lcd_rs <= 0 ; //order or data 0: order 1:data end else if(write_flag == 1)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<=0 ; end else begin lcd_rs<= 1; end end else begin lcd_rs<=lcd_rs; end end always @(posedge clk or negedge rst_n)begin if(rst_n==1‘b0)begin lcd_data<=0 ; end else if(write_flag)begin case(n_state) IDLE: lcd_data <= 8‘hxx; SET_FUNCTION: lcd_data <= 8‘h38; //2*16 5*8 8位数据 DISP_OFF: lcd_data <= 8‘h08; DISP_CLEAR: lcd_data <= 8‘h01; ENTRY_MODE: lcd_data <= 8‘h06; DISP_ON : lcd_data <= 8‘h0c; //显示功能开,没有光标,且不闪烁,// ------------------------------------修改5 CGRAM_ADDR: begin case(num) 0: lcd_data <= 8‘h40; 1: lcd_data <= 8‘h41; 2: lcd_data <= 8‘h42; 3: lcd_data <= 8‘h43; 4: lcd_data <= 8‘h44; 5: lcd_data <= 8‘h45; 6: lcd_data <= 8‘h46; 7: lcd_data <= 8‘h47; endcase end CGRAM_DATA: begin case(num1) 0: lcd_data <= 8‘h04; 1: lcd_data <= 8‘h1f; 2: lcd_data <= 8‘h15; 3: lcd_data <= 8‘h1f; 4: lcd_data <= 8‘h15; 5: lcd_data <= 8‘h1f; 6: lcd_data <= 8‘h04; 7: lcd_data <= 8‘h07; endcase end //-------------------------------------修改6第一行显示 i am liu xiao yi 第二行全部显示汉字电 ROW1_ADDR: lcd_data <= 8‘h80; //00+80 ROW1_0: lcd_data <= row_1 [127:120]; ROW1_1: lcd_data <= row_1 [119:112]; ROW1_2: lcd_data <= row_1 [111:104]; ROW1_3: lcd_data <= row_1 [103: 96]; ROW1_4: lcd_data <= row_1 [ 95: 88]; ROW1_5: lcd_data <= row_1 [ 87: 80]; ROW1_6: lcd_data <= row_1 [ 79: 72]; ROW1_7: lcd_data <= row_1 [ 71: 64]; ROW1_8: lcd_data <= row_1 [ 63: 56]; ROW1_9: lcd_data <= row_1 [ 55: 48]; ROW1_A: lcd_data <= row_1 [ 47: 40]; ROW1_B: lcd_data <= row_1 [ 39: 32]; ROW1_C: lcd_data <= row_1 [ 31: 24]; ROW1_D: lcd_data <= row_1 [ 23: 16]; ROW1_E: lcd_data <= row_1 [ 15: 8]; ROW1_F: lcd_data <= row_1 [ 7: 0]; ROW2_ADDR: lcd_data <= 8‘hc0; //40+80 ROW2_0: lcd_data <=8‘h00; //电 ROW2_1: lcd_data <=8‘h00; ROW2_2: lcd_data <=8‘h00; ROW2_3: lcd_data <=8‘h00; ROW2_4: lcd_data <=8‘h00; ROW2_5: lcd_data <=8‘h00; ROW2_6: lcd_data <=8‘h00; ROW2_7: lcd_data <=8‘h00; ROW2_8: lcd_data <=8‘h00; ROW2_9: lcd_data <=8‘h00; ROW2_A: lcd_data <=8‘h00; ROW2_B: lcd_data <=8‘h00; ROW2_C: lcd_data <=8‘h00; ROW2_D: lcd_data <=8‘h00; ROW2_E: lcd_data <=8‘h00; ROW2_F: lcd_data <=8‘h00; endcase end else lcd_data<=lcd_data ; endendmodule
4、显示结果
转载请注明出处:http://www.cnblogs.com/aslmer/p/5819868.html
lcd1602如何自定义汉字(verilog)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。