一水寒

lcd1602代码

0
阅读(3510)
这是之前的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;