• STM32进阶:使用STM32驱动ST7735S(内附核心源码)


    使用STM32驱动ST7735S(内附核心源码)

    感觉很久很久没有来博客更新了,历经千难万阻,终于做出来了TFT显示屏的SPI驱动,这里分享以下核心源码,接下来一段时间开始准备考科一了,后面有时间了再来更新,有三种模式下的驱动。

    一、软件SPI驱动TFT显示屏

    实验环境:正点原子 STM32F103ZET6 小型系统板
    实验工具:STM32F103ZET6 芯片与 ST7735S芯片(1.44寸TFT显示屏)
    数据交互:STM32 芯片通过 GPIO 输入输出引脚模拟软件SPI和TFT液晶显示屏进行通信、数据传输及命令背景光等控制。
    实验成效:见STM32F103VET6用SPI驱动ST7735S显示屏力所能及的最快速度了

    STM32F103VET6用SPI驱动ST7735S显示屏力所能及的最快速度了

    以下为部分实验源码:

    //spi.c
    #include "spi.h"
    
    extern GPIO_InitTypeDef GPIO_Initure;
    
    void spi_init() {
    	RCC_APB2PeriphClockCmd(SPI_RCC_ENABLE, ENABLE);
    	
    #if SPI_READ_ENABLE
    	//SPI	DATA_IN		PA1
    	GPIO_Initure.GPIO_Mode = SPI_DATA_IN_MODE;
    	GPIO_Initure.GPIO_Pin = SPI_DATA_IN_PIN;
    	GPIO_Initure.GPIO_Speed = SPI_DATA_IN_SPEED;
    	GPIO_Init(SPI_DATA_IN_GPIO, &GPIO_Initure);
    #endif
    	
    #if SPI_WRITE_ENABLE
    	//SPI	DATA_OUT
    	GPIO_Initure.GPIO_Mode = SPI_DATA_OUT_MODE;
    	GPIO_Initure.GPIO_Pin = SPI_DATA_OUT_PIN;
    	GPIO_Initure.GPIO_Speed = SPI_DATA_OUT_SPEED;
    	GPIO_Init(SPI_DATA_OUT_GPIO, &GPIO_Initure);
    #endif
    	
    	//SPI	SCLK
    	GPIO_Initure.GPIO_Mode = SPI_SCLK_MODE;
    	GPIO_Initure.GPIO_Pin = SPI_SCLK_PIN;
    	GPIO_Initure.GPIO_Speed = SPI_SCLK_SPEED;
    	GPIO_Init(SPI_SCLK_GPIO, &GPIO_Initure);
    	
    	//SPI	CS
    	GPIO_Initure.GPIO_Mode = SPI_CS_MODE;
    	GPIO_Initure.GPIO_Pin = SPI_CS_PIN;
    	GPIO_Initure.GPIO_Speed = SPI_CS_SPEED;
    	GPIO_Init(SPI_CS_GPIO, &GPIO_Initure);
    	
    	SPI_CS = 1;	//拉高SPI片选引脚,使通信无效
    	SPI_SCLK = SPI_DATA_OUT = 0;
    }
    
    void spi_start(){
    	SPI_CS = 0;
    }
    
    void spi_write_place(u8 data) {
    	SPI_DATA_OUT = data == 1 ? SPI_DATA_VALID : !SPI_DATA_VALID;
    	SPI_SCLK = !SPI_EDGE_TRIGGERED;
    #if (SPI_SCLK_LOW_KEEP != 0 && SPI_SCLK_HIGH_KEEP != 0)
    	SPI_EDGE_TRIGGERED == 1 ? delay_us(SPI_SCLK_LOW_KEEP) : delay_us(SPI_SCLK_HIGH_KEEP);
    #endif
    	SPI_SCLK = SPI_EDGE_TRIGGERED;
    #if (SPI_SCLK_LOW_KEEP != 0 && SPI_SCLK_HIGH_KEEP != 0)
    	SPI_EDGE_TRIGGERED == 1 ? delay_us(SPI_SCLK_LOW_KEEP) : delay_us(SPI_SCLK_HIGH_KEEP);
    #endif
    }
    
    void spi_write(u8 data){
    	u8 i = 0, place;
    
        for(; i < 8; i ++) {
        	place = data & 1 << (7 - i);
        	spi_write_place(place != 0 ? 1 : 0);
    	} 
    }
    
    u8 spi_read_place() {
    	u8 data;
    
    	SPI_SCLK = !SPI_EDGE_TRIGGERED;
    	SPI_EDGE_TRIGGERED == 1 ? delay_us(SPI_SCLK_LOW_KEEP) : delay_us(SPI_SCLK_HIGH_KEEP);
    	SPI_SCLK = SPI_EDGE_TRIGGERED;
    	data = SPI_DATA_IN;
    	SPI_EDGE_TRIGGERED == 1 ? delay_us(SPI_SCLK_LOW_KEEP) : delay_us(SPI_SCLK_HIGH_KEEP);
    
    	return data;
    }
    
    u8 spi_read(){
    	u8 i = 0, data, place;
    
    	for(; i < 8; i ++) {
    		place = spi_read_place();
    		data |= place << (7 - i);
    	}
    	
    	return data;
    }
    
    void spi_stop() {
    	SPI_CS = 1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    //spi.h
    #ifndef __SPI_H
    #define __SPI_H
    
    #include "sys.h"
    #include "delay.h"
    
    #define SPI_RCC_ENABLE		RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOF
    
    #define SPI_DATA_IN_MODE	GPIO_Mode_IN_FLOATING
    #define SPI_DATA_IN_PIN		GPIO_Pin_1
    #define SPI_DATA_IN_SPEED	GPIO_Speed_50MHz
    #define SPI_DATA_IN_GPIO	GPIOA
    
    #define SPI_DATA_OUT_MODE	GPIO_Mode_Out_PP
    #define SPI_DATA_OUT_PIN	GPIO_Pin_4
    #define SPI_DATA_OUT_SPEED	GPIO_Speed_50MHz
    #define SPI_DATA_OUT_GPIO	GPIOC
    
    #define SPI_SCLK_MODE		GPIO_Mode_Out_PP
    #define SPI_SCLK_PIN		GPIO_Pin_5
    #define SPI_SCLK_SPEED		GPIO_Speed_50MHz
    #define SPI_SCLK_GPIO		GPIOC
    
    #define SPI_CS_MODE			GPIO_Mode_Out_PP
    #define SPI_CS_PIN			GPIO_Pin_10
    #define SPI_CS_SPEED		GPIO_Speed_50MHz
    #define SPI_CS_GPIO			GPIOF
    
    #define SPI_DATA_IN 	PAin(1)
    #define SPI_DATA_OUT 	PCout(4)
    #define SPI_SCLK		PCout(5)
    #define SPI_CS			PFout(10)
    
    #define SPI_SCLK_HIGH_KEEP	0	//时钟信号低电平维持时间
    #define SPI_SCLK_LOW_KEEP	0	//时钟信号高电平维持时间
    
    #define SPI_DATA_VALID		1	//0-低电平有效, 1-高电平有效
    #define SPI_EDGE_TRIGGERED	1	//0-下降沿有效, 1-上升沿有效
    
    #define SPI_WRITE_ENABLE	1	//0-禁止SPI写入数据,1-使能SPI读取数据
    #define SPI_READ_ENABLE		0	//0-禁止SPI读取数据,1-使能SPI写入数据
    
    void spi_init(void);
    void spi_start(void);
    void spi_write_place(u8 data);
    void spi_write(u8 data);
    u8 spi_read_place(void);
    u8 spi_read(void);
    void spi_stop(void);
    
    #endif	//__SPI_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    //lcd.c
    #include "lcd.h"
    
    extern GPIO_InitTypeDef GPIO_Initure;
    
    void lcd_init() {
    	RCC_APB2PeriphClockCmd(LCD_RCC_ENABLE, ENABLE);
    	
    	//RESET
    	GPIO_Initure.GPIO_Mode = LCD_RESET_MODE;
    	GPIO_Initure.GPIO_Pin = LCD_RESET_PIN;
    	GPIO_Initure.GPIO_Speed = LCD_RESET_SPEED;
    	GPIO_Init(LCD_RESET_GPIO, &GPIO_Initure);
    	
    	//CMD DATA
    	GPIO_Initure.GPIO_Mode = LCD_CMD_DATA_MODE;
    	GPIO_Initure.GPIO_Pin = LCD_CMD_DATA_PIN;
    	GPIO_Initure.GPIO_Speed = LCD_CMD_DATA_SPEED;
    	GPIO_Init(LCD_CMD_DATA_GPIO, &GPIO_Initure);
    	
    	//BACK LIGHT
    	GPIO_Initure.GPIO_Mode = LCD_BACK_LIGHT_MODE;
    	GPIO_Initure.GPIO_Pin = LCD_BACK_LIGHT_PIN;
    	GPIO_Initure.GPIO_Speed = LCD_BACK_LIGHT_SPEED;
    	GPIO_Init(LCD_BACK_LIGHT_GPIO, &GPIO_Initure);
    	
    	LCD_RESRT = LCD_CMD_DATA = LCD_BACK_LIGHT = 1;
    	
    	spi_init();
    	lcd_config();
    }
    
    void lcd_config() {
    	//===============reset============================
    	lcd_reset();
    
    	//===============exit sleep=======================
    	lcd_write(TFT_CMD ,LCD_SLPOUT);
    	delay_ms(120);
    
    	//===============frame set========================
    	//Frame rate = fosc / ((RTNA x 2 + 40) x (LINE + FPA + BPA +2))
    //	lcd_write(TFT_CMD, LCD_FRMCTR1);
    //	lcd_write(TFT_DATA, 0x02);
    //	lcd_write(TFT_DATA, 0x35);
    //	lcd_write(TFT_DATA, 0x36);
    //	
    //	lcd_write(TFT_CMD, LCD_FRMCTR2);
    //	lcd_write(TFT_DATA, 0x02);
    //	lcd_write(TFT_DATA, 0x35);
    //	lcd_write(TFT_DATA, 0x36);
    //	
    //	lcd_write(TFT_CMD, LCD_FRMCTR3);
    //	lcd_write(TFT_DATA, 0x02);
    //	lcd_write(TFT_DATA, 0x35);
    //	lcd_write(TFT_DATA, 0x36);
    //	lcd_write(TFT_DATA, 0x02);
    //	lcd_write(TFT_DATA, 0x35);
    //	lcd_write(TFT_DATA, 0x36);
    	
    	lcd_write(TFT_CMD, LCD_FRMCTR1);
    	lcd_write(TFT_DATA, 0x01);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x2D);
    	
    	lcd_write(TFT_CMD, LCD_FRMCTR2);
    	lcd_write(TFT_DATA, 0x01);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x2D);
    	
    	lcd_write(TFT_CMD, LCD_FRMCTR3);
    	lcd_write(TFT_DATA, 0x01);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x2D);
    	lcd_write(TFT_DATA, 0x01);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x2D);
    	
    	//===============inversion of control=============
    	lcd_write(TFT_CMD, LCD_INVCRT);
    	lcd_write(TFT_DATA, 0x03);
    
    	//===============power set========================
    	lcd_write(TFT_CMD, LCD_PWCTR1);
    	lcd_write(TFT_DATA, 0xA2);
    	lcd_write(TFT_DATA, 0x02);
    	lcd_write(TFT_DATA, 0x84);
    		
    	lcd_write(TFT_CMD, LCD_PWCTR2);
    	lcd_write(TFT_DATA, 0xC5);
    
    	lcd_write(TFT_CMD, LCD_PWCTR3);
    	lcd_write(TFT_DATA, 0x0D);
    	lcd_write(TFT_DATA, 0x00);
    	
    	lcd_write(TFT_CMD, LCD_PWCTR4);
    	lcd_write(TFT_DATA, 0x8D);
    	lcd_write(TFT_DATA, 0x2A);
    	
    	lcd_write(TFT_CMD, LCD_PWCTR5);
    	lcd_write(TFT_DATA, 0x8D);
    	lcd_write(TFT_DATA, 0xEE);
    
    	//===============vcom set=========================
    	lcd_write(TFT_CMD, LCD_VMCTR1);
    	lcd_write(TFT_DATA, 0x03);
    
    	//===============color format set=================
    	set_color_format(0x05);
    	
    	//===============scanning direction set===========
    	set_scan_direction(0x08);
    	
    	//===============gamma sequence set===============
    	lcd_write(TFT_CMD, LCD_GMCTRP1);
    	lcd_write(TFT_DATA, 0x12);
    	lcd_write(TFT_DATA, 0x1C);
    	lcd_write(TFT_DATA, 0x10);
    	lcd_write(TFT_DATA, 0x18);
    	lcd_write(TFT_DATA, 0x33);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x25);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x27);
    	lcd_write(TFT_DATA, 0x2F);
    	lcd_write(TFT_DATA, 0x3C);
    	lcd_write(TFT_DATA, 0x00);
    	lcd_write(TFT_DATA, 0x03);
    	lcd_write(TFT_DATA, 0x03);
    	lcd_write(TFT_DATA, 0x10);
    
    	lcd_write(TFT_CMD, LCD_GMCTRN1);
    	lcd_write(TFT_DATA, 0x12);
    	lcd_write(TFT_DATA, 0x1C);
    	lcd_write(TFT_DATA, 0x10);
    	lcd_write(TFT_DATA, 0x18);
    	lcd_write(TFT_DATA, 0x2D);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x23);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x26);
    	lcd_write(TFT_DATA, 0x2F);
    	lcd_write(TFT_DATA, 0x3B);
    	lcd_write(TFT_DATA, 0x00);
    	lcd_write(TFT_DATA, 0x03);
    	lcd_write(TFT_DATA, 0x03);
    	lcd_write(TFT_DATA, 0x10);
    
    	//===============partial area set=================
    	lcd_write(TFT_CMD, LCD_PTLAR);             
    	lcd_write(TFT_DATA, 0x00);             
    	lcd_write(TFT_DATA, 0x00);             
    	lcd_write(TFT_DATA, 0x00);             
    	lcd_write(TFT_DATA, 0x80);
    	
    	//===============partial mode on==================
    	lcd_write(TFT_CMD, LCD_PTLON);
    
    	//===============display on=======================
    	lcd_write(TFT_CMD, LCD_DISPON);
    }
    
    void lcd_reset() {
    	LCD_RESRT = 1;
    	delay_ms(60);
    	LCD_RESRT = 0;
    	delay_ms(120);
    	LCD_RESRT = 1;
    	delay_ms(60);
    }
    
    void lcd_write(u8 c_d, u8 data) {
    	LCD_CMD_DATA = c_d;
    	spi_start();
    	spi_write(data);
    	spi_stop();
    }
    
    void set_background(u16 color) {
    	u8 i,j;
    	set_frame_size(0,0x7F,0x00,0x7F);
    
    	for(i = 0; i < 128; i ++) {
    	    for(j = 0; j < 128; j ++) {
    			lcd_write(TFT_DATA, color >> 8);
    			lcd_write(TFT_DATA, color);
    		}
    	}
    }
    
    void set_scan_direction(u8 data) {
    	lcd_write(TFT_CMD, LCD_MADCTL);
    	lcd_write(TFT_DATA, data);
    }
    
    void set_color_format(u8 data) {
    	lcd_write(TFT_CMD, LCD_COLMOD);
    	lcd_write(TFT_DATA, data);
    }
    
    void set_frame_size(u16 x_start, u16 x_end, u16 y_start, u16 y_end) {
    	lcd_write(TFT_CMD, LCD_CASET);
    	lcd_write(TFT_DATA, x_start >> 8);
    	lcd_write(TFT_DATA, x_start);
    	lcd_write(TFT_DATA, x_end >> 8);
    	lcd_write(TFT_DATA, x_end);
    	
    	lcd_write(TFT_CMD, LCD_RASET);
    	lcd_write(TFT_DATA, y_start >> 8);
    	lcd_write(TFT_DATA, y_start);
    	lcd_write(TFT_DATA, y_end >> 8);
    	lcd_write(TFT_DATA, y_end);
    	
    	lcd_write(TFT_CMD, LCD_RAMWR);
    }
    
    void set_point(u16 x, u16 y, u16 color) {
    	set_frame_size(x, x + 1, y, y + 1);
    
    	lcd_write(TFT_DATA, color >> 8);
    	lcd_write(TFT_DATA, color);
    }
    
    void set_rectangle(u16 x_start, u16 x_end, u16 y_start, u16 y_end, u16 color) {
    	u8 i, j, w, h;
    	
    	w = x_end - x_start;
    	h = y_end - y_start;
    	
    	set_frame_size(x_start, x_end, y_start, y_end);
    	
    	for(i = 0; i < w; i ++) {
    	    for(j = 0; j < h; j ++) {
    			lcd_write(TFT_DATA, color >> 8);
    			lcd_write(TFT_DATA, color);
    		}
    	}
    }
    
    void DispGrayHor16(void) {
    	u8 i,j,k;
    
       	set_frame_size(0, 127, 0, 127);
    
    	for(i = 0;i < 128; i ++) {	
    		for(j=0;j<16;j++) {
    	        for(k=0;k< 128 / 16; k ++) {		
    				lcd_write(TFT_DATA, ((j*2)<<3)|((j*4)>>3));		 
    				lcd_write(TFT_DATA, ((j*4)<<5)|(j*2));
    			} 
    		}
    	}
    }
    
    void DispFrame(void) {
    	u8 i,j;
    	
    	set_frame_size(0, 127, 0, 127);
    
    	lcd_write(TFT_DATA, 0xF8);
    	lcd_write(TFT_DATA, 0x00);
    	
    	for(i = 0; i < 126; i ++){
    		lcd_write(TFT_DATA, 0xFF);
    		lcd_write(TFT_DATA, 0xFF);
    	}
    	
    	lcd_write(TFT_DATA, 0x00);
    	lcd_write(TFT_DATA, 0x1F);
    
    	for(j = 0; j < 126; j ++)
    	{
    		lcd_write(TFT_DATA, 0xF8);
    		lcd_write(TFT_DATA, 0x00);
    		for(i = 0; i < 126; i ++) {
    			lcd_write(TFT_DATA, 0x00);
    			lcd_write(TFT_DATA, 0x00);
    		}
    		
    		lcd_write(TFT_DATA, 0x00);
    		lcd_write(TFT_DATA, 0x1F);
    	}
    	
    	lcd_write(TFT_DATA, 0xf8);
    	lcd_write(TFT_DATA, 0x00);
    	
    	for(i=0;i<126;i++){
    		lcd_write(TFT_DATA, 0xFF);
    		lcd_write(TFT_DATA, 0xFF);
    	}
    	
    	lcd_write(TFT_DATA, 0x00);
    	lcd_write(TFT_DATA, 0x1F);
    	
    }
    
    void DispBand(void) {
    	u8 i,j,k;
    	u16 color[8]={0x001f,0x07e0,0xf800,0x07ff,0xf81f,0xffe0,0x0000,0xffff};
    //	u16 color[8]={0xf800,0xf800,0x07e0,0x07e0,0x001f,0x001f,0xffff,0xffff};//0x94B2
    	//unsigned int gray16[]={0x0000,0x1082,0x2104,0x3186,0x42,0x08,0x528a,0x630c,0x738e,0x7bcf,0x9492,0xa514,0xb596,0xc618,0xd69a,0xe71c,0xffff};
    
    	lcd_write(TFT_CMD, 0x36); //Set Scanning Direction
    	lcd_write(TFT_DATA, 0x08); //0xc8
    
       	set_frame_size(0, 127, 0, 127);																								  
    
    	for(i=0;i < 8;i++)
    	{
    		for(j=0;j < 128 / 8;j++)
    		{
    	        for(k=0;k< 128;k++)
    			{
    				lcd_write(TFT_DATA, color[i]>>8); 
    				lcd_write(TFT_DATA, color[i]);   
    			} 
    		}
    	}
    }
    
    void DispPic(u8 x,u8 y,u8 w, u8 h,const unsigned char *p) {
    	unsigned int i,j;
    	unsigned char pic_h,pic_l;
    	
    //	lcd_write(TFT_CMD, 0x36); //Set Scanning Direction
    //	lcd_write(TFT_DATA, 0xC8); //0xc8
    	
    	set_frame_size(x, x + w - 1, y, y + h - 1);    
    
    	for(i = 0; i < h; i ++) {
    	    for(j = 0; j < w; j ++) {    
    			pic_l=(*p) ;
    			pic_h=(*(p+1)) ;
    			lcd_write(TFT_DATA, pic_h);				  
    			lcd_write(TFT_DATA, pic_l);
    			p=p+2;
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    //lcd.h
    #ifndef __LCD_H
    #define __LCD_H
    
    #include "sys.h"
    #include "spi.h"
    
    #define LCD_RCC_ENABLE		RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOF
    
    #define LCD_RESRT 		PBout(2)
    #define LCD_CMD_DATA	PBout(1)
    #define LCD_BACK_LIGHT	PFout(11)
    
    #define LCD_RESET_MODE			GPIO_Mode_Out_PP
    #define LCD_RESET_PIN			GPIO_Pin_2
    #define LCD_RESET_SPEED			GPIO_Speed_50MHz
    #define LCD_RESET_GPIO			GPIOB
    
    #define LCD_CMD_DATA_MODE		GPIO_Mode_Out_PP
    #define LCD_CMD_DATA_PIN		GPIO_Pin_1
    #define LCD_CMD_DATA_SPEED		GPIO_Speed_50MHz
    #define LCD_CMD_DATA_GPIO		GPIOB
    
    #define LCD_BACK_LIGHT_MODE		GPIO_Mode_Out_PP
    #define LCD_BACK_LIGHT_PIN		GPIO_Pin_11
    #define LCD_BACK_LIGHT_SPEED	GPIO_Speed_50MHz
    #define LCD_BACK_LIGHT_GPIO		GPIOF
    
    #define LCD_NOP			0x00	//空命令
    #define LCD_SWRESET		0x01	//软件复位,在睡眠和显示模式下,重置软件后需等待120ms后方可执行下一条指令
    #define LCD_RDDID		0x04	//读取LCD的制造商ID(8位)、驱动版本ID(最高位为1,7位)、驱动程序ID(8位)
    #define LCD_RDDST		0x09	//读取显示屏所有状态参数
    #define LCD_RDDPM		0x0A	//读取显示屏能量模式
    #define LCD_RDDMADCTL	0x0B	//读取显示屏MADCTL
    #define LCD_RDDCOLMOD	0x0C	//读取显示屏像素定义
    #define LCD_RDDIM		0x0D	//读取显示屏图片模式
    #define LCD_RDDSM		0x0E	//读取显示屏单信号模式
    #define LCD_RDDSDR		0x0F	//读取显示屏自我诊断结果
    #define LCD_SLPIN		0x10	//进入最小功耗模式
    #define LCD_SLPOUT 		0x11	//关闭睡眠模式
    #define LCD_PTLON		0x12	//打开Partial模式
    #define LCD_NORON		0x13	//恢复到正常模式
    #define LCD_INVOFF		0x20	//显示反转模式中恢复
    #define LCD_INVON		0x21	//进入反向显示模式
    #define LCD_GAMSET		0x26	//当前显示选择所需的伽马曲线
    #define LCD_DISPOFF		0x28	//关闭显示,帧内存的输出被禁用
    #define LCD_DISPON		0x29	//开启显示,帧内存的输出被启用
    #define LCD_CASET		0x2A	//列地址设置,每个值代表帧内存中的一列
    #define LCD_RASET		0x2B	//行地址设置,每个值代表帧内存中的一列
    #define LCD_RAMWR		0x2C	//写入内存
    #define LCD_RGBSET		0x2D	//颜色模式设置
    #define LCD_RAMRD		0x2E	//读取内存
    #define LCD_PTLAR		0x30	//部分模式的显示区域设置
    #define LCD_SCRLAR		0x33	//定义垂直滚动区域的显示
    #define LCD_TEOFF		0x34	//关闭(Active Low) TE信号线的撕裂效应输出信号
    #define LCD_TEON		0x35	//打开TE信号线的撕裂效果输出信号
    #define LCD_MADCTL		0x36	//定义帧内存的读写扫描方向
    #define LCD_VSCSAD		0x37	//设置垂直滚动起始地址,此命令与垂直滚动定义(33h)一起使用
    #define LCD_IDMOFF		0x38	//关闭空闲模式
    #define LCD_IDMON		0x39	//开启空闲模式
    #define LCD_COLMOD		0x3A	//定义通过MCU接口传输的RGB图片数据的格式
    #define LCD_FRMCTR1		0xB1	//设置全色正常模式的帧频
    #define LCD_FRMCTR2 	0xB2	//设置空闲模式的帧频
    #define LCD_FRMCTR3 	0xB3	//设置部分模式/全色的帧频率
    #define LCD_INVCRT 		0xB4	//反转模式控制
    #define LCD_PWCTR1 		0xC0	//设置AVDD、MODE、VRHP、VRHN
    #define LCD_PWCTR2 		0xC1	//设置VGH与VGL的供电功率
    #define LCD_PWCTR3 		0xC2	//设置正常模式/全色模式下的运放的电流
    #define LCD_PWCTR4 		0xC3	//设置空闲模式/八色模式下的运放的电流
    #define LCD_PWCTR5 		0xC4	//设置部分模式/全色模式下的运放的电流
    #define LCD_VMCTR1 		0xC5	//设置VCOM电压电平以减少闪烁问题
    #define LCD_VMOFCTR		0xC7	//VCOM偏移控制,在使用命令0xC7之前,命令0xD9的位VMF_EN必须启用(设置为1)
    #define LCD_WRID2		0xD1	//写入LCD模块版本的7位数据,保存到NVM
    #define LCD_WRID3		0xD2	//写入项目代码模块的8位数据,保存到NVM
    #define LCD_NVFCTR1		0xD9	//NVM状态控制
    #define LCD_RDID1		0xDA	//读字节返回8位LCD模块的制造商ID
    #define LCD_RDID2		0xDB	//读字节返回8位LCD模块/驱动程序版本ID
    #define LCD_RDID3		0xDC	//读字节返回8位LCD模块/驱动ID
    #define LCD_NVFCTR2		0xDE	//NVM读取命令
    #define LCD_NVFCTR3		0xDF	//NVM写取命令
    #define LCD_GMCTRP1		0xE0	//Gamma ‘+’ Polarity Correction Characteristics Setting
    #define LCD_GMCTRN1		0xE1	//Gamma ‘+’ Polarity Correction Characteristics Setting
    #define LCD_GCV			0xFC	//自动调节门泵时钟,节省功耗
    
    
    enum TFT_DATA_TYPE {
    	TFT_CMD = 0,
    	TFT_DATA
    };
    
    void lcd_init(void);
    void lcd_config(void);
    void lcd_reset(void);
    void lcd_write(u8 c_d, u8 data);
    void set_background(u16 color);
    void set_scan_direction(u8 data);
    void set_color_format(u8 data);
    void set_frame_size(u16 x_start, u16 x_end, u16 y_start, u16 y_end);
    void set_point(u16 x, u16 y, u16 color);
    void set_rectangle(u16 x_start, u16 x_end, u16 y_start, u16 y_end, u16 color);
    void DispGrayHor16(void);
    void DispFrame(void);
    void DispBand(void);
    void DispPic(u8 x,u8 y,u8 w, u8 h,const unsigned char *p);
    
    #endif	//__LCD_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106

    二、硬件SPI驱动TFT显示屏

    实验环境:正点原子 STM32F103ZET6 小型系统板
    实验工具:STM32F103ZET6 芯片与 ST7735S芯片(1.44寸TFT显示屏)
    数据交互:STM32 芯片通过 GPIO 输入输出引脚输出SPI和TFT液晶显示屏进行通信、数据传输及命令背景光等控制。
    实验成效:见STM32F103VET6硬件SPI确实比软件SPI快很多

    STM32F103VET6硬件SPI确实比软件SPI快很多

    以下为部分实验源码:

    //spi.c
    #include "spi.h"
    
    extern GPIO_InitTypeDef GPIO_Initure;
    SPI_InitTypeDef SPI_Initure;
    
    void spi_init() {
    	RCC_APB2PeriphClockCmd(SPI_RCC_ENABLE, ENABLE);
    	
    #if SPI_READ_ENABLE
    	//SPI	DATA_IN		PA1
    	GPIO_Initure.GPIO_Mode = SPI_DATA_IN_MODE;
    	GPIO_Initure.GPIO_Pin = SPI_DATA_IN_PIN;
    	GPIO_Initure.GPIO_Speed = SPI_DATA_IN_SPEED;
    	GPIO_Init(SPI_DATA_IN_GPIO, &GPIO_Initure);
    #endif
    	
    #if SPI_WRITE_ENABLE
    	//SPI	DATA_OUT
    	GPIO_Initure.GPIO_Mode = SPI_DATA_OUT_MODE;
    	GPIO_Initure.GPIO_Pin = SPI_DATA_OUT_PIN;
    	GPIO_Initure.GPIO_Speed = SPI_DATA_OUT_SPEED;
    	GPIO_Init(SPI_DATA_OUT_GPIO, &GPIO_Initure);
    #endif
    	
    	//SPI	SCLK
    	GPIO_Initure.GPIO_Mode = SPI_SCLK_MODE;
    	GPIO_Initure.GPIO_Pin = SPI_SCLK_PIN;
    	GPIO_Initure.GPIO_Speed = SPI_SCLK_SPEED;
    	GPIO_Init(SPI_SCLK_GPIO, &GPIO_Initure);
    	
    	//SPI	CS
    	GPIO_Initure.GPIO_Mode = SPI_CS_MODE;
    	GPIO_Initure.GPIO_Pin = SPI_CS_PIN;
    	GPIO_Initure.GPIO_Speed = SPI_CS_SPEED;
    	GPIO_Init(SPI_CS_GPIO, &GPIO_Initure);
    	
    	SPI_CS = 1;
    	
    	SPI_Initure.SPI_BaudRatePrescaler	= SPI_BaudRatePrescaler_2;	// 使分频值达到最大
    	SPI_Initure.SPI_CPHA				= SPI_CPHA_1Edge;			// 上降沿有效
    	SPI_Initure.SPI_CPOL				= SPI_CPOL_Low;				// 高电平有效
    	SPI_Initure.SPI_CRCPolynomial		= 7;						// 无 CRC 校验
    	SPI_Initure.SPI_DataSize			= SPI_DataSize_8b;			// 发送字长为 8 位
    	SPI_Initure.SPI_Direction			= SPI_Direction_1Line_Tx;	// 方向为发送
    	SPI_Initure.SPI_FirstBit			= SPI_FirstBit_MSB;			// 高位先行
    	SPI_Initure.SPI_Mode				= SPI_Mode_Master;			// 主机模式
    	SPI_Initure.SPI_NSS					= SPI_NSS_Soft;				// 软件控制
    	SPI_Init(SPI1,&SPI_Initure);
    	
    	SPI_Cmd(SPI1, ENABLE);
    	
    	spi_write(0xff);
    }
    
    void spi_write(u8 data) {
    	u16 next = 0;
    	while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) {
    		if(++ next > 500) return;
    	}
    	SPI_I2S_SendData(SPI1, data);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    //spi.h
    #ifndef __SPI_H
    #define __SPI_H
    
    #include "sys.h"
    #include "delay.h"
    
    #define SPI_RCC_ENABLE		RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1
    
    #define SPI_CS PAout(4)
    
    #define SPI_DATA_IN_MODE	GPIO_Mode_IN_FLOATING
    #define SPI_DATA_IN_PIN		GPIO_Pin_6
    #define SPI_DATA_IN_SPEED	GPIO_Speed_50MHz
    #define SPI_DATA_IN_GPIO	GPIOA
    
    #define SPI_DATA_OUT_MODE	GPIO_Mode_AF_PP
    #define SPI_DATA_OUT_PIN	GPIO_Pin_7
    #define SPI_DATA_OUT_SPEED	GPIO_Speed_50MHz
    #define SPI_DATA_OUT_GPIO	GPIOA
    
    #define SPI_SCLK_MODE		GPIO_Mode_AF_PP
    #define SPI_SCLK_PIN		GPIO_Pin_5
    #define SPI_SCLK_SPEED		GPIO_Speed_50MHz
    #define SPI_SCLK_GPIO		GPIOA
    
    #define SPI_CS_MODE			GPIO_Mode_Out_PP
    #define SPI_CS_PIN			GPIO_Pin_4
    #define SPI_CS_SPEED		GPIO_Speed_50MHz
    #define SPI_CS_GPIO			GPIOA
    
    #define SPI_WRITE_ENABLE	1	//0-禁止SPI写入数据,1-使能SPI读取数据
    #define SPI_READ_ENABLE		0	//0-禁止SPI读取数据,1-使能SPI写入数据
    
    void spi_init(void);
    void spi_write(u8 data);
    
    #endif	//__SPI_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    //lcd.c
    #include "lcd.h"
    
    extern GPIO_InitTypeDef GPIO_Initure;
    
    void lcd_init() {
    	RCC_APB2PeriphClockCmd(LCD_RCC_ENABLE, ENABLE);
    	
    	//RESET
    	GPIO_Initure.GPIO_Mode = LCD_RESET_MODE;
    	GPIO_Initure.GPIO_Pin = LCD_RESET_PIN;
    	GPIO_Initure.GPIO_Speed = LCD_RESET_SPEED;
    	GPIO_Init(LCD_RESET_GPIO, &GPIO_Initure);
    	
    	//CMD DATA
    	GPIO_Initure.GPIO_Mode = LCD_CMD_DATA_MODE;
    	GPIO_Initure.GPIO_Pin = LCD_CMD_DATA_PIN;
    	GPIO_Initure.GPIO_Speed = LCD_CMD_DATA_SPEED;
    	GPIO_Init(LCD_CMD_DATA_GPIO, &GPIO_Initure);
    	
    	//BACK LIGHT
    	GPIO_Initure.GPIO_Mode = LCD_BACK_LIGHT_MODE;
    	GPIO_Initure.GPIO_Pin = LCD_BACK_LIGHT_PIN;
    	GPIO_Initure.GPIO_Speed = LCD_BACK_LIGHT_SPEED;
    	GPIO_Init(LCD_BACK_LIGHT_GPIO, &GPIO_Initure);
    	
    	LCD_RESRT = LCD_CMD_DATA = LCD_BACK_LIGHT = 1;
    	
    	spi_init();
    	lcd_config();
    }
    
    void lcd_config() {
    	//===============reset============================
    	lcd_reset();
    
    	//===============exit sleep=======================
    	lcd_write(TFT_CMD ,LCD_SLPOUT);
    	delay_ms(120);
    
    	//===============frame set========================
    	//Frame rate = fosc / ((RTNA x 2 + 40) x (LINE + FPA + BPA +2))
    //	lcd_write(TFT_CMD, LCD_FRMCTR1);
    //	lcd_write(TFT_DATA, 0x02);
    //	lcd_write(TFT_DATA, 0x35);
    //	lcd_write(TFT_DATA, 0x36);
    //	
    //	lcd_write(TFT_CMD, LCD_FRMCTR2);
    //	lcd_write(TFT_DATA, 0x02);
    //	lcd_write(TFT_DATA, 0x35);
    //	lcd_write(TFT_DATA, 0x36);
    //	
    //	lcd_write(TFT_CMD, LCD_FRMCTR3);
    //	lcd_write(TFT_DATA, 0x02);
    //	lcd_write(TFT_DATA, 0x35);
    //	lcd_write(TFT_DATA, 0x36);
    //	lcd_write(TFT_DATA, 0x02);
    //	lcd_write(TFT_DATA, 0x35);
    //	lcd_write(TFT_DATA, 0x36);
    	
    	lcd_write(TFT_CMD, LCD_FRMCTR1);
    	lcd_write(TFT_DATA, 0x01);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x2D);
    	
    	lcd_write(TFT_CMD, LCD_FRMCTR2);
    	lcd_write(TFT_DATA, 0x01);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x2D);
    	
    	lcd_write(TFT_CMD, LCD_FRMCTR3);
    	lcd_write(TFT_DATA, 0x01);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x2D);
    	lcd_write(TFT_DATA, 0x01);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x2D);
    	
    	//===============inversion of control=============
    	lcd_write(TFT_CMD, LCD_INVCRT);
    	lcd_write(TFT_DATA, 0x03);
    
    	//===============power set========================
    	lcd_write(TFT_CMD, LCD_PWCTR1);
    	lcd_write(TFT_DATA, 0xA2);
    	lcd_write(TFT_DATA, 0x02);
    	lcd_write(TFT_DATA, 0x84);
    		
    	lcd_write(TFT_CMD, LCD_PWCTR2);
    	lcd_write(TFT_DATA, 0xC5);
    
    	lcd_write(TFT_CMD, LCD_PWCTR3);
    	lcd_write(TFT_DATA, 0x0D);
    	lcd_write(TFT_DATA, 0x00);
    	
    	lcd_write(TFT_CMD, LCD_PWCTR4);
    	lcd_write(TFT_DATA, 0x8D);
    	lcd_write(TFT_DATA, 0x2A);
    	
    	lcd_write(TFT_CMD, LCD_PWCTR5);
    	lcd_write(TFT_DATA, 0x8D);
    	lcd_write(TFT_DATA, 0xEE);
    
    	//===============vcom set=========================
    	lcd_write(TFT_CMD, LCD_VMCTR1);
    	lcd_write(TFT_DATA, 0x03);
    
    	//===============color format set=================
    	set_color_format(0x05);
    	
    	//===============scanning direction set===========
    	set_scan_direction(0x08);
    	
    	//===============gamma sequence set===============
    	lcd_write(TFT_CMD, LCD_GMCTRP1);
    	lcd_write(TFT_DATA, 0x12);
    	lcd_write(TFT_DATA, 0x1C);
    	lcd_write(TFT_DATA, 0x10);
    	lcd_write(TFT_DATA, 0x18);
    	lcd_write(TFT_DATA, 0x33);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x25);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x27);
    	lcd_write(TFT_DATA, 0x2F);
    	lcd_write(TFT_DATA, 0x3C);
    	lcd_write(TFT_DATA, 0x00);
    	lcd_write(TFT_DATA, 0x03);
    	lcd_write(TFT_DATA, 0x03);
    	lcd_write(TFT_DATA, 0x10);
    
    	lcd_write(TFT_CMD, LCD_GMCTRN1);
    	lcd_write(TFT_DATA, 0x12);
    	lcd_write(TFT_DATA, 0x1C);
    	lcd_write(TFT_DATA, 0x10);
    	lcd_write(TFT_DATA, 0x18);
    	lcd_write(TFT_DATA, 0x2D);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x23);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x26);
    	lcd_write(TFT_DATA, 0x2F);
    	lcd_write(TFT_DATA, 0x3B);
    	lcd_write(TFT_DATA, 0x00);
    	lcd_write(TFT_DATA, 0x03);
    	lcd_write(TFT_DATA, 0x03);
    	lcd_write(TFT_DATA, 0x10);
    
    	//===============partial area set=================
    	lcd_write(TFT_CMD, LCD_PTLAR);             
    	lcd_write(TFT_DATA, 0x00);             
    	lcd_write(TFT_DATA, 0x00);             
    	lcd_write(TFT_DATA, 0x00);             
    	lcd_write(TFT_DATA, 0x80);
    	
    	//===============partial mode on==================
    	lcd_write(TFT_CMD, LCD_PTLON);
    
    	//===============display on=======================
    	lcd_write(TFT_CMD, LCD_DISPON);
    }
    
    void lcd_reset() {
    	LCD_RESRT = 1;
    	delay_ms(60);
    	LCD_RESRT = 0;
    	delay_ms(120);
    	LCD_RESRT = 1;
    	delay_ms(60);
    }
    
    void lcd_write(u8 c_d, u8 data) {
    	LCD_CMD_DATA = c_d;
    	SPI_CS = 0;
    	spi_write(data);
    	SPI_CS = 1;
    }
    
    void set_background(u16 color) {
    	u8 i,j;
    	set_frame_size(0,0x7F,0x00,0x7F);
    
    	for(i = 0; i < 128; i ++) {
    	    for(j = 0; j < 128; j ++) {
    			lcd_write(TFT_DATA, color >> 8);
    			lcd_write(TFT_DATA, color);
    		}
    	}
    }
    
    void set_scan_direction(u8 data) {
    	lcd_write(TFT_CMD, LCD_MADCTL);
    	lcd_write(TFT_DATA, data);
    }
    
    void set_color_format(u8 data) {
    	lcd_write(TFT_CMD, LCD_COLMOD);
    	lcd_write(TFT_DATA, data);
    }
    
    void set_frame_size(u16 x_start, u16 x_end, u16 y_start, u16 y_end) {
    	lcd_write(TFT_CMD, LCD_CASET);
    	lcd_write(TFT_DATA, x_start >> 8);
    	lcd_write(TFT_DATA, x_start);
    	lcd_write(TFT_DATA, x_end >> 8);
    	lcd_write(TFT_DATA, x_end);
    	
    	lcd_write(TFT_CMD, LCD_RASET);
    	lcd_write(TFT_DATA, y_start >> 8);
    	lcd_write(TFT_DATA, y_start);
    	lcd_write(TFT_DATA, y_end >> 8);
    	lcd_write(TFT_DATA, y_end);
    	
    	lcd_write(TFT_CMD, LCD_RAMWR);
    }
    
    void set_point(u16 x, u16 y, u16 color) {
    	set_frame_size(x, x + 1, y, y + 1);
    
    	lcd_write(TFT_DATA, color >> 8);
    	lcd_write(TFT_DATA, color);
    }
    
    void set_rectangle(u16 x_start, u16 x_end, u16 y_start, u16 y_end, u16 color) {
    	u8 i, j, w, h;
    	
    	w = x_end - x_start;
    	h = y_end - y_start;
    	
    	set_frame_size(x_start, x_end, y_start, y_end);
    	
    	for(i = 0; i < w; i ++) {
    	    for(j = 0; j < h; j ++) {
    			lcd_write(TFT_DATA, color >> 8);
    			lcd_write(TFT_DATA, color);
    		}
    	}
    }
    
    void DispGrayHor16(void) {
    	u8 i,j,k;
    
       	set_frame_size(0, 127, 0, 127);
    
    	for(i = 0;i < 128; i ++) {	
    		for(j=0;j<16;j++) {
    	        for(k=0;k< 128 / 16; k ++) {		
    				lcd_write(TFT_DATA, ((j*2)<<3)|((j*4)>>3));		 
    				lcd_write(TFT_DATA, ((j*4)<<5)|(j*2));
    			} 
    		}
    	}
    }
    
    void DispFrame(void) {
    	u8 i,j;
    	
    	set_frame_size(0, 127, 0, 127);
    
    	lcd_write(TFT_DATA, 0xF8);
    	lcd_write(TFT_DATA, 0x00);
    	
    	for(i = 0; i < 126; i ++){
    		lcd_write(TFT_DATA, 0xFF);
    		lcd_write(TFT_DATA, 0xFF);
    	}
    	
    	lcd_write(TFT_DATA, 0x00);
    	lcd_write(TFT_DATA, 0x1F);
    
    	for(j = 0; j < 126; j ++)
    	{
    		lcd_write(TFT_DATA, 0xF8);
    		lcd_write(TFT_DATA, 0x00);
    		for(i = 0; i < 126; i ++) {
    			lcd_write(TFT_DATA, 0x00);
    			lcd_write(TFT_DATA, 0x00);
    		}
    		
    		lcd_write(TFT_DATA, 0x00);
    		lcd_write(TFT_DATA, 0x1F);
    	}
    	
    	lcd_write(TFT_DATA, 0xf8);
    	lcd_write(TFT_DATA, 0x00);
    	
    	for(i=0;i<126;i++){
    		lcd_write(TFT_DATA, 0xFF);
    		lcd_write(TFT_DATA, 0xFF);
    	}
    	
    	lcd_write(TFT_DATA, 0x00);
    	lcd_write(TFT_DATA, 0x1F);
    	
    }
    
    void DispBand(void) {
    	u8 i,j,k;
    	u16 color[8]={0x001f,0x07e0,0xf800,0x07ff,0xf81f,0xffe0,0x0000,0xffff};
    //	u16 color[8]={0xf800,0xf800,0x07e0,0x07e0,0x001f,0x001f,0xffff,0xffff};//0x94B2
    	//unsigned int gray16[]={0x0000,0x1082,0x2104,0x3186,0x42,0x08,0x528a,0x630c,0x738e,0x7bcf,0x9492,0xa514,0xb596,0xc618,0xd69a,0xe71c,0xffff};
    
    	lcd_write(TFT_CMD, 0x36); //Set Scanning Direction
    	lcd_write(TFT_DATA, 0x08); //0xc8
    
       	set_frame_size(0, 127, 0, 127);																								  
    
    	for(i=0;i < 8;i++)
    	{
    		for(j=0;j < 128 / 8;j++)
    		{
    	        for(k=0;k< 128;k++)
    			{
    				lcd_write(TFT_DATA, color[i]>>8); 
    				lcd_write(TFT_DATA, color[i]);   
    			} 
    		}
    	}
    }
    
    void DispPic(u8 x,u8 y,u8 w, u8 h,const unsigned char *p) {
    	unsigned int i,j;
    	unsigned char pic_h,pic_l;
    	
    //	lcd_write(TFT_CMD, 0x36); //Set Scanning Direction
    //	lcd_write(TFT_DATA, 0xC8); //0xc8
    	
    	set_frame_size(x, x + w - 1, y, y + h - 1);    
    
    	for(i = 0; i < h; i ++) {
    	    for(j = 0; j < w; j ++) {    
    			pic_l = *p ;
    			pic_h = *(p+1);
    			lcd_write(TFT_DATA, pic_h);				  
    			lcd_write(TFT_DATA, pic_l);
    			p += 2;
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    //lcd.h
    #ifndef __LCD_H
    #define __LCD_H
    
    #include "sys.h"
    #include "spi.h"
    
    #define LCD_RCC_ENABLE		RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOF
    
    #define LCD_RESRT 		PBout(2)
    #define LCD_CMD_DATA	PBout(1)
    #define LCD_BACK_LIGHT	PFout(11)
    
    #define LCD_RESET_MODE			GPIO_Mode_Out_PP
    #define LCD_RESET_PIN			GPIO_Pin_2
    #define LCD_RESET_SPEED			GPIO_Speed_50MHz
    #define LCD_RESET_GPIO			GPIOB
    
    #define LCD_CMD_DATA_MODE		GPIO_Mode_Out_PP
    #define LCD_CMD_DATA_PIN		GPIO_Pin_1
    #define LCD_CMD_DATA_SPEED		GPIO_Speed_50MHz
    #define LCD_CMD_DATA_GPIO		GPIOB
    
    #define LCD_BACK_LIGHT_MODE		GPIO_Mode_Out_PP
    #define LCD_BACK_LIGHT_PIN		GPIO_Pin_11
    #define LCD_BACK_LIGHT_SPEED	GPIO_Speed_50MHz
    #define LCD_BACK_LIGHT_GPIO		GPIOF
    
    #define LCD_NOP			0x00	//空命令
    #define LCD_SWRESET		0x01	//软件复位,在睡眠和显示模式下,重置软件后需等待120ms后方可执行下一条指令
    #define LCD_RDDID		0x04	//读取LCD的制造商ID(8位)、驱动版本ID(最高位为1,7位)、驱动程序ID(8位)
    #define LCD_RDDST		0x09	//读取显示屏所有状态参数
    #define LCD_RDDPM		0x0A	//读取显示屏能量模式
    #define LCD_RDDMADCTL	0x0B	//读取显示屏MADCTL
    #define LCD_RDDCOLMOD	0x0C	//读取显示屏像素定义
    #define LCD_RDDIM		0x0D	//读取显示屏图片模式
    #define LCD_RDDSM		0x0E	//读取显示屏单信号模式
    #define LCD_RDDSDR		0x0F	//读取显示屏自我诊断结果
    #define LCD_SLPIN		0x10	//进入最小功耗模式
    #define LCD_SLPOUT 		0x11	//关闭睡眠模式
    #define LCD_PTLON		0x12	//打开Partial模式
    #define LCD_NORON		0x13	//恢复到正常模式
    #define LCD_INVOFF		0x20	//显示反转模式中恢复
    #define LCD_INVON		0x21	//进入反向显示模式
    #define LCD_GAMSET		0x26	//当前显示选择所需的伽马曲线
    #define LCD_DISPOFF		0x28	//关闭显示,帧内存的输出被禁用
    #define LCD_DISPON		0x29	//开启显示,帧内存的输出被启用
    #define LCD_CASET		0x2A	//列地址设置,每个值代表帧内存中的一列
    #define LCD_RASET		0x2B	//行地址设置,每个值代表帧内存中的一列
    #define LCD_RAMWR		0x2C	//写入内存
    #define LCD_RGBSET		0x2D	//颜色模式设置
    #define LCD_RAMRD		0x2E	//读取内存
    #define LCD_PTLAR		0x30	//部分模式的显示区域设置
    #define LCD_SCRLAR		0x33	//定义垂直滚动区域的显示
    #define LCD_TEOFF		0x34	//关闭(Active Low) TE信号线的撕裂效应输出信号
    #define LCD_TEON		0x35	//打开TE信号线的撕裂效果输出信号
    #define LCD_MADCTL		0x36	//定义帧内存的读写扫描方向
    #define LCD_VSCSAD		0x37	//设置垂直滚动起始地址,此命令与垂直滚动定义(33h)一起使用
    #define LCD_IDMOFF		0x38	//关闭空闲模式
    #define LCD_IDMON		0x39	//开启空闲模式
    #define LCD_COLMOD		0x3A	//定义通过MCU接口传输的RGB图片数据的格式
    #define LCD_FRMCTR1		0xB1	//设置全色正常模式的帧频
    #define LCD_FRMCTR2 	0xB2	//设置空闲模式的帧频
    #define LCD_FRMCTR3 	0xB3	//设置部分模式/全色的帧频率
    #define LCD_INVCRT 		0xB4	//反转模式控制
    #define LCD_PWCTR1 		0xC0	//设置AVDD、MODE、VRHP、VRHN
    #define LCD_PWCTR2 		0xC1	//设置VGH与VGL的供电功率
    #define LCD_PWCTR3 		0xC2	//设置正常模式/全色模式下的运放的电流
    #define LCD_PWCTR4 		0xC3	//设置空闲模式/八色模式下的运放的电流
    #define LCD_PWCTR5 		0xC4	//设置部分模式/全色模式下的运放的电流
    #define LCD_VMCTR1 		0xC5	//设置VCOM电压电平以减少闪烁问题
    #define LCD_VMOFCTR		0xC7	//VCOM偏移控制,在使用命令0xC7之前,命令0xD9的位VMF_EN必须启用(设置为1)
    #define LCD_WRID2		0xD1	//写入LCD模块版本的7位数据,保存到NVM
    #define LCD_WRID3		0xD2	//写入项目代码模块的8位数据,保存到NVM
    #define LCD_NVFCTR1		0xD9	//NVM状态控制
    #define LCD_RDID1		0xDA	//读字节返回8位LCD模块的制造商ID
    #define LCD_RDID2		0xDB	//读字节返回8位LCD模块/驱动程序版本ID
    #define LCD_RDID3		0xDC	//读字节返回8位LCD模块/驱动ID
    #define LCD_NVFCTR2		0xDE	//NVM读取命令
    #define LCD_NVFCTR3		0xDF	//NVM写取命令
    #define LCD_GMCTRP1		0xE0	//Gamma ‘+’ Polarity Correction Characteristics Setting
    #define LCD_GMCTRN1		0xE1	//Gamma ‘+’ Polarity Correction Characteristics Setting
    #define LCD_GCV			0xFC	//自动调节门泵时钟,节省功耗
    
    
    enum TFT_DATA_TYPE {
    	TFT_CMD = 0,
    	TFT_DATA
    };
    
    void lcd_init(void);
    void lcd_config(void);
    void lcd_reset(void);
    void lcd_write(u8 c_d, u8 data);
    void set_background(u16 color);
    void set_scan_direction(u8 data);
    void set_color_format(u8 data);
    void set_frame_size(u16 x_start, u16 x_end, u16 y_start, u16 y_end);
    void set_point(u16 x, u16 y, u16 color);
    void set_rectangle(u16 x_start, u16 x_end, u16 y_start, u16 y_end, u16 color);
    void DispGrayHor16(void);
    void DispFrame(void);
    void DispBand(void);
    void DispPic(u8 x,u8 y,u8 w, u8 h,const unsigned char *p);
    
    #endif	//__LCD_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106

    三、硬件SPI+DMA驱动TFT显示屏

    实验环境:正点原子 STM32F103ZET6 小型系统板
    实验工具:STM32F103ZET6 芯片与 ST7735S芯片(1.44寸TFT显示屏)
    数据交互:STM32 芯片通过 GPIO 输入输出引脚输出SPI配合DMA与TFT液晶显示屏进行通信、数据传输及命令背景光等控制。
    实验成效:见STM32F103VET6硬件SPI+DMA着实快,图片上下移动的速度还可以

    STM32F103VET6硬件SPI+DMA着实快,图片上下移动的速度还可以

    以下为部分实验源码(lcd模块只改了部分代码,剩下的可以自己改):

    //spi.c
    #include "spi.h"
    
    extern GPIO_InitTypeDef GPIO_Initure;
    SPI_InitTypeDef SPI_Initure;
    
    void spi_init() {
    	RCC_APB2PeriphClockCmd(SPI_RCC_ENABLE, ENABLE);
    	
    #if SPI_READ_ENABLE
    	//SPI	DATA_IN		PA1
    	GPIO_Initure.GPIO_Mode = SPI_DATA_IN_MODE;
    	GPIO_Initure.GPIO_Pin = SPI_DATA_IN_PIN;
    	GPIO_Initure.GPIO_Speed = SPI_DATA_IN_SPEED;
    	GPIO_Init(SPI_DATA_IN_GPIO, &GPIO_Initure);
    #endif
    	
    #if SPI_WRITE_ENABLE
    	//SPI	DATA_OUT
    	GPIO_Initure.GPIO_Mode = SPI_DATA_OUT_MODE;
    	GPIO_Initure.GPIO_Pin = SPI_DATA_OUT_PIN;
    	GPIO_Initure.GPIO_Speed = SPI_DATA_OUT_SPEED;
    	GPIO_Init(SPI_DATA_OUT_GPIO, &GPIO_Initure);
    #endif
    	
    	//SPI	SCLK
    	GPIO_Initure.GPIO_Mode = SPI_SCLK_MODE;
    	GPIO_Initure.GPIO_Pin = SPI_SCLK_PIN;
    	GPIO_Initure.GPIO_Speed = SPI_SCLK_SPEED;
    	GPIO_Init(SPI_SCLK_GPIO, &GPIO_Initure);
    	
    	//SPI	CS
    	GPIO_Initure.GPIO_Mode = SPI_CS_MODE;
    	GPIO_Initure.GPIO_Pin = SPI_CS_PIN;
    	GPIO_Initure.GPIO_Speed = SPI_CS_SPEED;
    	GPIO_Init(SPI_CS_GPIO, &GPIO_Initure);
    	
    	SPI_CS = 1;
    	
    	SPI_Initure.SPI_BaudRatePrescaler	= SPI_BaudRatePrescaler_2;	// 使分频值达到最大
    	SPI_Initure.SPI_CPHA				= SPI_CPHA_1Edge;			// 上降沿有效
    	SPI_Initure.SPI_CPOL				= SPI_CPOL_Low;				// 高电平有效
    	SPI_Initure.SPI_CRCPolynomial		= 0;						// 无 CRC 校验
    	SPI_Initure.SPI_DataSize			= SPI_DataSize_8b;			// 发送字长为 8 位
    	SPI_Initure.SPI_Direction			= SPI_Direction_1Line_Tx;	// 方向为发送
    	SPI_Initure.SPI_FirstBit			= SPI_FirstBit_MSB;			// 高位先行
    	SPI_Initure.SPI_Mode				= SPI_Mode_Master;			// 主机模式
    	SPI_Initure.SPI_NSS					= SPI_NSS_Soft;				// 软件控制
    	SPI_Init(SPI1,&SPI_Initure);
    	
    	SPI_Cmd(SPI1, ENABLE);
    }
    
    void spi_write(u8 data) {
    	u16 next = 0;
    	while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) {
    		if(++ next > 500) return;
    	}
    	SPI_I2S_SendData(SPI1, data);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    //spi.h
    #ifndef __SPI_H
    #define __SPI_H
    
    #include "sys.h"
    #include "delay.h"
    
    #define SPI_RCC_ENABLE		RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1
    
    #define SPI_CS PAout(4)
    
    #define SPI_DATA_IN_MODE	GPIO_Mode_IN_FLOATING
    #define SPI_DATA_IN_PIN		GPIO_Pin_6
    #define SPI_DATA_IN_SPEED	GPIO_Speed_50MHz
    #define SPI_DATA_IN_GPIO	GPIOA
    
    #define SPI_DATA_OUT_MODE	GPIO_Mode_AF_PP
    #define SPI_DATA_OUT_PIN	GPIO_Pin_7
    #define SPI_DATA_OUT_SPEED	GPIO_Speed_50MHz
    #define SPI_DATA_OUT_GPIO	GPIOA
    
    #define SPI_SCLK_MODE		GPIO_Mode_AF_PP
    #define SPI_SCLK_PIN		GPIO_Pin_5
    #define SPI_SCLK_SPEED		GPIO_Speed_50MHz
    #define SPI_SCLK_GPIO		GPIOA
    
    #define SPI_CS_MODE			GPIO_Mode_Out_PP
    #define SPI_CS_PIN			GPIO_Pin_4
    #define SPI_CS_SPEED		GPIO_Speed_50MHz
    #define SPI_CS_GPIO			GPIOA
    
    #define SPI_WRITE_ENABLE	1	//0-禁止SPI写入数据,1-使能SPI读取数据
    #define SPI_READ_ENABLE		0	//0-禁止SPI读取数据,1-使能SPI写入数据
    
    void spi_init(void);
    void spi_write(u8 data);
    
    #endif	//__SPI_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    //dma.c
    #include "dma.h"
    
    DMA_InitTypeDef DMA_Initure;
    
    void dma1_init(DMA_Channel_TypeDef* dma_chanel, u32 mem_addr, u32 per_addr, u32 buf_size) {
    	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	// 使能 DMA 高速时钟
    	
    	DMA_DeInit(dma_chanel);
    	
    	DMA_Initure.DMA_BufferSize			= buf_size;						// 设置 DMA 缓冲区数据长度,后期可调
    	DMA_Initure.DMA_DIR					= DMA_DIR_PeripheralDST;		// 设置 DMA 数据传输方向,这里为内存到外设
    	DMA_Initure.DMA_M2M					= DMA_M2M_Disable;				// 禁止 DMA 的内存到内存操作
    	DMA_Initure.DMA_MemoryBaseAddr		= mem_addr;						// 设置 DMA 内存访问的起始地址
    	DMA_Initure.DMA_MemoryDataSize		= DMA_MemoryDataSize_Byte;		// 内存物理数据大小为一个字节占 8 位
    	DMA_Initure.DMA_MemoryInc			= DMA_MemoryInc_Enable;			// 使能 DMA 内存地址递增
    	DMA_Initure.DMA_Mode				= DMA_Mode_Normal;				// 选择 DMA 单次读写模式
    	DMA_Initure.DMA_PeripheralBaseAddr	= per_addr;						// 设置 DMA 外设访问的起始地址
    	DMA_Initure.DMA_PeripheralDataSize	= DMA_PeripheralDataSize_Byte;	// 外设物理数据大小为一个字节占 8 位
    	DMA_Initure.DMA_PeripheralInc		= DMA_PeripheralInc_Disable;	// 禁止 DMA 外设地址递增
    	DMA_Initure.DMA_Priority			= DMA_Priority_High;			// 高优先级
    	DMA_Init(dma_chanel, &DMA_Initure);
    }
    
    void dma1_chanel_choose(DMA_Channel_TypeDef* dma_chanel, u32 buf_size) {
    	DMA_Cmd(dma_chanel, DISABLE);					//禁止 DMA 通道
    	DMA_SetCurrDataCounter(dma_chanel, buf_size);	//设置 DMA 通道与 DMA 缓冲区大小
    	DMA_Cmd(dma_chanel, ENABLE);					//使能 DMA 通道
    }
    
    void dma1_to_spi1(DMA_Channel_TypeDef* dma_chanel, u32 buf_size, uint16_t spi_dma_req, uint32_t dma_flag) {
    	//设置一个超时变量
    	u16 timeout = 0;
    	
    	//重新初始化DMA缓冲区大小并使能 DMA 通道
    	dma1_chanel_choose(DMA1_Channel3, 128*2);
    
    	//使能 DMA1
    	SPI_I2S_DMACmd(SPI1, spi_dma_req, ENABLE);
    
    	//判断 DMA 是否完成数据传输,若超过一定时限,则中断本次传输
    	while(DMA_GetFlagStatus(dma_flag) == RESET) {
    		if(timeout ++ > 200) break;
    	}
    
    	// 清除 DMA 标志位
    	DMA_ClearFlag(dma_flag);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    #ifndef __DMA_H
    #define __DMA_H
    
    #include "sys.h"
    
    void dma1_init(DMA_Channel_TypeDef* DMAy_Channelx, u32 mem_addr, u32 per_addr, u32 buf_size);
    void dma1_chanel_choose(DMA_Channel_TypeDef* dma_chanel, u32 buf_size);
    void dma1_to_spi1(DMA_Channel_TypeDef* dma_chanel, u32 buf_size, uint16_t spi_dma_req,uint32_t dma_flag);
    
    #endif	//__DMA_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    //lcd.c
    #include "lcd.h"
    #include "led.h"
    
    #define BUF_SIZE 128
    
    extern GPIO_InitTypeDef GPIO_Initure;
    u8 dma_data[2 * BUF_SIZE];
    
    void lcd_init() {
    	RCC_APB2PeriphClockCmd(LCD_RCC_ENABLE, ENABLE);
    	
    	//RESET
    	GPIO_Initure.GPIO_Mode = LCD_RESET_MODE;
    	GPIO_Initure.GPIO_Pin = LCD_RESET_PIN;
    	GPIO_Initure.GPIO_Speed = LCD_RESET_SPEED;
    	GPIO_Init(LCD_RESET_GPIO, &GPIO_Initure);
    	
    	//CMD DATA
    	GPIO_Initure.GPIO_Mode = LCD_CMD_DATA_MODE;
    	GPIO_Initure.GPIO_Pin = LCD_CMD_DATA_PIN;
    	GPIO_Initure.GPIO_Speed = LCD_CMD_DATA_SPEED;
    	GPIO_Init(LCD_CMD_DATA_GPIO, &GPIO_Initure);
    	
    	//BACK LIGHT
    	GPIO_Initure.GPIO_Mode = LCD_BACK_LIGHT_MODE;
    	GPIO_Initure.GPIO_Pin = LCD_BACK_LIGHT_PIN;
    	GPIO_Initure.GPIO_Speed = LCD_BACK_LIGHT_SPEED;
    	GPIO_Init(LCD_BACK_LIGHT_GPIO, &GPIO_Initure);
    	
    	LCD_RESRT = LCD_CMD_DATA = LCD_BACK_LIGHT = 1;
    	
    	spi_init();
    	lcd_config();
    	dma1_init(DMA1_Channel3, (u32)dma_data, (u32)&(SPI1 -> DR), 2 * BUF_SIZE);
    }
    
    void lcd_config() {
    	//===============reset============================
    	lcd_reset();
    
    	//===============exit sleep=======================
    	lcd_write(TFT_CMD ,LCD_SLPOUT);
    	delay_ms(120);
    
    	//===============frame set========================
    	//Frame rate = fosc / ((RTNA x 2 + 40) x (LINE + FPA + BPA + 2))
    	lcd_write(TFT_CMD, LCD_FRMCTR1);
    //	lcd_write(TFT_DATA, 0x02);
    //	lcd_write(TFT_DATA, 0x35);
    //	lcd_write(TFT_DATA, 0x36);
    //	
    //	lcd_write(TFT_CMD, LCD_FRMCTR2);
    //	lcd_write(TFT_DATA, 0x02);
    //	lcd_write(TFT_DATA, 0x35);
    //	lcd_write(TFT_DATA, 0x36);
    //	
    //	lcd_write(TFT_CMD, LCD_FRMCTR3);
    //	lcd_write(TFT_DATA, 0x02);
    //	lcd_write(TFT_DATA, 0x35);
    //	lcd_write(TFT_DATA, 0x36);
    //	lcd_write(TFT_DATA, 0x02);
    //	lcd_write(TFT_DATA, 0x35);
    //	lcd_write(TFT_DATA, 0x36);
    	
    	lcd_write(TFT_CMD, LCD_FRMCTR1);
    	lcd_write(TFT_DATA, 0x01);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x2D);
    	
    	lcd_write(TFT_CMD, LCD_FRMCTR2);
    	lcd_write(TFT_DATA, 0x01);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x2D);
    	
    	lcd_write(TFT_CMD, LCD_FRMCTR3);
    	lcd_write(TFT_DATA, 0x01);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x2D);
    	lcd_write(TFT_DATA, 0x01);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x2D);
    	
    	//===============inversion of control=============
    	lcd_write(TFT_CMD, LCD_INVCRT);
    	lcd_write(TFT_DATA, 0x03);
    
    	//===============power set========================
    	lcd_write(TFT_CMD, LCD_PWCTR1);
    	lcd_write(TFT_DATA, 0xA2);
    	lcd_write(TFT_DATA, 0x02);
    	lcd_write(TFT_DATA, 0x84);
    		
    	lcd_write(TFT_CMD, LCD_PWCTR2);
    	lcd_write(TFT_DATA, 0xC5);
    
    	lcd_write(TFT_CMD, LCD_PWCTR3);
    	lcd_write(TFT_DATA, 0x0D);
    	lcd_write(TFT_DATA, 0x00);
    	
    	lcd_write(TFT_CMD, LCD_PWCTR4);
    	lcd_write(TFT_DATA, 0x8D);
    	lcd_write(TFT_DATA, 0x2A);
    	
    	lcd_write(TFT_CMD, LCD_PWCTR5);
    	lcd_write(TFT_DATA, 0x8D);
    	lcd_write(TFT_DATA, 0xEE);
    
    	//===============vcom set=========================
    	lcd_write(TFT_CMD, LCD_VMCTR1);
    	lcd_write(TFT_DATA, 0x03);
    
    	//===============color format set=================
    	set_color_format(0x05);
    	
    	//===============scanning direction set===========
    	set_scan_direction(0x08);
    	
    	//===============gamma sequence set===============
    	lcd_write(TFT_CMD, LCD_GMCTRP1);
    	lcd_write(TFT_DATA, 0x12);
    	lcd_write(TFT_DATA, 0x1C);
    	lcd_write(TFT_DATA, 0x10);
    	lcd_write(TFT_DATA, 0x18);
    	lcd_write(TFT_DATA, 0x33);
    	lcd_write(TFT_DATA, 0x2C);
    	lcd_write(TFT_DATA, 0x25);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x27);
    	lcd_write(TFT_DATA, 0x2F);
    	lcd_write(TFT_DATA, 0x3C);
    	lcd_write(TFT_DATA, 0x00);
    	lcd_write(TFT_DATA, 0x03);
    	lcd_write(TFT_DATA, 0x03);
    	lcd_write(TFT_DATA, 0x10);
    
    	lcd_write(TFT_CMD, LCD_GMCTRN1);
    	lcd_write(TFT_DATA, 0x12);
    	lcd_write(TFT_DATA, 0x1C);
    	lcd_write(TFT_DATA, 0x10);
    	lcd_write(TFT_DATA, 0x18);
    	lcd_write(TFT_DATA, 0x2D);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x23);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x28);
    	lcd_write(TFT_DATA, 0x26);
    	lcd_write(TFT_DATA, 0x2F);
    	lcd_write(TFT_DATA, 0x3B);
    	lcd_write(TFT_DATA, 0x00);
    	lcd_write(TFT_DATA, 0x03);
    	lcd_write(TFT_DATA, 0x03);
    	lcd_write(TFT_DATA, 0x10);
    
    	//===============partial area set=================
    	lcd_write(TFT_CMD, LCD_PTLAR);             
    	lcd_write(TFT_DATA, 0x00);             
    	lcd_write(TFT_DATA, 0x00);             
    	lcd_write(TFT_DATA, 0x00);             
    	lcd_write(TFT_DATA, 0x80);
    	
    	//===============partial mode on==================
    	lcd_write(TFT_CMD, LCD_PTLON);
    
    	//===============display on=======================
    	lcd_write(TFT_CMD, LCD_DISPON);
    }
    
    void lcd_reset() {
    	LCD_RESRT = 1;
    	delay_ms(60);
    	LCD_RESRT = 0;
    	delay_ms(120);
    	LCD_RESRT = 1;
    	delay_ms(60);
    }
    
    void lcd_write(u8 c_d, u8 data) {
    	LCD_CMD_DATA = c_d;
    	SPI_CS = 0;
    	spi_write(data);
    	SPI_CS = 1;
    }
    
    void set_background(u16 color) {
    	u8 i,j;
    	set_frame_size(0,0x7F,0x00,0x7F);
    
    	LCD_CMD_DATA = TFT_DATA;
    	SPI_CS = 0;
    
    	for(i = 0; i < 128; i ++) {
    		for(j = 0; j < BUF_SIZE; j ++) {
    			dma_data[j * 2] = color >> 8;
    			dma_data[j * 2 + 1] = color;
    		}
    		dma1_to_spi1(DMA1_Channel3, 2 * BUF_SIZE, SPI_I2S_DMAReq_Tx, DMA1_FLAG_TC3);
    	}
    
    	SPI_CS = 1;
    }
    
    void set_scan_direction(u8 data) {
    	lcd_write(TFT_CMD, LCD_MADCTL);
    	lcd_write(TFT_DATA, data);
    }
    
    void set_color_format(u8 data) {
    	lcd_write(TFT_CMD, LCD_COLMOD);
    	lcd_write(TFT_DATA, data);
    }
    
    void set_frame_size(u16 x_start, u16 x_end, u16 y_start, u16 y_end) {
    	lcd_write(TFT_CMD, LCD_CASET);
    	lcd_write(TFT_DATA, x_start >> 8);
    	lcd_write(TFT_DATA, x_start);
    	lcd_write(TFT_DATA, x_end >> 8);
    	lcd_write(TFT_DATA, x_end);
    	
    	lcd_write(TFT_CMD, LCD_RASET);
    	lcd_write(TFT_DATA, y_start >> 8);
    	lcd_write(TFT_DATA, y_start);
    	lcd_write(TFT_DATA, y_end >> 8);
    	lcd_write(TFT_DATA, y_end);
    	
    	lcd_write(TFT_CMD, LCD_RAMWR);
    }
    
    void set_point(u16 x, u16 y, u16 color) {
    	set_frame_size(x, x + 1, y, y + 1);
    
    	lcd_write(TFT_DATA, color >> 8);
    	lcd_write(TFT_DATA, color);
    }
    
    void set_rectangle(u16 x_start, u16 x_end, u16 y_start, u16 y_end, u16 color) {
    	u8 i, j, w, h;
    	
    	w = x_end - x_start;
    	h = y_end - y_start;
    	
    	set_frame_size(x_start, x_end, y_start, y_end);
    	
    	for(i = 0; i < w; i ++) {
    	    for(j = 0; j < h; j ++) {
    			lcd_write(TFT_DATA, color >> 8);
    			lcd_write(TFT_DATA, color);
    		}
    	}
    }
    
    void DispGrayHor16(void) {
    	u8 i,j,k;
    
       	set_frame_size(0, 127, 0, 127);
    
    	for(i = 0;i < 128; i ++) {	
    		for(j=0;j<16;j++) {
    	        for(k=0;k< 128 / 16; k ++) {		
    				lcd_write(TFT_DATA, ((j*2)<<3)|((j*4)>>3));		 
    				lcd_write(TFT_DATA, ((j*4)<<5)|(j*2));
    			} 
    		}
    	}
    }
    
    void DispFrame(void) {
    	u8 i,j;
    	
    	set_frame_size(0, 127, 0, 127);
    
    	lcd_write(TFT_DATA, 0xF8);
    	lcd_write(TFT_DATA, 0x00);
    	
    	for(i = 0; i < 126; i ++){
    		lcd_write(TFT_DATA, 0xFF);
    		lcd_write(TFT_DATA, 0xFF);
    	}
    	
    	lcd_write(TFT_DATA, 0x00);
    	lcd_write(TFT_DATA, 0x1F);
    
    	for(j = 0; j < 126; j ++)
    	{
    		lcd_write(TFT_DATA, 0xF8);
    		lcd_write(TFT_DATA, 0x00);
    		for(i = 0; i < 126; i ++) {
    			lcd_write(TFT_DATA, 0x00);
    			lcd_write(TFT_DATA, 0x00);
    		}
    		
    		lcd_write(TFT_DATA, 0x00);
    		lcd_write(TFT_DATA, 0x1F);
    	}
    	
    	lcd_write(TFT_DATA, 0xf8);
    	lcd_write(TFT_DATA, 0x00);
    	
    	for(i=0;i<126;i++){
    		lcd_write(TFT_DATA, 0xFF);
    		lcd_write(TFT_DATA, 0xFF);
    	}
    	
    	lcd_write(TFT_DATA, 0x00);
    	lcd_write(TFT_DATA, 0x1F);
    	
    }
    
    void DispBand(void) {
    	u8 i,j,k;
    	u16 color[8]={0x001f,0x07e0,0xf800,0x07ff,0xf81f,0xffe0,0x0000,0xffff};
    //	u16 color[8]={0xf800,0xf800,0x07e0,0x07e0,0x001f,0x001f,0xffff,0xffff};//0x94B2
    	//unsigned int gray16[]={0x0000,0x1082,0x2104,0x3186,0x42,0x08,0x528a,0x630c,0x738e,0x7bcf,0x9492,0xa514,0xb596,0xc618,0xd69a,0xe71c,0xffff};
    
    	lcd_write(TFT_CMD, 0x36); //Set Scanning Direction
    	lcd_write(TFT_DATA, 0x08); //0xc8
    
       	set_frame_size(0, 127, 0, 127);																								  
    
    	for(i=0;i < 8;i++)
    	{
    		for(j=0;j < 128 / 8;j++)
    		{
    	        for(k = 0;k < 128;k ++)
    			{
    				lcd_write(TFT_DATA, color[i]>>8); 
    				lcd_write(TFT_DATA, color[i]);   
    			} 
    		}
    	}
    }
    
    void DispPic(u8 x, u8 y, u8 w, u8 h, const u8 *p) {
    	u16 i, j;
    
    	set_frame_size(x, x + w - 1, y, y + h - 1);
    
    	LCD_CMD_DATA = TFT_DATA;
    	SPI_CS = 0;
    
    	for(i = 0; i < h; i ++) {
    		for(j = 0; j < w; j ++) {
    			dma_data[j * 2] = *(p + 1);
    			dma_data[j * 2 + 1] = *p;
    			p += 2;
    		}
    		dma1_to_spi1(DMA1_Channel3, 2 * BUF_SIZE, SPI_I2S_DMAReq_Tx, DMA1_FLAG_TC3);
    	}
    
    	SPI_CS = 1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    //lcd.h
    #ifndef __LCD_H
    #define __LCD_H
    
    #include "sys.h"
    #include "spi.h"
    #include "dma.h"
    
    #define LCD_RCC_ENABLE		RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOF
    
    #define LCD_RESRT 		PBout(2)
    #define LCD_CMD_DATA	PBout(1)
    #define LCD_BACK_LIGHT	PFout(11)
    
    #define LCD_RESET_MODE			GPIO_Mode_Out_PP
    #define LCD_RESET_PIN			GPIO_Pin_2
    #define LCD_RESET_SPEED			GPIO_Speed_50MHz
    #define LCD_RESET_GPIO			GPIOB
    
    #define LCD_CMD_DATA_MODE		GPIO_Mode_Out_PP
    #define LCD_CMD_DATA_PIN		GPIO_Pin_1
    #define LCD_CMD_DATA_SPEED		GPIO_Speed_50MHz
    #define LCD_CMD_DATA_GPIO		GPIOB
    
    #define LCD_BACK_LIGHT_MODE		GPIO_Mode_Out_PP
    #define LCD_BACK_LIGHT_PIN		GPIO_Pin_11
    #define LCD_BACK_LIGHT_SPEED	GPIO_Speed_50MHz
    #define LCD_BACK_LIGHT_GPIO		GPIOF
    
    #define LCD_NOP			0x00	//空命令
    #define LCD_SWRESET		0x01	//软件复位,在睡眠和显示模式下,重置软件后需等待120ms后方可执行下一条指令
    #define LCD_RDDID		0x04	//读取LCD的制造商ID(8位)、驱动版本ID(最高位为1,7位)、驱动程序ID(8位)
    #define LCD_RDDST		0x09	//读取显示屏所有状态参数
    #define LCD_RDDPM		0x0A	//读取显示屏能量模式
    #define LCD_RDDMADCTL	0x0B	//读取显示屏MADCTL
    #define LCD_RDDCOLMOD	0x0C	//读取显示屏像素定义
    #define LCD_RDDIM		0x0D	//读取显示屏图片模式
    #define LCD_RDDSM		0x0E	//读取显示屏单信号模式
    #define LCD_RDDSDR		0x0F	//读取显示屏自我诊断结果
    #define LCD_SLPIN		0x10	//进入最小功耗模式
    #define LCD_SLPOUT 		0x11	//关闭睡眠模式
    #define LCD_PTLON		0x12	//打开Partial模式
    #define LCD_NORON		0x13	//恢复到正常模式
    #define LCD_INVOFF		0x20	//显示反转模式中恢复
    #define LCD_INVON		0x21	//进入反向显示模式
    #define LCD_GAMSET		0x26	//当前显示选择所需的伽马曲线
    #define LCD_DISPOFF		0x28	//关闭显示,帧内存的输出被禁用
    #define LCD_DISPON		0x29	//开启显示,帧内存的输出被启用
    #define LCD_CASET		0x2A	//列地址设置,每个值代表帧内存中的一列
    #define LCD_RASET		0x2B	//行地址设置,每个值代表帧内存中的一列
    #define LCD_RAMWR		0x2C	//写入内存
    #define LCD_RGBSET		0x2D	//颜色模式设置
    #define LCD_RAMRD		0x2E	//读取内存
    #define LCD_PTLAR		0x30	//部分模式的显示区域设置
    #define LCD_SCRLAR		0x33	//定义垂直滚动区域的显示
    #define LCD_TEOFF		0x34	//关闭(Active Low) TE信号线的撕裂效应输出信号
    #define LCD_TEON		0x35	//打开TE信号线的撕裂效果输出信号
    #define LCD_MADCTL		0x36	//定义帧内存的读写扫描方向
    #define LCD_VSCSAD		0x37	//设置垂直滚动起始地址,此命令与垂直滚动定义(33h)一起使用
    #define LCD_IDMOFF		0x38	//关闭空闲模式
    #define LCD_IDMON		0x39	//开启空闲模式
    #define LCD_COLMOD		0x3A	//定义通过MCU接口传输的RGB图片数据的格式
    #define LCD_FRMCTR1		0xB1	//设置全色正常模式的帧频
    #define LCD_FRMCTR2 	0xB2	//设置空闲模式的帧频
    #define LCD_FRMCTR3 	0xB3	//设置部分模式/全色的帧频率
    #define LCD_INVCRT 		0xB4	//反转模式控制
    #define LCD_PWCTR1 		0xC0	//设置AVDD、MODE、VRHP、VRHN
    #define LCD_PWCTR2 		0xC1	//设置VGH与VGL的供电功率
    #define LCD_PWCTR3 		0xC2	//设置正常模式/全色模式下的运放的电流
    #define LCD_PWCTR4 		0xC3	//设置空闲模式/八色模式下的运放的电流
    #define LCD_PWCTR5 		0xC4	//设置部分模式/全色模式下的运放的电流
    #define LCD_VMCTR1 		0xC5	//设置VCOM电压电平以减少闪烁问题
    #define LCD_VMOFCTR		0xC7	//VCOM偏移控制,在使用命令0xC7之前,命令0xD9的位VMF_EN必须启用(设置为1)
    #define LCD_WRID2		0xD1	//写入LCD模块版本的7位数据,保存到NVM
    #define LCD_WRID3		0xD2	//写入项目代码模块的8位数据,保存到NVM
    #define LCD_NVFCTR1		0xD9	//NVM状态控制
    #define LCD_RDID1		0xDA	//读字节返回8位LCD模块的制造商ID
    #define LCD_RDID2		0xDB	//读字节返回8位LCD模块/驱动程序版本ID
    #define LCD_RDID3		0xDC	//读字节返回8位LCD模块/驱动ID
    #define LCD_NVFCTR2		0xDE	//NVM读取命令
    #define LCD_NVFCTR3		0xDF	//NVM写取命令
    #define LCD_GMCTRP1		0xE0	//Gamma ‘+’ Polarity Correction Characteristics Setting
    #define LCD_GMCTRN1		0xE1	//Gamma ‘+’ Polarity Correction Characteristics Setting
    #define LCD_GCV			0xFC	//自动调节门泵时钟,节省功耗
    
    
    enum TFT_DATA_TYPE {
    	TFT_CMD = 0,
    	TFT_DATA
    };
    
    void lcd_init(void);
    void lcd_config(void);
    void lcd_reset(void);
    void lcd_write(u8 c_d, u8 data);
    void set_background(u16 color);
    void set_scan_direction(u8 data);
    void set_color_format(u8 data);
    void set_frame_size(u16 x_start, u16 x_end, u16 y_start, u16 y_end);
    void set_point(u16 x, u16 y, u16 color);
    void set_rectangle(u16 x_start, u16 x_end, u16 y_start, u16 y_end, u16 color);
    void DispGrayHor16(void);
    void DispFrame(void);
    void DispBand(void);
    void DispPic(u8 x,u8 y,u8 w, u8 h,const u8 *p);
    
    #endif	//__LCD_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107

    以上就是混子近段时间的研究成果吧,有很多东西还是参考了别人的,这里都分享出来,不提供源代码哈,感谢观看!

    这里特别说明一下DMA配SPI,我测出来的刷帧速率最快能够达到50多帧每秒,慢点也是30多帧每秒,参数可以自己多配配,或者问问芯片原厂,具体咋操作我不是专业的,也不是很懂,我的参数部分来源于网络,部分来源于demo,理解万岁。

    学习分享,一起成长!以上为小编的学习经验分享,若存在不当之处,请批评指正!

  • 相关阅读:
    面试十分钟不到就被赶出来了,问的实在是太变态了...
    雷神MixBook Air笔记本系统故障怎么重装?
    TCP与应用层协议
    【Appium UI自动化】pytest运行常见错误解决办法
    C++文件加密、解密
    SpringBoot集成文件 - 如何基于POI-tl和word模板导出庞大的Word文件?
    monaco-editor 的 Language Services
    rust变量
    【2022Java学习计划】值得收藏的学习计划
    SQL中常见的DDL操作及示例,数据库操作及表操作
  • 原文地址:https://blog.csdn.net/qq_36553707/article/details/127865825