一水寒

lcd1602代码

0
阅读(2747)
这是之前的lcd1602代码,自己觉得代码思路还是比较简洁清晰的,贴这里吧,初学verilog的可以看一下。下面的显示的都是内 部给出的数据,可以加进输入输入端显示外部输入数据,也方便代码的移植。自己写的时候没写注释,刚刚把注释全部加上去,结果 这里的文字跟代码全混到一起去了,这个编辑器还不熟练,几经修改,全都乱了。现在直接复制过来。。
module lcd1602( input clk, input rst_n, // input [7:0] data_row1, // input [7:0] data_row2, output reg [7:0] lcd_data, output lcd_e, output reg lcd_rs, output lcd_rw ); reg [23:0] cnt; reg [3:0] cstate; reg [3:0] nstate; reg start_flag; reg [5:0] addr=6'b000000; reg [255:0] data_in_buf; parameter IDLE= 4'b0000, SETF= 4'b0001, //6 CLER= 4'b0010, //1 SETM= 4'b0011, //3 SHIF= 4'b0100, //5 DISP= 4'b0101, //4 SETD1= 4'b0110, SETD2= 4'b0111, WRTM= 4'b1000; parameter DATA_IN="ABCDEFG HIJKLMN OPQ RST UVW XYZ " ; always @ (posedge clk, negedge rst_n) if (!rst_n) cnt <= 0; else cnt <= cnt + 1'b1; wire lcd_clk = cnt[23]; always@(posedge lcd_clk,negedge rst_n) if(~rst_n) cstate<=IDLE; else cstate<=nstate; always@(*) case(cstate) IDLE: if(~start_flag) nstate= SETF; else nstate= SHIF; SETF: nstate= DISP; CLER: nstate= SETM; SETM: nstate= SETD1; SHIF: nstate= IDLE; DISP: nstate= CLER; SETD1: nstate= WRTM; WRTM: if(addr==15) nstate= SETD2; else if(addr==31) nstate= SHIF; else nstate= WRTM; SETD2: nstate= WRTM; default:nstate<=IDLE; endcase always@(posedge lcd_clk or negedge rst_n) if(~rst_n) begin lcd_rs<=0; lcd_data<=8'hzz; start_flag<=0; data_in_buf<=DATA_IN; end else case(nstate) IDLE: if(~start_flag) begin lcd_rs<=0; start_flag<=1; end else ; SETF: begin lcd_rs<=0;lcd_data<=8'h38;end CLER: begin lcd_rs<=0;lcd_data<=8'h01;end SETM: begin lcd_rs<=0;lcd_data<=8'h06;end SHIF: begin lcd_rs<=0;lcd_data<=8'h14;end DISP: begin lcd_rs<=0;lcd_data<=8'h0E;end SETD1: begin lcd_rs<=0;lcd_data<=8'h80;end WRTM: begin lcd_rs<=1; lcd_data<=data_in_buf[255:248]; data_in_buf<=data_in_buf<<8; if(addr==31) begin lcd_rs<=0; addr<=0; end else addr<=addr+1; end SETD2: begin lcd_rs<=0;lcd_data<=8'hC0;end default :; endcase assign lcd_e=lcd_clk; assign lcd_rw=0;
Baidu
map