睿酷研发-助学板上实现的液晶刷屏程序

睿酷研发-助学板上实现的液晶刷屏程序
时间:2020年8月21~23日
开发板型号:睿智FPGA开发板ALTERA IV EP4CE四代
液晶屏型号:3.5' 320X480 LCD MODULE
液晶屏驱动:ILI9481
液晶屏接口:8080

源码如下:
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************

  • File Name : ILI9481_320X480.v
  • Author : 驱动开发小组
  • Version : V1.0.0
  • Date : 8/23/2018
  • Description : 3.5寸液晶屏模块FPGA驱动.

  • 屏幕尺寸 :3.5英寸
  • 分辨率 :320 X 480
  • 颜色深度 :262k
  • 驱动型号 :ILI9481,IC分辨率320*480
  • 接口类型 :8080接口

*******************************************************************************/
module ILI9481_320X480(RSTn,clk,LCD_DB,LCD_CS,LCD_WR,LCD_RS,test,state_lcd_write,LCD_RESET,LCD_DATA_TEMP_17);
input clk;
input RSTn;
output [15:0] LCD_DB;
output LCD_CS; //液晶屏选择
output LCD_WR; //写命令
output LCD_RS; //1:数据/0:命令
output test; //测试引脚
output LCD_RESET; //复位引脚
output [3:0] state_lcd_write;//写的状态
output LCD_DATA_TEMP_17; //也是用于测试位,将此信号接到FPGA引脚上

reg [15:0] LCD_DB;
reg LCD_CS;
reg LCD_WR;
reg LCD_RS;
reg LCD_RESET;
reg test;

//内部寄存器
reg [3:0] state_lcd_write;//写的状态
reg [16:0] LCD_DATA_TEMP; //数据缓存
reg [7:0] addr_command; //地址命令
reg [31:0] count_dot; //显示的点数
reg [15:0] count_delay; //延时时钟周期

assign LCD_DATA_TEMP_17=LCD_DATA_TEMP[16];

//将时钟信号分频之后
always @(posedge clk)
LCD_RESET<=1'b1;

//测试代码
always @(posedge clk)
test<=~test;

always @(posedge clk)
if(!RSTn) //复位,各个状态初始化
begin
state_lcd_write <= 4'd0;//0状态
LCD_CS <= 1'b1; //未选中液晶屏
LCD_WR <= 1'b1; //写入不使能
LCD_RS <= 1'b0; //0表示命令读写
LCD_DB <= 16'd0; //总线上数据清零
addr_command <= 8'd0; //初始化命令为零
LCD_DATA_TEMP <= 17'd0; //数据缓存清零
count_dot <= 16'd0; //写屏点数清零
count_delay <= 16'd0; //延时是时钟数初始化
end
else
begin
case(state_lcd_write)//LCD的各个状态
4'd0: //初始化状态
if(count_delay == 16'd2499) //init delay,初始化延时50ms
begin
state_lcd_write <= 4'd1;
count_delay <= 16'd0; //到下一个状态延时清零
end
else
begin
state_lcd_write <= 4'd0; //在50ms内每次回到原状态
count_delay <= count_delay + 1'b1;
end
4'd1: //开始执行Function中的命令
begin
state_lcd_write <= 4'd2;//更改状态
LCD_CS <= 1'b1;
LCD_WR <= 1'b1;
LCD_DATA_TEMP<=display_command(addr_command);
count_delay <= 16'd0; //延时清零
count_delay <= count_delay + 1'b1;
end

		4'd2:
			if(LCD_DATA_TEMP[16])//data写数据
					begin
						state_lcd_write <= state_lcd_write + 1'b1;//状态变换
						LCD_CS    <= 1'b0;
						LCD_RS    <= 1'b1;  //写数据
						LCD_WR    <= 1'b0;
						LCD_DB <= LCD_DATA_TEMP[15:0];
					end
			else    //command写命令
					begin
						state_lcd_write <= state_lcd_write + 1'b1;//状态变换
						LCD_CS    <= 1'b0;
						LCD_RS    <= 1'b0; //写命令
						LCD_WR    <= 1'b0;
						LCD_DB<= LCD_DATA_TEMP[15:0];
					end
		4'd3:
			begin
				state_lcd_write <= state_lcd_write + 1'b1;//状态变换,相当于等待一个周期,20ns
			end
		4'd4:
			begin
				state_lcd_write <= state_lcd_write + 1'b1;//状态变换
				LCD_CS <= 1'b1;									//液晶屏不选中
			end
		4'd5:
			begin 
				state_lcd_write <= state_lcd_write + 1'b1;//状态变换
				LCD_WR <= 1'b1;									//WR置高
			end
		4'd6:
			if(addr_command == 8'd49)//如果当前命令为第48条命令,显示颜色为红色这条
			begin
				count_dot <= count_dot + 1'b1;//显示的点加1
				state_lcd_write <= 4'd1;		//置下一状态为1状态

				if(count_dot == 32'd76800)    //显示液晶屏的一半,就更换颜色显示
					begin 
						addr_command <= 8'd50;  //换颜色
						count_dot <= 32'd1;		//显示颜色变换,将显示的颜色点数重新计数
					end
				else
					state_lcd_write <= 4'd1;	//取数的状态
				end
			else if(addr_command == 8'd50)        //white
				begin
					count_dot <= count_dot + 1'b1;
					state_lcd_write <= 4'd1;
					if(count_dot == 32'd76800)    //显示液晶屏的一半,就更换颜色显示
						begin 
							addr_command <= 8'd49;  //换颜色
							count_dot <= 32'd0; //显示颜色变换,将显示的颜色点数重新计数
						end
					else
						state_lcd_write <= 4'd1;
					end
			else 
				begin
					addr_command <= addr_command + 1'b1;
					state_lcd_write <= 4'd0;
				end
			4'd7:
				state_lcd_write <= 4'd7;
		endcase
	end

//返回一个值
function [16:0] display_command;
input [7:0] addr;//端口说明语句
begin
case (addr)
8'd0:display_command = {1'b0,16'h0011};
//需要延时120ms
8'd1:display_command = {1'b0,16'h00D0};//写寄存器
8'd2:display_command = {1'b1,16'h0007};//写命令
8'd3:display_command = {1'b1,16'h0042};
8'd4:display_command = {1'b1,16'h0018};

	8'd5:display_command = {1'b0,16'h00D1};
	8'd6:display_command = {1'b1,16'h0000};
	8'd7:display_command = {1'b1,16'h0007};
	8'd8:display_command = {1'b1,16'h0010};
	  
	8'd9:display_command = {1'b0,16'h00D2};
	8'd10:display_command = {1'b1,16'h0001};
	8'd11:display_command = {1'b1,16'h0002};
	
	8'd12:display_command = {1'b0,16'h00C0};		 
	8'd13:display_command = {1'b1,16'h0010};                 
	8'd14:display_command = {1'b1,16'h003B};		 
	8'd15:display_command = {1'b1,16'h0000};
	8'd16:display_command = {1'b1,16'h0002};		 
	8'd17:display_command = {1'b1,16'h0011};
			
	8'd18:display_command = {1'b0,16'h00C5};		 
	8'd19:display_command = {1'b1,16'h0003};//set display control mode
	
	8'd20:display_command = {1'b0,16'h00C8};	  
	8'd21:display_command = {1'b1,16'h0000};
	8'd22:display_command = {1'b1,16'h0032};		  
	8'd23:display_command = {1'b1,16'h0036};           
	8'd24:display_command = {1'b1,16'h0045};
	8'd25:display_command = {1'b1,16'h0006};
	8'd26:display_command = {1'b1,16'h0016};
	8'd27:display_command = {1'b1,16'h0037};
	8'd28:display_command = {1'b1,16'h0075};
	8'd29:display_command = {1'b1,16'h0077};
	8'd30:display_command = {1'b1,16'h0054};
	8'd31:display_command = {1'b1,16'h000C};
	8'd32:display_command = {1'b1,16'h0000};
	
	8'd33:display_command = {1'b0,16'h0036};
	8'd34:display_command = {1'b1,16'h000A};
	
	8'd35:display_command = {1'b0,16'h003A};
	8'd36:display_command = {1'b1,16'h0055};
	
	8'd37:display_command = {1'b0,16'h002A};
	8'd38:display_command = {1'b1,16'h0000};	  
	8'd39:display_command = {1'b1,16'h0000};
	8'd40:display_command = {1'b1,16'h0001};
	8'd41:display_command = {1'b1,16'h003F};
	
	8'd42:display_command = {1'b0,16'h002B};		 
	8'd43:display_command = {1'b1,16'h0000};
	8'd44:display_command = {1'b1,16'h0000};	 
	8'd45:display_command = {1'b1,16'h0001};
	8'd46:display_command = {1'b1,16'h00E0};
	 
	 //需要延时 120ms
	8'd47:display_command = {1'b0,16'h0029};//horizontal ram address
	8'd48:display_command = {1'b0,16'h002c};
	
	8'd49:display_command = {1'b1,16'hF800};//显示为红色的数据
	8'd50:display_command = {1'b1,16'hFFFF};//显示为白色的数据
	
	default:display_command = {1'b0,16'h0000};
	endcase
end

endfunction

endmodule

状态机如下图所示

代码参考:

https://www.cnblogs.com/zhezhe1988/p/3504572.html

posted on 2020-09-24 20:25  弦歌不辍  阅读(314)  评论(0编辑  收藏  举报