ST7789V.c

#include "stm32f4xx.h"                  // Device header
#include "ST7789V.h"                   
#include "delay.h" 		
#include "STM32F4XX_HAL_GPIO.h" 

extern TIM_HandleTypeDef htim3;
extern SPI_HandleTypeDef hspi1;
extern DMA_HandleTypeDef hdma_spi1_tx;

void SPISendDataByte(uint8_t Data)
{
	HAL_SPI_Transmit(&hspi1,&Data,1,1);
}

//写入数据
void SPISendData2Bytes(uint16_t Data)
{
	uint8_t temp[2];
	temp[0]=(Data>>8)&0xff;
	temp[1]=Data&0xff;
	HAL_SPI_Transmit(&hspi1,temp,2,1);
}

//写命令
void SPISendCmdByte(uint8_t Data)
{
	LCD_DC_Clr() ;
	while (__HAL_SPI_GET_FLAG(&hspi1, SPI_FLAG_TXE) == RESET);
	SPISendDataByte(Data);
	LCD_DC_Set() ;
}

void ST7789V_GPIO_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure = {0};
	
 	__HAL_RCC_GPIOB_CLK_ENABLE();
	
	GPIO_InitStructure.Pin = RES_PIN|CS_PIN|DC_PIN;	 
 	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; 		 //推挽输出
	GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;//速度50MHz
 	HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);	  //初始化GPIOB
 	HAL_GPIO_WritePin(GPIOB, RES_PIN|CS_PIN|DC_PIN, GPIO_PIN_SET);
}
void ST7789V_Reset(void)
{
    // 拉低复位引脚,使显示屏进入复位状态
    LCD_RES_Clr();
    // 延时 100ms,确保复位信号保持足够时间
    delay_ms(100);
    // 拉高复位引脚,退出复位状态
    LCD_RES_Set();
    // 再次延时 100ms,等待显示屏稳定
    delay_ms(100);
} 
void ST7789V_LcdInit(void)
{
	ST7789V_GPIO_Init();//初始化GPIO
	LCD_CS_Clr();		//选择设备
	
	ST7789V_Reset();//复位

	SPISendCmdByte(0x11); //退出睡眠模式
	delay_ms(120); 

	ST7789V_SetDir(USE_HORIZONTAL);
	
	/*12位颜色为03h,16位颜色位05h,18位为06h,代表了颜色更多,显示更好*/
	SPISendCmdByte(0x3A);
	SPISendDataByte(0x55);
//-------------ST7789V Frame rate setting-----------//
	SPISendCmdByte(0xB2);//Porch Setting
	SPISendDataByte(0x0C);
	SPISendDataByte(0x0C);
	SPISendDataByte(0x00);
	SPISendDataByte(0x33);
	SPISendDataByte(0x33); 
	
	SPISendCmdByte(0xB7);//Gate Control
	SPISendDataByte(0x75);//······12.2v   -10.43v  
	
	SPISendCmdByte(0xC2);//VDV and VRH Command Enable
	SPISendDataByte(0x01);

	SPISendCmdByte(0xC3);//VRH Set
	SPISendDataByte(0x16);//······4.3+( vcom+vcom offset+vdv)   

	SPISendCmdByte(0xC4);//VDV Set
	SPISendDataByte(0x20); //0v 

	SPISendCmdByte(0xC6);//Frame Rate Control in Normal Mode 
	SPISendDataByte(0x0F);//111Hz   

	SPISendCmdByte(0xD0);//Power Control 1 
	SPISendDataByte(0xA4);
	SPISendDataByte(0xA1);
	
	SPISendCmdByte(0xD6);
	SPISendDataByte(0xA1);
	
	SPISendCmdByte(0xBB);//VCOM
	SPISendDataByte(0x3B);
//---------------ST7789V gamma setting-------------//
	SPISendCmdByte(0xE0);//Set Gamma
	SPISendDataByte(0xF0);
	SPISendDataByte(0x0B);
	SPISendDataByte(0x11);
	SPISendDataByte(0x0E);
	SPISendDataByte(0x0D);
	SPISendDataByte(0x19);
	SPISendDataByte(0x36);
	SPISendDataByte(0x33);
	SPISendDataByte(0x4B);
	SPISendDataByte(0x07);
	SPISendDataByte(0x14);
	SPISendDataByte(0x14);
	SPISendDataByte(0x2C);
	SPISendDataByte(0x2E);    

	SPISendCmdByte(0xE1);//Set Gamma
	SPISendDataByte(0xF0);
	SPISendDataByte(0x0D);
	SPISendDataByte(0x12);
	SPISendDataByte(0x0B);
	SPISendDataByte(0x09);
	SPISendDataByte(0x03);
	SPISendDataByte(0x32);
	SPISendDataByte(0x44);
	SPISendDataByte(0x48);
	SPISendDataByte(0x39);
	SPISendDataByte(0x16);
	SPISendDataByte(0x16);
	SPISendDataByte(0x2d);
	SPISendDataByte(0x30);

	SPISendCmdByte(0xE4);
	SPISendDataByte(0x25);
	SPISendDataByte(0x00);
	SPISendDataByte(0x00);

//	SPISendCmdByte(0x21);//此命令用于从显示反转模式恢复。
	SPISendCmdByte(0x29);//显示打开
	SPISendCmdByte(0x2c);
}
void ST7789V_SetDir(uint8_t Dir_Mode)
{
	SPISendCmdByte(0x36);/*显示方向*/ 
	if(Dir_Mode==0)SPISendDataByte(0x00);
	else if(Dir_Mode==1)SPISendDataByte(0xC0);
	else if(Dir_Mode==2)SPISendDataByte(0x70);
	else SPISendDataByte(0xA0);
}
void ST7789V_SetLcdAddress(uint16_t Start_X,uint16_t Start_Y,uint16_t End_X,uint16_t End_Y,uint8_t Dir_Mode)
{
	if(Dir_Mode == 0 || Dir_Mode == 1)
	{
		SPISendCmdByte(0x2a);//列地址设置
		SPISendData2Bytes(Start_X);
		SPISendData2Bytes(End_X);
		SPISendCmdByte(0x2b);//行地址设置
		SPISendData2Bytes(Start_Y);
		SPISendData2Bytes(End_Y);
		SPISendCmdByte(0x2c);//储存器写
	}
}
void ST7789V_LcdDrawPoint(uint16_t X,uint16_t Y,uint16_t Color,uint8_t Dir_Mode)
{
	ST7789V_SetLcdAddress(X,Y,X,Y,USE_HORIZONTAL);//设置光标位置 
	SPISendData2Bytes(Color);
} 
void ST7789V_AdaptiveBrightnessColorEnhancementInit(WRCACE_InitTypedef*WRCACE_InitStruct)
{
	SPISendCmdByte(0x55);
	SPISendDataByte((WRCACE_InitStruct->Color_Enhancement_Extent<<4)|(WRCACE_InitStruct->Color_Enhancement_Cmd<<7)|WRCACE_InitStruct->Adaptive_Brightness_Goal);
}
void ST7789V_LcdDrawLine(uint16_t Start_X,uint16_t Start_Y,uint16_t End_X,uint16_t End_Y,uint16_t Color,uint8_t Dir_Mode)
{
	uint16_t t; 
	int xerr=0,yerr=0,delta_x,delta_y,distance;
	int incx,incy,uRow,uCol;
	delta_x=End_X-Start_X; //计算坐标增量 
	delta_y=End_Y-Start_Y;
	uRow=Start_X;//画线起点坐标
	uCol=Start_Y;
	if(delta_x>0)incx=1; //设置单步方向 
	else if (delta_x==0)incx=0;//垂直线 
	else {incx=-1;delta_x=-delta_x;}
	if(delta_y>0)incy=1;
	else if (delta_y==0)incy=0;//水平线 
	else {incy=-1;delta_y=-delta_y;}
	if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴 
	else distance=delta_y;
	for(t=0;t<distance+1;t++)
	{
		ST7789V_LcdDrawPoint(uRow,uCol,Color,Dir_Mode);//画点
		xerr+=delta_x;
		yerr+=delta_y;
		if(xerr>distance)
		{
			xerr-=distance;
			uRow+=incx;
		}
		if(yerr>distance)
		{
			yerr-=distance;
			uCol+=incy;
		}
	}
}
void ST7789V_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 *color,uint8_t increasing)
{          
	u16 i,j; 
	ST7789V_SetLcdAddress(xsta,ysta,xend,yend,USE_HORIZONTAL);//设置显示范围
	for(i=ysta;i<=yend;i++)
	{		
		for(j=xsta;j<=xend;j++)
		{
			SPISendData2Bytes(*color);
			if(increasing == 1){color++;}
		}
	} 					  	    
}
//spi+dma
void ST7789V_Fill_dma(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 *color_p)
{
	u16 width,height; 
	width = xend-xsta+1;
	height = yend-ysta+1;
	uint32_t size = width * height;
	
	ST7789V_SetLcdAddress(xsta,ysta,xend,yend,USE_HORIZONTAL);
	
	hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
	hspi1.Instance->CR1|=SPI_CR1_DFF;
	HAL_SPI_Transmit_DMA(&hspi1,(uint8_t*)color_p,size);
	while(__HAL_DMA_GET_COUNTER(&hdma_spi1_tx)!=0);
	
	hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
	hspi1.Instance->CR1&=~SPI_CR1_DFF;
	
}
void ST7789V_Open_Light(void)
{
	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);
}
void ST7789V_Set_Light(uint8_t dc)
{
	if(dc>=5 && dc<=100)
	__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_3,dc*PWM_PERIOD/100);
}

ST7789V.h


#ifndef _ST7789V_H_
#define _ST7789V_H_
#include "sys.h"

extern TIM_HandleTypeDef htim3;
extern SPI_HandleTypeDef hspi1;
extern DMA_HandleTypeDef hdma_spi1_tx;

#define USE_HORIZONTAL 	 1  //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏
#define LCD_W 					 240
#define LCD_H 					 320

#define PWM_PERIOD 300

//-----------------LCD端口定义---------------- 
#define RES_PORT			GPIOB
#define RES_PIN				GPIO_PIN_7

#define DC_PORT				GPIOB
#define DC_PIN				GPIO_PIN_9

#define CS_PORT				GPIOB
#define CS_PIN				GPIO_PIN_8


#define LCD_SCLK_Clr() HAL_GPIO_WritePin(SCLK_PORT,SCLK_PIN,GPIO_PIN_RESET)//SCL=SCLK
#define LCD_SCLK_Set() HAL_GPIO_WritePin(SCLK_PORT,SCLK_PIN,GPIO_PIN_SET)

#define LCD_MOSI_Clr() HAL_GPIO_WritePin(SDA_PORT,SDA_PIN,GPIO_PIN_RESET)//SDA=MOSI
#define LCD_MOSI_Set() HAL_GPIO_WritePin(SDA_PORT,SDA_PIN,GPIO_PIN_SET)

#define LCD_RES_Clr()  HAL_GPIO_WritePin(RES_PORT,RES_PIN,GPIO_PIN_RESET)//RES
#define LCD_RES_Set()  HAL_GPIO_WritePin(RES_PORT,RES_PIN,GPIO_PIN_SET)

#define LCD_DC_Clr()   HAL_GPIO_WritePin(DC_PORT,DC_PIN,GPIO_PIN_RESET)//DC
#define LCD_DC_Set()   HAL_GPIO_WritePin(DC_PORT,DC_PIN,GPIO_PIN_SET)
 		     
#define LCD_CS_Clr()   HAL_GPIO_WritePin(CS_PORT,CS_PIN,GPIO_PIN_RESET)//CS
#define LCD_CS_Set()   HAL_GPIO_WritePin(CS_PORT,CS_PIN,GPIO_PIN_SET)


//画笔颜色
#define WHITE         	 (uint16_t)0xFFFF
#define BLACK         	 (uint16_t)0x0000	  
#define BLUE           	 (uint16_t)0x001F  
#define BRED             (uint16_t)0XF81F
#define GRED 			       (uint16_t)0XFFE0
#define GBLUE			       (uint16_t)0X07FF
#define RED           	 (uint16_t)0xF800
#define MAGENTA       	 (uint16_t)0xF81F
#define GREEN         	 (uint16_t)0x07E0
#define CYAN          	 (uint16_t)0x7FFF
#define YELLOW        	 (uint16_t)0xFFE0
#define BROWN 			     (uint16_t)0XBC40 //棕色
#define BRRED 			     (uint16_t)0XFC07 //棕红色
#define GRAY  			     (uint16_t)0X8430 //灰色
#define DARKBLUE      	 (uint16_t)0X01CF	//深蓝色
#define LIGHTBLUE      	 (uint16_t)0X7D7C	//浅蓝色  
#define GRAYBLUE       	 (uint16_t)0X5458 //灰蓝色
#define LIGHTGREEN     	 (uint16_t)0X841F //浅绿色
#define LGRAY 			     (uint16_t)0XC618 //浅灰色(PANNEL),窗体背景色
#define LGRAYBLUE        (uint16_t)0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE           (uint16_t)0X2B12 //浅棕蓝色(选择条目的反色)

void SPISendDataByte(uint8_t Data);
void SPISendData2Bytes(uint16_t Data);
void SPISendCmdByte(uint8_t Data);

void ST7789V_Reset(void);
void ST7789V_LcdInit(void);
void ST7789V_SetDir(uint8_t Dir_Mode);
void ST7789V_SetLcdAddress(uint16_t Start_X,uint16_t Start_Y,uint16_t End_X,uint16_t End_Y,uint8_t Dir_Mode);
void ST7789V_LcdDrawPoint(uint16_t X,uint16_t Y,uint16_t Color,uint8_t Dir_Mode);
void ST7789V_LcdDrawLine(uint16_t Start_X,uint16_t Start_Y,uint16_t End_X,uint16_t End_Y,uint16_t Color,uint8_t Dir_Mode);
void ST7789V_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 *color,uint8_t increasing);
void ST7789V_Fill_dma(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 *color_p);
void ST7789V_Open_Light(void);
void ST7789V_Set_Light(uint8_t dc);

#endif

LCD.c

#include "stm32f4xx.h"                  // Device header
#include "ST7789V.h"                   	

extern TIM_HandleTypeDef htim3;
extern SPI_HandleTypeDef hspi1;
extern DMA_HandleTypeDef hdma_spi1_tx;


void Lcd_Init(void)
{
	ST7789V_LcdInit();
}

void Lcd_SetAddr(uint16_t Start_X,uint16_t Start_Y,uint16_t End_X,uint16_t End_Y,uint8_t Dir_Mode)
{
	ST7789V_SetLcdAddress(Start_X,Start_Y,End_X,End_Y,Dir_Mode);
}

void Lcd_DrawPoint(uint16_t X,uint16_t Y,uint16_t Color,uint8_t Dir_Mode)
{
	ST7789V_LcdDrawPoint(X,Y,Color,Dir_Mode);
}

void Lcd_DrawLine(uint16_t Start_X,uint16_t Start_Y,uint16_t End_X,uint16_t End_Y,uint16_t Color,uint8_t Dir_Mode)
{
	ST7789V_LcdDrawLine(Start_X,Start_Y,End_X,End_Y,Color,Dir_Mode);
}

void Lcd_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 *color,uint8_t increasing)
{          
	ST7789V_Fill(xsta,ysta,xend,yend,color,increasing);		  	    
}

//spi+dma
void Lcd_Fill_dma(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 *color_p)
{
	ST7789V_Fill_dma(xsta,ysta,xend,yend,color_p);
}

void Lcd_Open_Light(void)
{
	ST7789V_Open_Light();
}

void Lcd_Set_Light(uint8_t dc)
{
	ST7789V_Set_Light(dc);
}




LCD.h

#ifndef __LCD_H__
#define __LCD_H__
#include "sys.h"


void Lcd_Init(void);
void Lcd_SetAddr(uint16_t Start_X,uint16_t Start_Y,uint16_t End_X,uint16_t End_Y,uint8_t Dir_Mode);
void Lcd_DrawPoint(uint16_t X,uint16_t Y,uint16_t Color,uint8_t Dir_Mode);
void Lcd_DrawLine(uint16_t Start_X,uint16_t Start_Y,uint16_t End_X,uint16_t End_Y,uint16_t Color,uint8_t Dir_Mode);
void Lcd_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 *color,uint8_t increasing);
void Lcd_Fill_dma(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 *color_p);
void Lcd_Open_Light(void);
void Lcd_Set_Light(uint8_t dc);


#endif


Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐