STM32F4x HAL库软硬SPI驱动ST7735s 1.8寸LCD屏幕详解

单片机:STM32F4x HAL库软硬SPI驱动ST7735s 1.8寸LCD屏幕

说明:此篇为学习记录。可能存在错误或者不足。如有问题请指出。

硬件环境

主控芯片:STM32F411CEU6
主控开发板:WeAct STM32F411CEU6最小系统板
TFT-LCD屏幕:合宙1.8寸TFT-LCD,驱动为ST7735s

软件环境

MDK版本:5,32
HAL库版本:1.27.1
STM32CubeMX版本:6.7.0

从手册了解一些必要信息

ST7735s支持8080并口,3线和4线串行接口,模块的驱动方式是4线串行驱动方式也就是四线类SPI通信方式。
手册内容很多,这里简单记录必要的信息。

读写模式以及时序

1、四线通信方式下,D/CX(DC,D/C)引脚拉低表示命令,拉高表示数据。
2、高位在前
3、片选(CS,CSX)拉低(下降沿)为选中

和SPI时序相同,不过数据线只有一条,必须接到MOSI上。

1、向模块读数据时,需要主机先发送指令,然后st7735向主机发送数据,需要拉高CS在其期间直到下个指令。
注:读数据很少用到。

显示缓存(frame memory)寻址

1、128×160分辨率下,行寻址范围为0-159,列寻址范围为0-127,超过这个范围模块不接受。
2、行列以及扫描顺序都可以镜像翻转,通过配置MADCTL的MY,MX,ML,MH实现。
3、颜色通道可配置为RGB或者BGR模式,通过MADCTL的RGB位可配置。
4、补充,st7735可选择12-bit、16-bit、18-bit即,2k(RGB444)、65K(RGB565)、262k(RGB666)颜色模式。

显示模式

写入显示缓存前需要指定显示窗口,通过xs,xe,ys,ye设置,完成窗口设置后将像素数据按照扫描方式写入缓存即可进行显示。


这几张图说明在控制器缓存和模块写方向都是从左到右、上到下的情况下,MX,MY,MV这几个不同值下的显示情况,如果发现屏幕显示不全或者(0,0)点不是期待的位置可按照这个图重新配置MX,MY,MV这几位的值。

一些指令的解释和初始化程序

这里不放手册的图了,太多了。


手册上的命令太多了,看麻了,以上几个是可能用到的,如果有需要看手册第十章即可。

void LCD_Init(void)
{
#if USE_SIM_SPI
    LCD_SIM_SPI_GPIO_Init();
#endif
	LCD_RES_0();//复位
	HAL_Delay(100);
	LCD_RES_1();
	HAL_Delay(100);
	
	LCD_BLK_1();//打开背光
    HAL_Delay(100);
	
	//************* Start Initial Sequence **********//
	LCD_SPI_Send_Cmd(0x11); //Sleep out 
	HAL_Delay(120);              //Delay 120ms 
	//------------------------------------ST7735S 帧率设置-----------------------------------------// 
	LCD_SPI_Send_Cmd(0xB1); 
	LCD_SPI_Send_Data_8(0x01); 
	LCD_SPI_Send_Data_8(0x2C); 
	LCD_SPI_Send_Data_8(0x2D); 
	LCD_SPI_Send_Cmd(0xB2); 
	LCD_SPI_Send_Data_8(0x01);
	LCD_SPI_Send_Data_8(0x2C); 
	LCD_SPI_Send_Data_8(0x2D); 
	LCD_SPI_Send_Cmd(0xB3); 
	LCD_SPI_Send_Data_8(0x01); 
	LCD_SPI_Send_Data_8(0x2C); 
	LCD_SPI_Send_Data_8(0x2D); 
	LCD_SPI_Send_Data_8(0x01); 
	LCD_SPI_Send_Data_8(0x2C); 
	LCD_SPI_Send_Data_8(0x2D); 
	//------------------------------------End ST7735S Frame Rate---------------------------------// 
	LCD_SPI_Send_Cmd(0xB4); //Dot inversion 
	LCD_SPI_Send_Data_8(0x07); 
	//------------------------------------ST7735S 功率设置---------------------------------// 
	LCD_SPI_Send_Cmd(0xC0); 
	LCD_SPI_Send_Data_8(0xA2); 
	LCD_SPI_Send_Data_8(0x02); 
	LCD_SPI_Send_Data_8(0x84); 
	LCD_SPI_Send_Cmd(0xC1); 
	LCD_SPI_Send_Data_8(0xC5); 
	LCD_SPI_Send_Cmd(0xC2); 
	LCD_SPI_Send_Data_8(0x0A); 
	LCD_SPI_Send_Data_8(0x00); 
	LCD_SPI_Send_Cmd(0xC3); 
	LCD_SPI_Send_Data_8(0x8A); 
	LCD_SPI_Send_Data_8(0x2A); 
	LCD_SPI_Send_Cmd(0xC4); 
	LCD_SPI_Send_Data_8(0x8A); 
	LCD_SPI_Send_Data_8(0xEE); 
	//---------------------------------End ST7735S Power Sequence-------------------------------------// 
	LCD_SPI_Send_Cmd(0xC5); //VCOM 
	LCD_SPI_Send_Data_8(0x0E); 
	LCD_SPI_Send_Cmd(0x36);//0x00 0x80 0x40 0xc0 0x20 0xA0 0x60 0xE0; 
	LCD_SPI_Send_Data_8(0x00);

	//------------------------------------ST7735S Gamma Sequence---------------------------------// 
    LCD_SPI_Send_Cmd(0xE0); 
	LCD_SPI_Send_Data_8(0x04); 
	LCD_SPI_Send_Data_8(0x22); 
	LCD_SPI_Send_Data_8(0x07); 
	LCD_SPI_Send_Data_8(0x0A); 
	LCD_SPI_Send_Data_8(0x2E); 
	LCD_SPI_Send_Data_8(0x30); 
	LCD_SPI_Send_Data_8(0x25); 
	LCD_SPI_Send_Data_8(0x2A); 
	LCD_SPI_Send_Data_8(0x28); 
	LCD_SPI_Send_Data_8(0x26); 
	LCD_SPI_Send_Data_8(0x2E); 
	LCD_SPI_Send_Data_8(0x3A); 
	LCD_SPI_Send_Data_8(0x00); 
	LCD_SPI_Send_Data_8(0x01); 
	LCD_SPI_Send_Data_8(0x03); 
	LCD_SPI_Send_Data_8(0x13); 
	LCD_SPI_Send_Cmd(0xE1); 
	LCD_SPI_Send_Data_8(0x04); 
	LCD_SPI_Send_Data_8(0x16); 
	LCD_SPI_Send_Data_8(0x06); 
	LCD_SPI_Send_Data_8(0x0D); 
	LCD_SPI_Send_Data_8(0x2D); 
	LCD_SPI_Send_Data_8(0x26); 
	LCD_SPI_Send_Data_8(0x23); 
	LCD_SPI_Send_Data_8(0x27); 
	LCD_SPI_Send_Data_8(0x27); 
	LCD_SPI_Send_Data_8(0x25); 
	LCD_SPI_Send_Data_8(0x2D); 
	LCD_SPI_Send_Data_8(0x3B); 
	LCD_SPI_Send_Data_8(0x00); 
	LCD_SPI_Send_Data_8(0x01); 
	LCD_SPI_Send_Data_8(0x04); 
	LCD_SPI_Send_Data_8(0x13); 
	//------------------------------------End ST7735S Gamma Sequence-----------------------------// 
	LCD_SPI_Send_Cmd(0x3A); //65k mode 
	LCD_SPI_Send_Data_8(0x05); 
	LCD_SPI_Send_Cmd(0x29); //Display on 
}

帧率和功率,伽马设置无需理解。

CubeMX配置以及SPI通信部分源码

时钟不要太高,不要超过14M,硬件SPI情况下有可能会初始化不成功,加一些延时即可。

#if USE_SIM_SPI
void LCD_SIM_SPI_GPIO_Init(void)
{
      GPIO_InitTypeDef GPIO_InitStruct = {0};
    
      __HAL_RCC_GPIOB_CLK_ENABLE();
    
      /*Configure GPIO pins : PBPin PBPin PBPin */
  GPIO_InitStruct.Pin = SPI_SIM_SDA_PIN|SPI_SIM_SCL_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void LCD_Writ_Bus(unsigned char dat)
{
    unsigned char i;
	LCD_CS_0();
	for(i=0;i<8;i++)
	{			  
		LCD_SCLK_0();
		if(dat&0x80)
		{
		   LCD_MOSI_1();
		}
		else
		{
		   LCD_MOSI_0();
		}
		LCD_SCLK_1();
		dat<<=1;
	}	
  LCD_CS_1();	
}

void LCD_WR_DATA(unsigned char dat)
{
    LCD_Writ_Bus(dat>>8);
	LCD_Writ_Bus(dat);
}

void LCD_WR_DATA8(unsigned char dat)
{
    LCD_Writ_Bus(dat);
}

void LCD_WR_REG(unsigned char dat)
{
    LCD_DC_0();//写命令
	LCD_Writ_Bus(dat);
	LCD_DC_1();//写数据
}

void LCD_SPI_Send_Cmd(unsigned char CMD)
{
    LCD_WR_REG(CMD);
}

void LCD_SPI_Send_Data_8(unsigned char data)
{
    LCD_WR_DATA8(data);
}

void LCD_SPI_Send_Data_816(unsigned int data)
{
    LCD_WR_DATA(data);
}
#else
/********************************************
@Function name;             void LCD_SPI_Send_Cmd(unsigned char CMD)
@Function description;      LCD发送指令
@Function input;
@Function output;
@Date;
*********************************************/
/**********FUNTCTION NOTICE********

**************************/
void LCD_SPI_Send_Cmd(unsigned char CMD)
{   
    LCD_CS_0();
    LCD_DC_0();  
    HAL_SPI_Transmit(&hspi2, &CMD, 1, 0xffff);
    LCD_CS_1();  
   // HAL_Delay(1);
}

/********************************************
@Function name;		    void LCD_SPI_Send_Data_8(unsigned char data)
@Function description;	发送八位数据
@Function input;		
@Function output;		
@Date;			
*********************************************/
/**********FUNTCTION NOTICE********

**************************/
void LCD_SPI_Send_Data_8(unsigned char data)
{
    LCD_CS_0();
    LCD_DC_1();
    HAL_SPI_Transmit(&hspi2, &data, 1, 0xffff);
    LCD_CS_1();
   // HAL_Delay(1);
}

/********************************************
@Function name;		   void LCD_SPI_Send_Data_16(unsigned int data) 
@Function description;	发送十六位数据
@Function input;		
@Function output;		
@Date;			特别注意很少需要直接发送十六位数据,RGB565模式下发送像素数据需要。
*********************************************/
/**********FUNTCTION NOTICE********

**************************/
void LCD_SPI_Send_Data_16(unsigned int data)
{
    LCD_SPI_Send_Data_8(data >> 8);
    LCD_SPI_Send_Data_8(data);
}
#endif

附件:参考手册以及例程(来自合宙Lua社区,其实就是中景园的例程)

Lua社区:https://doc.openluat.com/wiki/21?wiki_page_id=2650
例程下载:https://cdn.openluat-luatcommunity.openluat.com/attachment/20211112203446851_ST7735_1.8LCD%E7%A8%8B%E5%BA%8F%E6%BA%90%E7%A0%81_%E5%90%88%E5%AE%99.zip
或者去合宙淘宝店找下也可以。

物联沃分享整理
物联沃-IOTWORD物联网 » STM32F4x HAL库软硬SPI驱动ST7735s 1.8寸LCD屏幕详解

发表评论