求助

/*************************************************
//Module:       lcd1602
//File Name:    lcd1602.v
//Version:      2.0
//Date:         2011.12.5 
//Author:       wang li
//Code Type:    RTL
//Description:  LCD1602液晶显示
//              clk——时钟输入(1位)
//              rst——复位信号输入(1位)
//							输入看模块

-- 内部显示地址
--  1   2  3  4   5   6   7  8  9  10  11  12  13  14  15  16
-- 00  01 02  03  04  05 06 07 08  09  0A  0B  0C  0D  0E  0F   第一行
-- 40  41 42  43  44  45 46 47 48  49  4A  4B  4C  4D  4E  4F   第二行
**************************************************/
module lcd1602(clk,reset,LCD_E,LCD_RW,LCD_RS,LCD_DATA);
input clk;				//时钟信号,50Mhz
input reset;			//复位信号,低电平进行复位
output LCD_E;			//1602使能引脚,1时读取信息,1->0(下降沿)执行命令
output LCD_RS;			//1602数据——H/命令——L  选择端
output LCD_RW;			//1602写——L/读——H  选择端
output [7:0] LCD_DATA;	//1602数据传输端口

//----------------------
//-----时钟分频模块-----
wire clk_lcd;		// 用于将clk_div模块输出的clk_lcd接到lcd_ctrl中  
reg [11:0] cnt;	//对时钟进行计数分频
reg clk_buf;

always @(posedge clk or negedge reset)
begin
	if(!reset)	//低电平进行复位
		cnt<=0;
	else if(cnt>=50000)	//1ms的范围
		cnt<=0;
	else
		cnt<=cnt+1;
end

always @(posedge clk or negedge reset)
begin
	if(!reset)	//低电平进行复位
		cnt<=0;
	else if(cnt==50000)	//1ms的范围
		clk_buf<=~clk_buf;
		
	assign	clk_lcd=clk_buf;
end



//----------------------
//-----显示控制模块-----
parameter   
CLEAR 			 = 4'd1, //清屏指令  
SET_FUNCTION	 = 4'd2, //工作方式设置指令  
SWITCH_MODE 	 = 4'd3, //开关控制指令  
SET_MODE		 = 4'd4, //设定显示屏或光标移动方向指令  
SET_DDRAM1 		 = 4'd5, //设定第一行DDRAM地址指令  
WRITE_RAM1 		 = 4'd6, //向第一行写入的数码  
WRITE_RAM2  	 = 4'd7,  
IDLE  			 = 4'd8; //空闲 

reg [127:0] Data_First = "www.endchina.com"; //液晶显示的第一行的数据  
reg [127:0] Data_Second = " chick_kid "; //液晶显示的第二行的数据  
reg [127:0] Data_First_Buf,
						Data_Second_Buf; //液晶显示的数据缓存 

//-----LCD状态机寄存器-----  
reg[3:0] state; 				//当前状态寄存器  
reg lcd_rs_reg = 1'b0; //lcd_rs输出寄存器  
reg lcd_rw_reg = 1'b0; //lcd_rw输出寄存器  
reg[7:0] lcd_data_reg; //lcd_data输出寄存器  
reg lcd_e_sel;  
reg [5:0] display_count;  

wire LCD_E;			//1602使能引脚,1时读取信息,1->0(下降沿)执行命令
wire LCD_RS;			//1602数据——H/命令——L  选择端
wire LCD_RW;			//1602写——L/读——H  选择端
wire [7:0] LCD_DATA;	//1602数据传输端口

//-----状态控制-----
always @(posedge clk_lcd or negedge reset)
begin
	if(!reset)
		begin
			state<=CLEAR;
			lcd_rs_reg<=0;
			lcd_data_reg<=0;
			lcd_e_sel<=1;			//为什么是1
			display_count<=0;
		end
	else
		case(state)
			CLEAR:									//清屏指令
				begin
					state<=SET_FUNCTION;
					lcd_data_reg<=8'b0000_0001;		
				end
				
			SET_FUNCTION:						//工作方式设置
				begin
					state<=SWITCH_MODE;		
					lcd_data_reg<=8'b0011_1000;
					//第4位DL:0=数据总线为4位;1=数据总线为8位
					//第3位N:0=显示1行;1=显示2行  
					//第2位F:0=5×7点阵/每字符;1=5×10点阵/每字符
				end
				
			SWITCH_MODE:						//显示开关控制指令
				begin
					state<=SET_MODE;
					lcd_data_reg<=8'b0000_1100;
					//第2位D:0=显示功能关;1=显示功能开
					//第1位C:0=无光标;1=有光标  
					//第0位B:0=光标闪烁 1=光标不闪烁
				end
				
			SET_MODE:		 					//设定显示屏或光标移动方向指令  
				begin
					state <= SET_DDRAM1;  
          lcd_data_reg<=8'b0000_0110;  
          //第3位S/C;第2位R/L
					//	  	S/C   R/L     设定情况  
					//   		0      0      光标左移1格,且AC值减1  
					//   		0      1      光标右移1格,且AC值加1  
					//  	  	1      0      显示器上字符全部左移一格,但光标不动  
					//   		1      1      显示器上字符全部右移一格,但光标不动  
				end
				
			SET_DDRAM1:  				//设定第一行DDRAM地址指令
	      begin  
	        state<=WRITE_RAM1; 
//-----写入第一行显示起始地址:----- 
//  1   2  3  4   5   6   7  8  9  10  11  12  13  14  15  16
// 00  01 02  03  04  05 06 07 08  09  0A  0B  0C  0D  0E  0F   第一行
// 40  41 42  43  44  45 46 47 48  49  4A  4B  4C  4D  4E  4F   第二行
	        lcd_data_reg<=8'h80+8'h01; //第一行第二个位置  
	        Data_First_Buf<=Data_First;  
	      end
	      
	     WRITE_RAM1:			//向第一行写入的数码
	     	begin
	     		if(display_count==16)			//表示第一行写完
						begin
							lcd_data_reg<=8'h80+8'h40;	//送入写第二行的指令  
							lcd_rs_reg<=0;
							display_count<=0;
							Data_Second_Buf<=Data_Second;
							state<=WRITE_RAM2;		//写完第一行进入写第二行状态 
						end
					else
						begin
							lcd_data_reg<=Data_First_Buf[127:120];
							Data_First_Buf<=(Data_First_Buf<<8); 	//左移
							lcd_rs_reg<=1;	RS=1表示写数据  
							display_count<=display_count+1;
							state<=WRITE_RAM1;
						end
	     	end
	     WRITE_RAM2:			//向第2行写入的数码
	     	begin
	     		if(display_count==16)
	     			begin
		     			lcd_e_sel<=0;
		     			lcd_rs_reg<=0;
		     			display_count<=0;
		     			state<=IDLE;		//写完进入空闲状态  
	     			end
	     		else
	     			begin
		     			lcd_data_reg<=Data_Second_Buf[127:120];  
						Data_Second_Buf <= (Data_Second_Buf << 8);  
						lcd_rs_reg <= 1;  
						display_count <= display_count +1;  
						state <= WRITE_RAM2;  
	     			end
	     	end
	     IDLE:
	     	begin
	     		state<=IDLE;
	     	end
	     default:
	     	state<=CLEAR;
	  endcase
	  
	assign LCD_RW = lcd_rw_reg;  
	assign LCD_RS = lcd_rs_reg;  
	assign LCD_DATA = lcd_data_reg;  
	assign LCD_E = lcd_e_sel ? clk_lcd : 1'b0;  

end

endmodule
	



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值