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

📄 lcd.v

📁 FPGA EP2C5Q288C8 TEST 原码,测试OK 打开即用.
💻 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] datain;
	reg [7:0] data;
	
	reg [10:0] state;
	reg flag;
	reg [5:0] address;
	reg [6:0] counter;
	reg [3:0] divcounter;
	
	
	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 SETDDRAM1	=11'b00010000000;		//设置DDRAM
	parameter SETDDRAM2	=11'b00011000000;		//设置DDRAM
	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;
	

	
	
	reg [20:0] clkcnt;
	
	always @ (posedge clk)
	if(!rst)
	clkcnt<=21'b00000_0000_0000_0000_0000;
	else
	begin
		if(clkcnt==21'b01001_1100_0100_0000_0000)
			clkcnt<=21'b00000_0000_0000_0000_0000;
		else 
			clkcnt<=clkcnt+1;
	end
	
	wire tc_clkcnt;
	assign tc_clkcnt=(clkcnt==21'b01001_1100_0100_0000_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)//下降沿lcd_e输出
	if(!rst)
		lcd_e<=0;
	else
		lcd_e<=~lcd_e;
		
		
	always @ (posedge clk_int or negedge rst)
	 begin
		if(!rst)
		begin
			state<=IDLE;
			flag<=0;
			counter<=0;
			divcounter<=0;
			address<=0;
		end
		else
		begin
			case(state)
			IDLE		:begin 
							if(!flag)
							  begin
								state<=SETFUNCTION;
								flag<=1'b1;
								counter<=0;
								divcounter<=0;
						      end
				            else if(divcounter<4'd8)//改变移动速度
							   begin
							    divcounter<=divcounter+1;
							    state<=IDLE;
						   	    lcd_rw <=1'b1;
							   end
							  else
							   begin
							    divcounter<=0;
								state<=SHIFT;
							   end
						 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<=SETDDRAM1;
							end
			RETURNCURSOR	:begin 
									lcd_rs<=0;
									lcd_rw<=0;
									data<=8'b00000010;
									state<=WRITERAM;
							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_display;
								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
			SETDDRAM1		:begin
			                  lcd_rs<=0;
			                  lcd_rw<=0;
			                  state<=WRITERAM;
			                   if(counter==0)
			                     data<=8'b1000_0000;
			                    else
			                      data<=8'b1100_0000;
			                 end
			SETDDRAM2		:begin
			                 lcd_rs<=0;
			                 lcd_rw<=0;
			                 data<=8'b10000000;
			                 state<=WRITERAM;
			                 end//0x80显示在第一行
			WRITERAM		:begin
			                  lcd_rs<=1;
			                  lcd_rw<=0;
			                  data<=datain;
			                   if(counter<7'd40)
			                     begin
                                  address = counter+1;
                                   counter=counter+1;
                                   state<=WRITERAM;
                                 end
                               else  if(counter==7'd40)//1602lcd第一行能显示40个字符,可通过左移分别显示出来
			                      begin
			                       state<=SETDDRAM1;
			                        counter<=counter+1;
			                      end
                                 else if(counter<7'd73)
                                  begin
                                  address=counter-'d41+'d8;//-41表示所有字符重新显示在第二行,从第8个字符开始显示
                                   counter=counter+1;
                                   state=WRITERAM;
                                   end
                                   else if(counter<7'd81)
                                    begin
                                      address=counter-7'd81+7'd8;
                                      counter=counter+1;
                                      state<=WRITERAM; 
                                     end
                                  else 
                                    begin
                                     data<=8'd87;//"W"的ASCII值
                                      state<=SHIFT;
                                    end
                             end                   
	     		endcase
		end
	end
char_ram charram(.address(address),.data(datain));

endmodule
							
			
			
		
		

⌨️ 快捷键说明

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