求助——Verilog 写的LCD12864 模块
这几天用Verilog写了一个LCD12864模块,调试几天,还是不工作,如有高手看到,请指教:module LCD12864(
input clk,
input reset,
output reg rs,
output rw,
output en,
output reg date,
output rst
);
reg clk_lcd;
reg count;
reg flag; //LCD操作完毕,释放其控制
always@(posedge clk or negedge reset) //50Mhz TO 100khz
begin
if(!reset)
begin
count<=25'b0;
clk_lcd<=0;
end
else if(count==25'hf4240) //
begin
count<=25'b0;
clk_lcd<=~clk_lcd;
end
elsecount<=count+25'b1;
end
reg state; //state machine code
parameter idle=9'b00000_0000; //initial,next is clear
parameter setfunction=9'b00000_0001; //set function ,8-bits date
parameter setfunction2=9'b00000_0010;
parameter setfunction3=9'b00000_0100;
parameter switchmode=9'b00000_1000; //显示开关控制:开显示,光标和闪烁关闭
parameter clear=9'b00001_0000;
parameter setmode=9'b00010_0000; //输入方式设置:数据读写操作后,地址自动加一/画面不动
parameter setddram=9'b00100_0000; //设置DDRAM的地址:第一行起始为0x80/第二行为0x90
parameter writeram=9'b01000_0000; //数据写入DDRAM相应的地址
parameter stop=9'b10000_0000; //LCD操作完毕,释放其控制
parameter message="项目名称: 声强仪功能介绍: 设计人: 第五组日期:2011.04.21 ";
reg message1;
reg char_cnt;
reg date_disp;
assign rw=1'b0; //没有读操作,R/W信号始终为低电平
assign en=(flag==1)?clk_lcd:1'b0; //E信号出现高电平以及下降沿的时刻与LCD时钟相同
always@(posedge clk_lcd or negedge rst)
begin
if(!rst)
begin
rs<=1'b0;
end
else if(state==writeram)
begin rs<=1'b1; end
elsers<=1'b0;
end
// state machine
always @(posedge clk_lcd or negedge rst)
begin
if(!rst)
begin
state<=idle;
date<=8'bxxxxxxxx;
char_cnt<=5'b0;
flag<=1'b1;
message1<=message;
end
else begin
case(state)
idle:begin
state<=setfunction;
date<=8'h30;
end
setfunction: begin
state<=setfunction2;
date<=8'h08; // 8-bit 控制界面,基本指令集动作
end
setfunction2: begin
state<= setfunction3;
date<=8'h10;
end
setfunction3: begin
state<=clear;
date<=8'h0c;// 显示开关:开显示,光标和闪烁关闭
end
clear:begin
state<=switchmode;
date<=8'h01;
end
switchmode:begin
state<=setddram;
date<=8'h06;//输入方式设置: 数据读写后,地址自动加1,画面不动
end
setddram:begin
state<=writeram;
if(char_cnt==0) //如果显示的是第一个字符,则设置第一行的首字符地址
begin
date<=8'h80; //Line1
end
else if(char_cnt==16) begin
date<=8'h90; //line2
end
else if(char_cnt==32) begin
date<=8'h88;
end
else if(char_cnt==48) begin
date<=8'h98;
end
end
writeram:begin
if((char_cnt==16)|(char_cnt==32)|(char_cnt==48))
beginstate<=setddram;end
else if(char_cnt==64)
beginchar_cnt<=0; end
else
begin
date_disp<=message1;
message1<=(message1<<8);
char_cnt<=char_cnt+1'b1;
state<=writeram;
end
end
stop:begin
state<=stop;
flag<=0;
end
default: state<='bxxxxxxxxx;
endcase
end
end
endmodule 谁给个正确的模块也行啊 module LCD_12864(
input CLK, //系统时钟输入
input RST_N, //系统复位输入
output reg LCD_RS, //LCD的寄存器选择输出信号
output LCD_RW, //LCD的读、写操作选择输出信号
output LCD_E, //LCD使能信号
output reg LCD_D, //LCD的数据总线(不进行读操作,故为输出)
inputdata_miao,
inputdata_fen,
inputdata_hour
);
reg CLK_LCD; //LCD时钟信号
reg cnt;
// CLK频率为50MHz, 产生LCD时钟信号, 10Hz
always @(posedge CLK or negedge RST_N)
begin
if (!RST_N)begin cnt <= 16'b0;CLK_LCD <= 0;end
else if(cnt == 49999)begin cnt <= 0;CLK_LCD <= ~CLK_LCD;end
else cnt <= cnt +1'b1;end
reg state; //State Machine code
parameter IDLE= 9'b00000000; //初始状态,下一个状态为CLEAR
parameter SETFUNCTION = 9'b00000001; //功能设置:8位数据接口
parameter SETFUNCTION2 = 9'b00000010;
parameter SWITCHMODE = 9'b00000100; //显示开关控制:开显示,光标和闪烁关闭
parameter CLEAR = 9'b00001000; //清屏
parameter SETMODE = 9'b00010000; //输入方式设置:数据读写操作后,地址自动加一/画面不动
parameter SETDDRAM = 9'b00100000; //设置DDRAM的地址:第一行起始为0x80/第二行为0x90
parameter WRITERAM = 9'b01000000; //数据写入DDRAM相应的地址
parameter STOP = 9'b10000000; //LCD操作完毕,释放其控制
wire disp_miao_L,disp_miao_H;//秒显示低位 * 秒显示高位
wire disp_fen_L,disp_fen_H;
wire disp_hour_L,disp_hour_H;
//秒
assigndisp_miao_H=data_miao/8'd10+8'h30;
assigndisp_miao_L=data_miao%8'd10+8'h30;
//分
assigndisp_fen_H=data_fen/8'd10+8'h30;
assigndisp_fen_L=data_fen%8'd10+8'h30;
//时
assigndisp_hour_H=data_hour/8'd10+8'h30;
assigndisp_hour_L=data_hour%8'd10+8'h30;
reg flag; //标志位,LCD操作完毕为0
reg char_cnt;
reg data_disp;
assign LCD_RW = 1'b0; //没有读操作,R/W信号始终为低电平
assign LCD_E= (flag == 1)?CLK_LCD:1'b0; //E信号出现高电平以及下降沿的时刻与LCD时钟相同
always @(posedge CLK_LCD or negedge RST_N) //只有在写数据操作时,RS信号才为高电平,其余为低电平
begin
if(!RST_N)
LCD_RS <= 1'b0;
else if(state == WRITERAM)
LCD_RS <= 1'b1;
else
LCD_RS <= 1'b0;
end
// State Machine
always @(posedge CLK_LCD or negedge RST_N)
begin
if(!RST_N)
begin
state <= IDLE;
LCD_D <= 8'bzzzzzzzz;
char_cnt <= 5'b0;
flag <= 1'b1;
end
else begin
case(state)
IDLE:
begin
state <= SETFUNCTION;
LCD_D <= 8'bzzzzzzzz;
end
SETFUNCTION:
begin
state <= SETFUNCTION2;
LCD_D <= 8'h30; // 8-bit 控制界面,基本指令集动作
end
SETFUNCTION2:
begin
state <= SWITCHMODE;
LCD_D <= 8'h30; // 清屏
end
SWITCHMODE:
begin
state <= CLEAR;
LCD_D <= 8'h0c; // 显示开关:开显示,光标和闪烁关闭
end
CLEAR:
begin
state <= SETMODE;
LCD_D <= 8'h01;
end
SETMODE:
begin
state <= SETDDRAM;
LCD_D <= 8'h06; // 输入方式设置: 数据读写后,地址自动加1,画面不动
end
SETDDRAM:
begin
state <= WRITERAM;
if(char_cnt == 0) //如果显示的是第一个字符,则设置第一行的首字符地址
begin
LCD_D <= 8'h90; //Line2
end
else //第二次设置时,是设置第二行的首字符地址
begin
LCD_D <= 8'h88; //Line3
end
end
WRITERAM:
begin
if(char_cnt <= 12)
begin
char_cnt <= char_cnt + 1'b1;
LCD_D <= data_disp;
if( char_cnt == 12 )
state <= SETDDRAM;
else
state <= WRITERAM;
end
else if( char_cnt >= 13 && char_cnt <= 28)
begin
LCD_D <= data_disp;
state <= WRITERAM;
char_cnt <= char_cnt + 1'b1;
end
else if(char_cnt == 29)
begin
state <=SETDDRAM;
char_cnt <= 5'b0;
// flag <= 1'b0;
end
end
STOP: state <= STOP;
default: state <= IDLE;
endcase
end
end
always @(char_cnt) //输出的字符
begin
case (char_cnt)
5'd0:data_disp <= 8'h20;
5'd1:data_disp <= 8'h20;
5'd2:data_disp <= 8'h20;
5'd3:data_disp <= 8'h20;
5'd4:data_disp <= 8'd181;
5'd5:data_disp <= 8'd177;//当
5'd6:data_disp <= 8'd199;
5'd7:data_disp <= 8'd176;//前
5'd8:data_disp <= 8'd186;
5'd9:data_disp <= 8'd177;//时
5'd10:data_disp <= 8'd188;
5'd11:data_disp <= 8'd228;//间
5'd12:data_disp <= ":";
5'd13:data_disp <= 8'h20;
5'd14:data_disp <= 8'h20;
5'd15:data_disp <= 8'h20;
5'd16:data_disp <= 8'h20;
5'd17:data_disp <= disp_hour_H;
5'd18:data_disp <= disp_hour_L; //时
5'd19:data_disp <= ":";
5'd20:data_disp <= disp_fen_H;
5'd21:data_disp <= disp_fen_L;//分
5'd22:data_disp <= ":";
5'd23:data_disp <= disp_miao_H;
5'd24:data_disp <= disp_miao_L; //秒
5'd25:data_disp <= 8'h20;
5'd26:data_disp <= 8'h20;
5'd27:data_disp <= 8'h20;
5'd28:data_disp <= 8'h20;
default : data_disp <= 8'd20;
endcase
end
endmodule
程序来自坛子的一位网友,我只是稍微改了些。代码一直在用,没问题。 mark下 谢了 MARK MARK mark mark 回复【3楼】nison
-----------------------------------------------------------------------
试一下,使用时发现动态显示不成功! 回复【10楼】chenbo_ourdev
-----------------------------------------------------------------------
我就是用这个代码写的一个秒表啊, mark mark!!! mark {:lol:}{:lol:}{:lol:}{:lol:}{:lol:}{:lol:}{:lol:}{:lol:}{:lol:}{:lol:} 正在找相关方面的例程嘿嘿貌是不错试一下
页:
[1]