(原文件名:elsonx.jpg)
module LCD1602 (clk_500Hz, rst_n, update, addr, data, lcd_rw, lcd_rs, lcd_en, lcd_data);
input clk_500Hz, rst_n, update;
input[4:0] addr;
input[7:0] data;
output lcd_rw, lcd_rs, lcd_en;
output[7:0] lcd_data;
reg lcd_rs;
wire lcd_en;
reg[7:0] lcd_data;
reg[9:0] current_state, next_state;
reg[4:0] addr_cnt;
reg[7:0] disp_buf1[15:0];
reg[7:0] disp_buf2[15:0];
parameter IDLE = 10'b00_0000_0000,
CLEAR = 10'b00_0000_0010,
DISPOFF = 10'b00_0000_0100,
SETLCDMODE = 10'b00_0000_1000,
SETCURSOR = 10'b00_0001_0000,
CURSORMODE = 10'b00_0010_0000,
WRITEADDR1 = 10'b00_0100_0000,
WRITEADDR2 = 10'b00_1000_0000,
WRITEDATA1 = 10'b01_0000_0000,
WRITEDATA2 = 10'b10_0000_0000;
assign lcd_rw = 1'b0;
assign lcd_en = clk_500Hz;
task init_buf;
disp_buf1[0] <= "T";
disp_buf1[1] <= "o";
disp_buf1[2] <= ":";
disp_buf1[3] <= "w";
disp_buf1[4] <= "w";
disp_buf1[5] <= "w";
disp_buf1[6] <= ".";
disp_buf1[7] <= "o";
disp_buf1[8] <= "u";
disp_buf1[9] <= "r";
disp_buf1[10] <= "d";
disp_buf1[11] <= "e";
disp_buf1[12] <= "v";
disp_buf1[13] <= ".";
disp_buf1[14] <= "c";
disp_buf1[15] <= "n";
disp_buf2[0] <= " ";
disp_buf2[1] <= " ";
disp_buf2[2] <= " ";
disp_buf2[3] <= " ";
disp_buf2[4] <= " ";
disp_buf2[5] <= " ";
disp_buf2[6] <= " ";
disp_buf2[7] <= "b";
disp_buf2[8] <= "y";
disp_buf2[9] <= " ";
disp_buf2[10] <= "E";
disp_buf2[11] <= "l";
disp_buf2[12] <= "s";
disp_buf2[13] <= "o";
disp_buf2[14] <= "n";
disp_buf2[15] <= "x";
endtask
always @ (posedge clk_500Hz or negedge rst_n)
begin
if (!rst_n)
current_state <= IDLE;
else
current_state <= next_state;
end
always @ (current_state or addr_cnt)
begin
next_state = 4'hx;
case (current_state)
IDLE: next_state = SETLCDMODE;
SETLCDMODE: next_state = DISPOFF;
DISPOFF: next_state = CLEAR;
CLEAR: next_state = SETCURSOR;
SETCURSOR: next_state = CURSORMODE;
CURSORMODE: next_state = WRITEADDR1;
WRITEADDR1: next_state = WRITEDATA1;
WRITEADDR2: next_state = WRITEDATA2;
WRITEDATA1:
begin
if(addr_cnt == 16)
next_state = WRITEADDR2;
else
next_state = WRITEDATA1;
end
WRITEDATA2:
begin
if(addr_cnt == 16)
next_state = WRITEADDR1;
else
next_state = WRITEDATA2;
end
default: next_state = IDLE;
endcase
end
always @ (posedge clk_500Hz or negedge rst_n)
begin
if (!rst_n)
addr_cnt <= 0;
else
case (next_state)
IDLE:
begin
lcd_rs = 0;
lcd_data = 8'hxx;
end
SETLCDMODE:
begin
lcd_rs = 0;
lcd_data = 8'h38;
end
DISPOFF:
begin
lcd_rs = 0;
lcd_data = 8'h08;
end
CLEAR:
begin
lcd_rs = 0;
lcd_data = 8'h1;
end
SETCURSOR:
begin
lcd_rs = 0;
lcd_data = 8'h06;
end
CURSORMODE:
begin
lcd_rs = 0;
lcd_data = 8'h0C;
end
WRITEADDR1:
begin
lcd_rs = 0;
lcd_data = 8'h80;
end
WRITEADDR2:
begin
lcd_rs = 0;
lcd_data = 8'hc0;
end
WRITEDATA1:
begin
lcd_rs = 1;
lcd_data = disp_buf1[addr_cnt];
addr_cnt <= addr_cnt + 1;
end
WRITEDATA2:
begin
lcd_rs = 1;
lcd_data = disp_buf2[addr_cnt];
addr_cnt <= addr_cnt + 1;
end
endcase
end
always @ (posedge update or negedge rst_n)
begin
if (!rst_n)
init_buf;
else if (!addr[4])
disp_buf1[addr[3:0]] <= data;
else
disp_buf2[addr[3:0]] <= data;
end
endmodule
代码贴上来好像缩进有点乱了~~~
点击此处下载 LCD1602.rar(文件大小:960字节) (原文件名CD1602.rar) |
|
|
|