这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 交LCD12864 篇显示汉字作业

共3条 1/1 1 跳转至

交LCD12864 篇显示汉字作业

助工
2014-07-31 22:17:26     打赏

终于要把LCD12864篇显示汉字的作业交了,源代码如下:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: Charles Wang 
// 
// Create Date:    07/20/2014 
// Design Name: 	lcd12864
// Module Name:   lcd12864
// Project Name: 	lcd12864
// Target Devices: EP4CE6E22C8
// Tool versions: Quartus II 13.1 & Modelsim 10.0c SE 
// Description: 用LCD12864 显示汉字
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//			
//////////////////////////////////////////////////////////////////////////////////
module lcd12864_ch(clk,rst_n,lcd12864_en,lcd12864_rs,lcd12864_rw,lcd12864_data);
input clk;//50Mhz 总线时钟
input rst_n;//异步复位,低电平有效

output lcd12864_en;//LCD12864 使能端
output lcd12864_rs;//LCD12864 片选,低电平指令,高电平数据
output lcd12864_rw;//读写信号输出端,这里只有写的动作,电平一直为0
output [7:0]lcd12864_data;//8位数据端口
//寄存器及wire 定义
reg lcd12864_rs;
reg [7:0]lcd12864_data;
reg [22:0]div_cnt;
reg [8:0]state;
reg [5:0] word_cnt;
reg [7:0]showdata;
wire lcd12864_en;
wire div_clk;
//////////////////////////////////////////////////////////////////////////////////
///////////////////////////////50Mhz → 1Hz///////////////////////////////////////
always@(posedge clk or negedge rst_n)//50Mhz → 1Hz
	begin
		if(!rst_n)
			div_cnt <= 23'd0;
		else
			div_cnt <= div_cnt + 1'b1;
	end
assign div_clk = (div_cnt == 23'd4999999);
/////////////////////////////////////////////////////////////////////////////////
///////////////////////////////状态机定义/////////////////////////////////////////
parameter 	            idle 	 = 9'b0_0000_0001,
			    setbase_h    = 9'b0_0000_0010,
			    setbase_l    = 9'b0_0000_0100,
			    setdisp      = 9'b0_0000_1000,
			    clear     	 = 9'b0_0001_0000,
			    setmode      = 9'b0_0010_0000,
			    wr_addr      = 9'b0_0100_0000,
			    wr_data	 = 9'b0_1000_0000,
			    stop_here    = 9'b1_0000_0000;
assign lcd12864_rw = 1'b0;
assign lcd12864_en =div_clk;
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////状态转移描述//////////////////////////////////////
always@(posedge div_clk or negedge rst_n )
  begin
    if(!rst_n)
      lcd12864_rs <= 1'b0;
    else if(state == wr_data)
      lcd12864_rs <= 1'b1;
    else
      lcd12864_rs <= 1'b0;
  end
always@(posedge div_clk or negedge rst_n)
begin
	if(!rst_n)
		begin
		word_cnt	<= 6'd0;
		lcd12864_data 	<= 8'hzz;//lcd12864_data 默认高阻
		state		<= idle;
		end
	else
	begin
	case(state)
		idle: 
			begin
				lcd12864_data 	<= 8'hzz;
				state 		<=	setbase_h;
			end
///////////////////////////////设定8bit MPU 接口,基本指令集///////////////////////////
		setbase_h:
			begin
				state		<= setbase_l;
				lcd12864_data	<= 8'h30;
			end
		setbase_l:
			begin
				state		<=	setdisp;
				lcd12864_data	<= 8'h30;
			end
//////////////////////////////显示开关设置//////////////////////////////////////////
		setdisp:
			begin
				state		<= clear;
				lcd12864_data	<= 8'h0c;
			end
//////////////////////////////////清屏////////////////////////////////////////////
		clear:
			begin
				state		<= setmode;
				lcd12864_data	<= 8'h01;
			end
/////////////设置设定点,游标右移,DDRAM 地址计数器(AC)加 1///////////////////////////
		setmode:
			begin
				state		<= wr_addr;
				lcd12864_data	<= 8'h06;
			end
///////////////////////////////写汉字数据到LCD////////////////////////////////////
		wr_addr:
			begin
				state		<= wr_data;
				if(word_cnt == 6'd0)
					lcd12864_data	<= 8'h80;//第一行
				else if(word_cnt == 6'd16)
					lcd12864_data	<= 8'h90;//第二行
				else if(word_cnt == 6'd28)
					lcd12864_data	<= 8'h88;//第三行
				else if(word_cnt == 6'd44)
					lcd12864_data	<= 8'h98;//第四行
			end
		wr_data:
			begin
				if(word_cnt >= 6'd0 && word_cnt <= 6'd15)
					begin
						word_cnt 	<= word_cnt + 1'b1;
						lcd12864_data	<= showdata;
					if(word_cnt == 6'd15)
						state		<= wr_addr;
					else
						state		<= wr_data;
					end
				else if(word_cnt >= 6'd16 && word_cnt <= 6'd27)
					begin
						word_cnt	<= word_cnt + 1'b1;
						lcd12864_data	<= showdata;
					if(word_cnt == 6'd27)
						state		<= wr_addr;
					else
						state		<= wr_data;
					end
				else if(word_cnt >=6'd28 && word_cnt <= 6'd43)
					begin
						word_cnt	<= word_cnt	+ 1'b1;
						lcd12864_data	<= showdata;
					if(word_cnt == 6'd43)
						state	<= wr_addr;
					else
						state	<= wr_data;
					end
				else if(word_cnt >=6'd44 && word_cnt <= 6'd57)
					begin
						word_cnt	<= word_cnt	+ 1'b1;
						lcd12864_data	<= showdata;
					if(word_cnt == 6'd57)
						begin
							state   <= stop_here;
							word_cnt<= 6'd0;
						end
					else
						begin
							state	<= wr_data;
							word_cnt<= word_cnt	+ 1'b1;
						end
					end
			end
		stop_here:
			begin
				state	<= stop_here;
			end
		default:
				state	<= idle;
	endcase
	end
end
always@(word_cnt)
	begin
		case(word_cnt)
		
			6'd0:	showdata 	<= 8'hC8;
			6'd1:	showdata 	<= 8'hE7;//"如"
			6'd2:	showdata	<= 8'hB9;
			6'd3: 	showdata	<= 8'hFB;//"果"
			6'd4: 	showdata	<= 8'hC4;
			6'd5: 	showdata	<= 8'hE3;//"你"
			6'd6: 	showdata	<= 8'hCF;
			6'd7: 	showdata	<= 8'hEB;//"想"
			6'd8: 	showdata	<= 8'hD3;
			6'd9: 	showdata	<= 8'hB5;//"拥"
			6'd10: 	showdata	<= 8'hD3;
			6'd11: 	showdata	<= 8'hD0;//"有"
			6'd12: 	showdata	<= 8'hC4;
			6'd13: 	showdata	<= 8'hE3;//"你"
			6'd14: 	showdata	<= 8'hB4;
			6'd15: 	showdata	<= 8'hD3;//"从"
			
			6'd16: 	showdata	<= 8'hCE;
			6'd17: 	showdata	<= 8'hB4;//"未"
			6'd18:	showdata	<= 8'hD3;
			6'd19:	showdata	<= 8'hD0;//"有"
			6'd20:	showdata	<= 8'hB9;
			6'd21:	showdata	<= 8'hFD;//"过"
			6'd22:	showdata	<= 8'hB5;
			6'd23:	showdata	<= 8'hC4;//"的"
			6'd24:	showdata	<= 8'hB6;
			6'd25:	showdata	<= 8'hAB;//"东"
			6'd26:	showdata	<= 8'hCE;
			6'd27:	showdata	<= 8'hF7;//"西"

			6'd28:	showdata	<= 8'hC4;
			6'd29:	showdata	<= 8'hC7;//"那"
			6'd30:	showdata	<= 8'hC3;
			6'd31:	showdata	<= 8'hB4;//"么"
			6'd32:	showdata	<= 8'hC4;
			6'd33:	showdata	<= 8'hE3;//"你"
			6'd34: 	showdata 	<= 8'hB1;
			6'd35:	showdata	<= 8'hD8;//"必"
			6'd36:	showdata	<= 8'hD0;
			6'd37:	showdata	<= 8'hEB;//"须"
			6'd38: 	showdata	<= 8'hC8;
			6'd39:	showdata	<= 8'hA5;//"去"
			6'd40:	showdata	<= 8'hD7;
			6'd41:	showdata	<= 8'hF6;//"做"
			6'd42:	showdata	<= 8'hC4;
			6'd43:	showdata	<= 8'hE3;//"你"
			
			6'd44:	showdata	<= 8'hB4;
			6'd45:	showdata	<= 8'hD3;//"从"
			6'd46:	showdata	<= 8'hCE;
			6'd47:	showdata	<= 8'hB4;//"未"
			6'd48:	showdata	<= 8'hD7;
			6'd49:	showdata	<= 8'hF6;//"做"
			6'd50:	showdata	<= 8'hB9;
			6'd51:	showdata	<= 8'hFD;//"过"
			6'd52:	showdata	<= 8'hB5;
			6'd53:	showdata	<= 8'hC4;//"的"
			6'd54:	showdata	<= 8'hCA;
			6'd55:	showdata	<= 8'hC2;//"事"
			6'd56:	showdata	<= 8'hC7;
			6'd57:	showdata	<= 8'hE9;//"情"
			default: showdata	<= 8'hzz;
		endcase
	end				
endmodule
testbench 代码如下:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: Charles Wang 
// 
// Create Date:    07/22/2014 
// Design Name: 	lcd12864_tb
// Module Name:         lcd12864_tb
// Project Name: 	lcd12864_tb
// Target Devices: EP4CE6E22C8
// Tool versions: Quartus II 13.1 & Modelsim 10.0C SE
// Description: ?LCD12864 ?????????
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//			
//////////////////////////////////////////////////////////////////////////////////
module lcd12864_tb();
  reg clk;
  reg rst_n;
  wire lcd12864_en;
  wire lcd12864_rw;
  wire lcd12864_rs;
  wire [7:0]lcd12864_data;
//////////////////////////////////////////////////////////////////////////////////
lcd12864_ch LCD(.clk(clk),.rst_n(rst_n),.lcd12864_en(lcd12864_en),
.lcd12864_rw(lcd12864_rw),.lcd12864_rs(lcd12864_rs),.lcd12864_data(lcd12864_data));
initial
  begin
    clk   = 1'b0;
    rst_n = 1'b0;
    #20 rst_n = 1'b1;
    #10 forever
    #10 clk = ~clk;
end
endmodule

 


效果如下:
 

 





关键词: LCD12864     汉字     作业    

助工
2014-07-31 22:41:53     打赏
2楼

这次做LCD12864显示汉字,折腾了很多天,自己总结了三种可以显示汉字的方法,仅供参考:

1. 用128x64的单色图片,在图片中用绘图工具写好16x16(2个字节)的汉字,然后用51大大提供的取模工具取模,再用Keil 编译生成.hex 文件,之后在51大大的源代码中的显示即可,缺点就是复杂不易修改成之后自己想要的文字

2. 用51大大提供的取模工具进行字符取模,取模之后要注意,比如“如”这个字得到的字模是这样的:



{0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x7C,0xFE,0x44,0x22,0x44,0x22,0x44,0x22,0x44},
{0x42,0x44,0x24,0x44,0x14,0x44,0x08,0x44,0x14,0x44,0x22,0x7C,0x42,0x44,0x80,0x00},/*"如",0*/
要把改成:

0x10,0x00,
0x10,0x00,
0x10,0x00,
0x10,0x7C,
0xFE,0x44,
0x22,0x44,
0x22,0x44,
0x22,0x44,

.

.

.

0x80,0x00

然后在keil上生成.hex文件,这样才能能在51大大源代码中显示出“如”这个字,至于为什么这样,我就不说了,大家都比我聪明,这种方法很笨,而且更复杂,变更新的汉字也很麻烦

3. 就是用ST7920自带的字库,具体做法如上代码。这种方法的有点就不多说了,哈哈

以上三种,自己亲试都是可行的,当然只是分享一下自己的经历,可能很多童鞋都比我聪明,我是一个一个做过来,所以走了些弯路

顺便分享一个汉字转16进制字符工具:汉字十六进制转换工具.zip


助工
2014-07-31 22:45:22     打赏
3楼
下一站就是VGA 了,自己笨,只能慢慢来,破茧成蝶,总是痛苦的,各位看官,您说是吧?

共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]