⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd.v

📁 用EPM1270实现的1602液晶驱动Verilog
💻 V
字号:
module lcd(clk,rst,lcd_e,lcd_rw,lcd_rs,data);
	input clk,rst;
	output lcd_e,lcd_rw,lcd_rs;
	output [7:0] data;
	reg lcd_e,lcd_rw,lcd_rs;
	reg [7:0] data;
	
	reg [10:0] state;
	reg flag,flag1;
	reg [5:0] address;
	
	
	parameter IDLE		=11'b00000000000;
	parameter CLEAR		=11'b00000000001;		//清屏
	
	parameter RETURNCURSOR	=11'b00000000010;	//归home位
	
	parameter SETMODE	=11'b00000000100;		
	//输入方式设置,读写数据后ram地址增/减1;画面动/不动
	
	parameter SWITCHMODE	=11'b00000001000;	
	//显示状态设置,显示开/关;光标开/关;闪烁开/关
	
	parameter SHIFT		=11'b00000010000;		
	//光标画面滚动 画面/光标平移一位;左/右平移一位
	
	parameter SETFUNCTION	=11'b00000100000;	
	//工作方式设置 1:8/1:4位数据接口;两行/一行显示;5x10/5x7点阵
	
	parameter SETCGRAM	=11'b00001000000;		//设置CGRAM
	parameter SETDDRAM	=11'b00010000000;		//设置DDRAM
	parameter SETDDRAM1 =11'b00010000001;
	parameter READFLAG	=11'b00100000000;		//
	parameter WRITERAM	=11'b01000000000;		//写RAM
	parameter READRAM	=11'b10000000000;		//读RAM

	parameter cur_inc      	=1;
	parameter cur_dec      	=0;
	parameter cur_shift    	=1;
	parameter cur_noshift  	=0;
	parameter open_display 	=1;
	parameter open_cur     	=0;
	parameter blank_cur    	=0;
	parameter shift_display	=1;
	parameter shift_cur    	=0;
	parameter right_shift  	=1;
	parameter left_shift   	=0;
	parameter datawidth8   	=1;
	parameter datawidth4   	=0;
	parameter twoline      	=1;
	parameter oneline      	=0;
	parameter font5x10     	=1;
	parameter font5x7      	=0;

	function [7:0] ddram;
		input [5:0] n;
		begin
			case(n)
			6'b000_000:ddram=8'h43;			//C
			6'b000_001:ddram=8'h68;			//h	  
			6'b000_010:ddram=8'h61;			//a
			6'b000_011:ddram=8'h6e;			//n
			6'b000_100:ddram=8'h67;			//g
			6'b000_101:ddram=8'h73;			//s
			6'b000_110:ddram=8'h68;			//h
			6'b000_111:ddram=8'h61;			//a
			6'b001_000:ddram=8'h4d;			//M
			6'b001_001:ddram=8'h69;			//i
			6'b001_010:ddram=8'h6e;			//n
			6'b001_011:ddram=8'h67;			//g
			6'd12:ddram=8'h77;			//w
			6'd13:ddram=8'h65;			//e
			6'd14:ddram=8'h69;			//i
			6'd15:ddram=8'h21;			//!
			
			6'd16:ddram=8'h44;			//D
			6'd17:ddram=8'h65;			//e
			6'd18:ddram=8'h73;			//s
			6'd19:ddram=8'h69;			//i
			6'd20:ddram=8'h67;			//g
			6'd21:ddram=8'h6e;			//n
			6'd22:ddram=8'h62;			//b
			6'd23:ddram=8'h79;			//y
			6'd24:ddram=8'h3a;			//:
			6'd25:ddram=8'h53;			//S
			6'd26:ddram=8'h68;			//h
			6'd27:ddram=8'h75;			//u
			6'd28:ddram=8'h77;			//w
			6'd29:ddram=8'h61;			//a
			6'd30:ddram=8'h6e;			//n
			6'd31:ddram=8'h67;			//g
			endcase
		end
	endfunction
	
	reg [15:0] clkcnt;
	
	always @ (posedge clk)
	if(!rst)
	clkcnt<=16'b0000_0000_0000_0000;
	else
	begin
		if(clkcnt==16'b1001_1100_0100_0000)
		//if(clkcnt==16'b1001_1000_0100_0000)
			clkcnt<=16'b0000_0000_0000_0000;
		else 
			clkcnt<=clkcnt+1;
	end
	
	wire tc_clkcnt;
	assign tc_clkcnt=(clkcnt==16'b1001_1100_0100_0000)?1:0;
	//assign tc_clkcnt=(clkcnt==16'b1001_1000_0100_0000)?1:0;
	
	reg clkdiv;
	always @ (posedge tc_clkcnt)
	if(!rst)
		clkdiv<=0;
	else
		clkdiv<=~clkdiv;
	
	reg clk_int;
	always @ (posedge clkdiv)
	if(rst==0)
		clk_int<=0;
	else
		clk_int<=~clk_int;
		
	always @ (negedge clkdiv)
	if(rst==0)
		lcd_e<=0;
	else
		lcd_e<=~lcd_e;
		
		
	always @ (posedge clk_int or negedge rst)
		if(!rst)
		begin
			state<=IDLE;
			address<=6'b000_000;
			flag<=0;
		end
		else
		begin
			case(state)
			IDLE		:begin 
							data<=8'bzzzz_zzzz;
							if(flag==0)
							begin
								state<=SETFUNCTION;
								flag<=1;
							end
							else
								state<=SHIFT;
						 end
			CLEAR			:begin lcd_rs<=0;lcd_rw<=0;data<=8'b0000_0001;
									state<=SETMODE;end   
			SETMODE			:begin lcd_rs<=0;lcd_rw<=0;data[7:2]<=6'b000001;data[1]<=cur_inc;data[0]<=cur_noshift;
									state<=SETDDRAM;end
			RETURNCURSOR	:begin lcd_rs<=0;lcd_rw<=0;data<=8'b00000010;
									state<=SETDDRAM;end
			SWITCHMODE 		:begin lcd_rs<=0;lcd_rw<=0;data[7:3]<=5'b00001;data[2]<=open_display;data[1]<=open_cur;data[0]<=blank_cur;
								state<=CLEAR;end
			SHIFT			:begin lcd_rs<=0;lcd_rw<=0;data[7:4]<=4'b0001;data[3]<=shift_cur;data[2]<=left_shift;data[1:0]<=2'b00;
								state<=IDLE;end
			SETFUNCTION		:begin lcd_rs<=0;lcd_rw<=0;data[7:5]<=3'b001;data[4]<=datawidth8;data[3]<=twoline;data[2]<=font5x10;data[1:0]<=2'b00;
								state<=SWITCHMODE;end
			SETCGRAM		:begin lcd_rs<=0;lcd_rw<=0;data<=8'b01000000;state<=IDLE;end
			SETDDRAM		:begin lcd_rs<=0;lcd_rw<=0;data<=8'b10000000;state<=WRITERAM;end
			SETDDRAM1		:begin lcd_rs<=0;lcd_rw<=0;data<=8'b11000000;state<=WRITERAM;end //设置第二行首地址
			WRITERAM		:begin
			                if(address<=6'd15)
							begin
								lcd_rs<=1;
								lcd_rw<=0;
								data<=ddram(address);
								address<=address+1;
								state<=WRITERAM;
								flag1<=1;
							end	
			                else
							begin
							    if (address>=6'd16&&address<=6'd31&&flag1)
							    begin
							       flag1<=0;
							       state<=SETDDRAM1;
							    end
							    else
							    begin
							       if (address<=6'd31)
							       begin							    
							       lcd_rs<=1;
								   lcd_rw<=0;
								   data<=ddram(address);
								   address<=address+1;
								   state<=WRITERAM;
								   end
								   else
								   begin
								lcd_rs<=0;
								lcd_rw<=0;
								state<=SHIFT;
								//state<=CLEAR;
								address<=6'b000_000;
								   end
							    end
							end
							
						
							end
			endcase
		end
endmodule
							
			
			
		
		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -