<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于STEP FPGA的SPI RGB液晶屏顯示驅(qū)動(dòng)

          基于STEP FPGA的SPI RGB液晶屏顯示驅(qū)動(dòng)

          作者: 時(shí)間:2023-12-05 來源:電子森林 收藏

          硬件說明

          我們的STEP-BaseBoard底板上集成了1.8寸彩色液晶屏TFT_LCD模塊,大家可以驅(qū)動(dòng)LCD顯示文字、圖片或動(dòng)態(tài)的波形。
          首先了解一下液晶屏模塊,相關(guān)資料下載:https://pan.baidu.com/s/1bp6AYsR

          本文引用地址:http://www.ex-cimer.com/article/202312/453553.htm

          框圖如下:

          原理圖如下:

          原理圖中的器件U1為液晶屏,液晶屏為1.8寸,128RGB160像素,串行總線(SPI),液晶屏集成了ST7735S的驅(qū)動(dòng)器,處理器與ST7735S通信完成液晶屏的顯示控制

          ST7735S為132RGBx162像素點(diǎn)262K控制器/驅(qū)動(dòng)器,芯片可以直接跟外部處理器連接,支持串行SPI通信和8/9/16/18位并行通信(本液晶屏集成ST7735S時(shí)沒有留并行接口,所以只能使用串行通信),詳細(xì)參數(shù)請(qǐng)參考數(shù)據(jù)手冊(cè):st7735s_datasheet.pdf


          Verilog代碼

          // --------------------------------------------------------------------
          // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
          // --------------------------------------------------------------------
          // Module: LCD_RGB
          // 
          // Author: Step
          // 
          // Description: Drive TFT_RGB_LCD_1.8 to display
          // 
          // --------------------------------------------------------------------
          // Code Revision History :
          // --------------------------------------------------------------------
          // Version: |Mod. Date:   |Changes Made:
          // V1.1     |2016/10/30   |Initial ver
          // --------------------------------------------------------------------
          module LCD_RGB #(
          	parameter LCD_W = 8'd132,			//液晶屏像素寬度
          	parameter LCD_H = 8'd162			//液晶屏像素高度)(
          	input				clk_in,			//12MHz系統(tǒng)時(shí)鐘
          	input				rst_n_in,		//系統(tǒng)復(fù)位,低有效 	
          	output	reg			ram_lcd_clk_en,	//RAM時(shí)鐘使能
          	output	reg	[7:0]	ram_lcd_addr,	//RAM地址信號(hào)
          	input		[131:0]	ram_lcd_data,	//RAM數(shù)據(jù)信號(hào) 	
          	output	reg			lcd_rst_n_out,	//LCD液晶屏復(fù)位
          	output	reg			lcd_bl_out,		//LCD背光控制
          	output	reg			lcd_dc_out,		//LCD數(shù)據(jù)指令控制
          	output	reg			lcd_clk_out,	//LCD時(shí)鐘信號(hào)
          	output	reg			lcd_data_out	//LCD數(shù)據(jù)信號(hào)
          	); 	
          	localparam			INIT_DEPTH = 16'd73; //LCD初始化的命令及數(shù)據(jù)的數(shù)量 	
          	localparam			RED		=	16'hf800;	//紅色
          	localparam			GREEN	=	16'h07e0;	//綠色
          	localparam			BLUE	=	16'h001f;	//藍(lán)色
          	localparam			BLACK	=	16'h0000;	//黑色
          	localparam			WHITE	=	16'hffff;	//白色
          	localparam			YELLOW	=	16'hffe0;	//黃色 	
          	localparam			IDLE	=	3'd0;
          	localparam			MAIN	=	3'd1;
          	localparam			INIT	=	3'd2;
          	localparam			SCAN	=	3'd3;
          	localparam			WRITE	=	3'd4;
          	localparam			DELAY	=	3'd5; 	
          	localparam			LOW		=	1'b0;
          	localparam			HIGH	=	1'b1; 	
          	//assign	lcd_bl_out = HIGH;				// backlight active high level 	
          	wire		[15:0]	color_t	=	YELLOW;		//頂層色為黃色
          	wire		[15:0]	color_b	=	BLACK;		//背景色為黑色 	
          	reg			[7:0]	x_cnt;
          	reg			[7:0]	y_cnt;
          	reg			[131:0]	ram_data_r; 	
          	reg			[8:0]	data_reg;				//
          	reg			[8:0]	reg_setxy	[10:0];
          	reg			[8:0]	reg_init	[72:0];
          	reg			[2:0]	cnt_main;
          	reg			[2:0]	cnt_init;
          	reg			[2:0]	cnt_scan;
          	reg			[5:0]	cnt_write;
          	reg			[15:0]	cnt_delay;
          	reg			[15:0]	num_delay;
          	reg			[15:0]	cnt;
          	reg					high_word;
          	reg			[2:0] 	state = IDLE;
          	reg			[2:0] 	state_back = IDLE;
          	always@(posedge clk_in or negedge rst_n_in) begin
          		if(!rst_n_in) begin
          			x_cnt <= 8'd0;
          			y_cnt <= 8'd0;
          			ram_lcd_clk_en <= 1'b0;
          			ram_lcd_addr <= 8'd0;
          			cnt_main <= 3'd0;
          			cnt_init <= 3'd0;
          			cnt_scan <= 3'd0;
          			cnt_write <= 6'd0;
          			cnt_delay <= 16'd0;
          			num_delay <= 16'd50;
          			cnt <= 16'd0;
          			high_word <= 1'b1;
          			lcd_bl_out <= LOW;
          			state <= IDLE;
          			state_back <= IDLE;
          		end else begin
          			case(state)
          				IDLE:begin
          						x_cnt <= 8'd0;
          						y_cnt <= 8'd0;
          						ram_lcd_clk_en <= 1'b0;
          						ram_lcd_addr <= 8'd0;
          						cnt_main <= 3'd0;
          						cnt_init <= 3'd0;
          						cnt_scan <= 3'd0;
          						cnt_write <= 6'd0;
          						cnt_delay <= 16'd0;
          						num_delay <= 16'd50;
          						cnt <= 16'd0;
          						high_word <= 1'b1;
          						state <= MAIN;
          						state_back <= MAIN;
          					end
          				MAIN:begin
          						case(cnt_main)	//MAIN狀態(tài)
          							3'd0:	begin state <= INIT; cnt_main <= cnt_main + 1'b1; end
          							3'd1:	begin state <= SCAN; cnt_main <= cnt_main + 1'b1; end
          							3'd2:	begin cnt_main <= 1'b1; 
          							end
          							default: state <= IDLE;
          						endcase
          					end
          				INIT:begin	//初始化狀態(tài)
          						case(cnt_init)
          							3'd0:	begin lcd_rst_n_out <= 1'b0; 
          							cnt_init <= cnt_init + 1'b1; 
          							end	//復(fù)位有效
          							3'd1:	begin num_delay <= 16'd3000; 
          							state <= DELAY; 
          							state_back <= INIT; 
          							cnt_init <= cnt_init + 1'b1; end	//延時(shí)
          							3'd2:	begin lcd_rst_n_out <= 1'b1; 
          							cnt_init <= cnt_init + 1'b1; 
          							end	//復(fù)位恢復(fù)
          							3'd3:	begin num_delay <= 16'd3000; 
          							state <= DELAY; 
          							state_back <= INIT; 
          							cnt_init <= cnt_init + 1'b1; 
          							end	//延時(shí)
          							3'd4:	begin 
          										if(cnt>=INIT_DEPTH) begin	
          										//當(dāng)73條指令及數(shù)據(jù)發(fā)出后,配置完成
          											cnt <= 16'd0;
          											cnt_init <= cnt_init + 1'b1;
          										end else begin
          											data_reg <= reg_init[cnt];	
          											if(cnt==16'd0) num_delay <= 16'd50000; //第一條指令需要較長(zhǎng)延時(shí)
          											else num_delay <= 16'd50;
          											cnt <= cnt + 16'd1;
          											state <= WRITE;
          											state_back <= INIT;
          										end
          									end
          							3'd5:	begin cnt_init <= 1'b0; 
          							state <= MAIN; end	//初始化完成,返回MAIN狀態(tài)
          							default: state <= IDLE;
          						endcase
          					end
          				SCAN:begin	//刷屏狀態(tài),從RAM中讀取數(shù)據(jù)刷屏
          						case(cnt_scan)
          							3'd0:	begin //確定刷屏的區(qū)域坐標(biāo),這里為全屏
          										if(cnt >= 11) begin	//
          											cnt <= 16'd0;
          											cnt_scan <= cnt_scan + 1'b1;
          										end else begin
          											data_reg <= reg_setxy[cnt];
          											cnt <= cnt + 16'd1;
          											num_delay <= 16'd50;
          											state <= WRITE;
          											state_back <= SCAN;
          										end
          									end
          							3'd1:	begin ram_lcd_clk_en <= HIGH; 
          							ram_lcd_addr <= y_cnt; 
          							cnt_scan <= cnt_scan + 1'b1; 
          							end	//RAM時(shí)鐘使能
          							3'd2:	begin cnt_scan <= cnt_scan + 1'b1; 
          							end	//延時(shí)一個(gè)時(shí)鐘
          							3'd3:	begin ram_lcd_clk_en <= LOW; 
          							ram_data_r <= ram_lcd_data; 
          							cnt_scan <= cnt_scan + 1'b1; 
          							end	//讀取RAM數(shù)據(jù),同時(shí)關(guān)閉RAM時(shí)鐘使能
          							3'd4:	begin 
          							//每個(gè)像素點(diǎn)需要16bit的數(shù)據(jù),SPI每次傳8bit,兩次分別傳送高8位和低8位
          										if(x_cnt>=LCD_W) begin	
          										//當(dāng)一個(gè)數(shù)據(jù)(一行屏幕)寫完后,
          											x_cnt <= 8'd0;	
          											if(y_cnt>=LCD_H) begin y_cnt <= 8'd0; 
          											cnt_scan <= cnt_scan + 1'b1; 
          											end	//如果是最后一行就跳出循環(huán)
          											else begin y_cnt <= y_cnt + 1'b1; 
          											cnt_scan <= 3'd1; 
          											end		//否則跳轉(zhuǎn)至RAM時(shí)鐘使能,循環(huán)刷屏
          										end else begin
          											if(high_word) data_reg <= {1'b1,(ram_data_r[x_cnt]? color_t[15:8]:color_b[15:8])};	
          											//根據(jù)相應(yīng)bit的狀態(tài)判定顯示頂層色或背景色,根據(jù)high_word的狀態(tài)判定寫高8位或低8位
          											else begin data_reg <= {1'b1,(ram_data_r[x_cnt]? color_t[7:0]:color_b[7:0])}; 
          											x_cnt <= x_cnt + 1'b1; 
          											end	//根據(jù)相應(yīng)bit的狀態(tài)判定顯示頂層色或背景色,根據(jù)high_word的狀態(tài)判定寫高8位或低8位,同時(shí)指向下一個(gè)bit
          											high_word <= ~high_word;	
          											//high_word的狀態(tài)翻轉(zhuǎn)
          											num_delay <= 16'd50;	
          											//設(shè)定延時(shí)時(shí)間
          											state <= WRITE;	//跳轉(zhuǎn)至WRITE狀態(tài)
          											state_back <= SCAN;	
          											//執(zhí)行完WRITE及DELAY操作后返回SCAN狀態(tài)
          										end
          									end
          							3'd5:	begin cnt_scan <= 1'b0; 
          							lcd_bl_out <= HIGH; 
          							state <= MAIN; 
          							end
          							default: state <= IDLE;
          						endcase
          					end
          				WRITE:begin	//WRITE狀態(tài),將數(shù)據(jù)按照SPI時(shí)序發(fā)送給屏幕
          						if(cnt_write >= 6'd17) cnt_write <= 1'b0;
          						else cnt_write <= cnt_write + 1'b1;
          						case(cnt_write)
          							6'd0:	begin lcd_dc_out <= data_reg[8]; 
          							end	//9位數(shù)據(jù)最高位為命令數(shù)據(jù)控制位
          							6'd1:	begin lcd_clk_out <= LOW; 
          							lcd_data_out <= data_reg[7]; 
          							end	//先發(fā)高位數(shù)據(jù)
          							6'd2:	begin lcd_clk_out <= HIGH; 
          							end
          							6'd3:	begin lcd_clk_out <= LOW; 
          							lcd_data_out <= data_reg[6]; 
          							end
          							6'd4:	begin lcd_clk_out <= HIGH; 
          							end
          							6'd5:	begin lcd_clk_out <= LOW; 
          							lcd_data_out <= data_reg[5]; 
          							end
          							6'd6:	begin lcd_clk_out <= HIGH; 
          							end
          							6'd7:	begin lcd_clk_out <= LOW; 
          							lcd_data_out <= data_reg[4]; 
          							end
          							6'd8:	begin lcd_clk_out <= HIGH; e
          							nd
          							6'd9:	begin lcd_clk_out <= LOW; 
          							lcd_data_out <= data_reg[3]; 
          							end
          							6'd10:	begin lcd_clk_out <= HIGH; 
          							end
          							6'd11:	begin lcd_clk_out <= LOW; 
          							lcd_data_out <= data_reg[2]; 
          							end
          							6'd12:	begin lcd_clk_out <= HIGH; 
          							end
          							6'd13:	begin lcd_clk_out <= LOW; 
          							lcd_data_out <= data_reg[1]; 
          							end
          							6'd14:	begin lcd_clk_out <= HIGH; 
          							end
          							6'd15:	begin lcd_clk_out <= LOW; 
          							lcd_data_out <= data_reg[0]; 
          							end	//后發(fā)低位數(shù)據(jù)
          							6'd16:	begin lcd_clk_out <= HIGH; 
          							end
          							6'd17:	begin lcd_clk_out <= LOW; 
          							state <= DELAY; 
          							end	//
          							default: state <= IDLE;
          						endcase
          					end
          				DELAY:begin	//延時(shí)狀態(tài)
          						if(cnt_delay >= num_delay) begin
          							cnt_delay <= 16'd0;
          							state <= state_back; 
          						end else cnt_delay <= cnt_delay + 1'b1;
          					end
          				default:state <= IDLE;
          			endcase
          		end
          	end 	// data for setxy
          	initial	//設(shè)定顯示區(qū)域指令及數(shù)據(jù)
          		begin
          			reg_setxy[0]	=	{1'b0,8'h2a};
          			reg_setxy[1]	=	{1'b1,8'h00};
          			reg_setxy[2]	=	{1'b1,8'h00};
          			reg_setxy[3]	=	{1'b1,8'h00};
          			reg_setxy[4]	=	{1'b1,LCD_W-1};
          			reg_setxy[5]	=	{1'b0,8'h2b};
          			reg_setxy[6]	=	{1'b1,8'h00};
          			reg_setxy[7]	=	{1'b1,8'h00};
          			reg_setxy[8]	=	{1'b1,8'h00};
          			reg_setxy[9]	=	{1'b1,LCD_H-1};
          			reg_setxy[10]	=	{1'b0,8'h2c};
          		end 	// data for init
          	initial	//LCD初始化的命令及數(shù)據(jù)
          		begin
          			reg_init[0]		=	{1'b0,8'h11}; 
          			reg_init[1]		=	{1'b0,8'hb1}; 
          			reg_init[2]		=	{1'b1,8'h05}; 
          			reg_init[3]		=	{1'b1,8'h3c}; 
          			reg_init[4]		=	{1'b1,8'h3c}; 
          			reg_init[5]		=	{1'b0,8'hb2}; 
          			reg_init[6]		=	{1'b1,8'h05}; 
          			reg_init[7]		=	{1'b1,8'h3c}; 
          			reg_init[8]		=	{1'b1,8'h3c}; 
          			reg_init[9]		=	{1'b0,8'hb3}; 
          			reg_init[10]	=	{1'b1,8'h05}; 
          			reg_init[11]	=	{1'b1,8'h3c}; 
          			reg_init[12]	=	{1'b1,8'h3c}; 
          			reg_init[13]	=	{1'b1,8'h05}; 
          			reg_init[14]	=	{1'b1,8'h3c}; 
          			reg_init[15]	=	{1'b1,8'h3c}; 
          			reg_init[16]	=	{1'b0,8'hb4}; 
          			reg_init[17]	=	{1'b1,8'h03}; 
          			reg_init[18]	=	{1'b0,8'hc0}; 
          			reg_init[19]	=	{1'b1,8'h28}; 
          			reg_init[20]	=	{1'b1,8'h08}; 
          			reg_init[21]	=	{1'b1,8'h04}; 
          			reg_init[22]	=	{1'b0,8'hc1}; 
          			reg_init[23]	=	{1'b1,8'hc0}; 
          			reg_init[24]	=	{1'b0,8'hc2}; 
          			reg_init[25]	=	{1'b1,8'h0d}; 
          			reg_init[26]	=	{1'b1,8'h00}; 
          			reg_init[27]	=	{1'b0,8'hc3}; 
          			reg_init[28]	=	{1'b1,8'h8d}; 
          			reg_init[29]	=	{1'b1,8'h2a}; 
          			reg_init[30]	=	{1'b0,8'hc4}; 
          			reg_init[31]	=	{1'b1,8'h8d}; 
          			reg_init[32]	=	{1'b1,8'hee}; 
          			reg_init[32]	=	{1'b0,8'hc5}; 
          			reg_init[33]	=	{1'b1,8'h1a}; 
          			reg_init[34]	=	{1'b0,8'h36}; 
          			reg_init[35]	=	{1'b1,8'hc0}; 
          			reg_init[36]	=	{1'b0,8'he0}; 
          			reg_init[37]	=	{1'b1,8'h04}; 
          			reg_init[38]	=	{1'b1,8'h22}; 
          			reg_init[39]	=	{1'b1,8'h07}; 
          			reg_init[40]	=	{1'b1,8'h0a}; 
          			reg_init[41]	=	{1'b1,8'h2e}; 
          			reg_init[42]	=	{1'b1,8'h30}; 
          			reg_init[43]	=	{1'b1,8'h25}; 
          			reg_init[44]	=	{1'b1,8'h2a}; 
          			reg_init[45]	=	{1'b1,8'h28}; 
          			reg_init[46]	=	{1'b1,8'h26}; 
          			reg_init[47]	=	{1'b1,8'h2e}; 
          			reg_init[48]	=	{1'b1,8'h3a}; 
          			reg_init[49]	=	{1'b1,8'h00}; 
          			reg_init[50]	=	{1'b1,8'h01}; 
          			reg_init[51]	=	{1'b1,8'h03}; 
          			reg_init[52]	=	{1'b1,8'h13}; 
          			reg_init[53]	=	{1'b0,8'he1}; 
          			reg_init[54]	=	{1'b1,8'h04}; 
          			reg_init[55]	=	{1'b1,8'h16}; 
          			reg_init[56]	=	{1'b1,8'h06}; 
          			reg_init[57]	=	{1'b1,8'h0d}; 
          			reg_init[58]	=	{1'b1,8'h2d}; 
          			reg_init[59]	=	{1'b1,8'h26}; 
          			reg_init[60]	=	{1'b1,8'h23}; 
          			reg_init[61]	=	{1'b1,8'h27}; 
          			reg_init[62]	=	{1'b1,8'h27}; 
          			reg_init[63]	=	{1'b1,8'h25}; 
          			reg_init[64]	=	{1'b1,8'h2d}; 
          			reg_init[65]	=	{1'b1,8'h3b}; 
          			reg_init[66]	=	{1'b1,8'h00}; 
          			reg_init[67]	=	{1'b1,8'h01}; 
          			reg_init[68]	=	{1'b1,8'h04}; 
          			reg_init[69]	=	{1'b1,8'h13}; 
          			reg_init[70]	=	{1'b0,8'h3a}; 
          			reg_init[71]	=	{1'b1,8'h05}; 
          			reg_init[72]	=	{1'b0,8'h29};  		
          			end	
          			endmodule

          小結(jié)

          本節(jié)主要為大家講解了1.8寸RGB液晶屏圖片顯示的框架,需要大家掌握的同時(shí)自己創(chuàng)建工程,通過整個(gè)設(shè)計(jì)流程,生成FPGA配置文件加載測(cè)試。



          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();