STM32F407HAL库模拟SPI驱动1.8寸TFT(ST7735)屏幕

        找了好久没找到能用的,就自己移植HAL库,现在分享一下

        最近屏幕涨价不少,为了图便宜就在某宝花了23买了一块1.8寸无触摸TFT(ST7735)的屏幕,买回来后发现跟其他的有些许不太一样,网上没看见相关参考,仅有几个店家给的例程,但是例程里面的针脚定义跟我拿到手的也不一样,没办法控制背光,我拿到的就是下面这块屏幕

 可以看到仅有CLK、SDA(MOSI)、RS、RST、CS五个有效引脚,少了控制背光LED引脚的,但是这并不是大问题,因为项目其他功能都是使用HAL库开发,所以就只能把STM32F103固件库的驱动例程自己改一下移植到STM32F407HAL库上。


目录

硬件平台

 接线方式

STM32CubeMX配置

代码部分

运行效果

取模部分


硬件平台

 本次使用的硬件平台是STM32F407VET6核心板

软件则用的是 Keil5.35 和 STM32CubeMX


 接线方式

  •  VCC              3.3V(5V容易烧坏屏幕)
  • GND               GND
  • GND               GND
  • NC                  悬空
  • NC                  悬空
  • NC                  悬空
  • CLK                PD0
  • SDA/MOSI      PD1
  • RS/DC            PD2
  • RST/RES        PD3
  • CS/CE             PD4

STM32CubeMX配置

第一步选择芯片:

 然后找到你开发板上的芯片型号(我推荐是把自己开发板上的芯片型号点哪个星星收藏一下,下次直接点搜索框旁边的收藏夹就能直接选择了)

 第二步开启调试(防止芯片锁住)并配置IO口

 选择使用外部高速时钟HSE

 配置IO

后面的四个配置方式一样无上下拉,推挽输出,并把IO速率开到最高very high(为了屏幕刷新快一点 )

 

第三步配置时钟

因为板子上带的是8M的晶振所以需要改一下,cubemx默认25M晶振 

 第四步设置工程配置

 

 最后一步生成代码

先生成报告,得到一个cubemx的ioc文件等后续还可以继续配置

接着点右上角生成代码(生成代码的路径不能存在中文,否则生成代码会失败)

 

 生成成功后直接点击打开工程

 打开工程后配置一下下载

 接着选择pack取消掉(防止下载后不会复位运行)

完成之后先编译一遍工程

 

 然后回到工程目录创建一文件用来装移植过来的程序

打开里面放移植的程序

 

回到keil接着点这个

 接着新建一个

 选中新键的往里面添加文件

找到刚刚移植过来的C文件添加进去再点ok

 

 接着添加头文件目录

 

 接着新建一个路径,点旁边序号选择头文件路径

 

 然后点ok

到这里大部分移植过程已经完成了,接下来就是改代码


代码部分

Lcd_Driver.h(部分代码)

#include "stm32f4xx_hal.h"
#include "stm32f407xx.h"

#define RED  	0xf800
#define GREEN	0x07e0
#define BLUE 	0x001f
#define WHITE	0xffff
#define BLACK	0x0000
#define YELLOW  0xFFE0
#define GRAY0   0xEF7D   	//灰色0 3165 00110 001011 00101
#define GRAY1   0x8410      	//灰色1      00000 000000 00000
#define GRAY2   0x4208      	//灰色2  1111111111011111




#define LCD_CTRL   	  	GPIOD		//定义TFT数据端口
#define LCD_RS         	GPIO_PIN_2	//TFT --RS/DC
#define LCD_CS        	GPIO_PIN_4  //TFT --CS/CE
#define LCD_RST     		GPIO_PIN_3	//TFT --RST
#define LCD_SCL        	GPIO_PIN_0	//TFT --SCL/SCK
#define LCD_SDA        	GPIO_PIN_1	//TFT --SDA/DIN



#define	LCD_CS_SET  	LCD_CTRL->BSRR=LCD_CS    
#define	LCD_RS_SET  	LCD_CTRL->BSRR=LCD_RS    
#define	LCD_SDA_SET  	LCD_CTRL->BSRR=LCD_SDA    
#define	LCD_SCL_SET  	LCD_CTRL->BSRR=LCD_SCL    
#define	LCD_RST_SET  	LCD_CTRL->BSRR=LCD_RST    
#define	LCD_LED_SET  	LCD_CTRL->BSRR=LCD_LED 




void LCD_GPIO_Init(void);
void Lcd_WriteIndex(uint8_t Index);
void Lcd_WriteData(uint8_t Data);
void Lcd_WriteReg(uint8_t Index,uint8_t Data);
uint16_t Lcd_ReadReg(uint8_t LCD_Reg);
void Lcd_Reset(void);
void Lcd_Init();
void Lcd_Clear(uint16_t Color);
void Lcd_SetXY(uint16_t x,uint16_t y);
void Gui_DrawPoint(uint16_t x,uint16_t y,uint16_t Data);
unsigned int Lcd_ReadPoint(uint16_t x,uint16_t y);

Lcd_Driver.c(部分代码)

/******************************************************************************
接口定义在Lcd_Driver.h内
#define LCD_CTRL   	  	GPIOD		
#define LCD_SCL        	GPIO_Pin_0	//SCL/SCK
#define LCD_SDA        	GPIO_Pin_1	//SDA/DIN
#define LCD_RS         	GPIO_Pin_2	//RS/DC
#define LCD_RST     	GPIO_Pin_3	//RST
#define LCD_CS        	GPIO_Pin_4  //CS/CE
*******************************************************************************/
void LCD_GPIO_Init(void)
{

	GPIO_InitTypeDef GPIO_InitStruct = {0};
	      
	 __HAL_RCC_GPIOD_CLK_ENABLE();
	
	GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
      
}


/****************************************************************************
* 名    称:Lcd_WriteIndex(uint8_t Index)
* 功    能:写 ST7735 控制器寄存器地址
* 入口参数:Index   寄存器地址
* 出口参数:无
* 说    明:调用前需先选中控制器,内部函数
* 调用方法:Lcd_WriteIndex(0xB1);
****************************************************************************/
void Lcd_WriteIndex(uint8_t Index)
{
   uint8_t i=0;
   //SPI 写命令时序开始
   LCD_CS_CLR;
   LCD_RS_CLR;

   for(i=8;i>0;i--)
   {
    if(Index&0x80){	
	  LCD_SDA_SET; }//输出数据
    else 
	  LCD_SDA_CLR; 

      LCD_SCL_CLR;      
      LCD_SCL_SET;
      Index<<=1; 
   }
   LCD_CS_SET;
}

/****************************************************************************
* 名    称:void Lcd_WriteData(uint8_t Data)
* 功    能:写 ST7735 寄存器数据
* 入口参数:Data     寄存器数据
* 出口参数:无
* 说    明:向控制器指定地址写入数据,调用前需先写寄存器地址,内部函数
* 调用方法:Lcd_WriteData(0x01);
****************************************************************************/
void Lcd_WriteData(uint8_t Data)
{
   uint8_t i=0;
   LCD_CS_CLR;
   LCD_RS_SET;

   for(i=8;i>0;i--)
   {
      if(Data&0x80)	{
	  LCD_SDA_SET;} //输出数据
      else LCD_SDA_CLR;
	   
      LCD_SCL_CLR;       
      LCD_SCL_SET;
      Data<<=1; 
   }
   LCD_CS_SET; 
}

/*************************************************
函数名:Lcd_WriteReg
功能:写寄存器
入口参数:Index,Data
返回值:无
*************************************************/
void Lcd_WriteReg(uint8_t Index,uint8_t Data)
{
	Lcd_WriteIndex(Index);
   	Lcd_WriteData(Data);
}

/*************************************************
函数名:Lcd_Reset
功能:重置LCD
入口参数:无
返回值:无
*************************************************/
void Lcd_Reset(void)
{
	LCD_RST_CLR;
	HAL_Delay(100);
	LCD_RST_SET;
	HAL_Delay(50);
}


/*************************************************
函数名:Lcd_SetRegion
功能:设置lcd显示区域,在此区域写点数据自动换行
入口参数:x_start起点,y_start起点,x_end,y_end终点
返回值:无
*************************************************/
void Lcd_SetRegion(uint16_t x_start,uint16_t y_start,uint16_t x_end,uint16_t y_end)
{		
	Lcd_WriteIndex(0x2a);
	Lcd_WriteData(0x00);
	Lcd_WriteData(x_start);
	Lcd_WriteData(0x00);
	Lcd_WriteData(x_end);

	Lcd_WriteIndex(0x2b);
	Lcd_WriteData(0x00);
	Lcd_WriteData(y_start);
	Lcd_WriteData(0x00);
	Lcd_WriteData(y_end);

	Lcd_WriteIndex(0x2c);

}

/*************************************************
函数名:Lcd_SetXY
功能:设置lcd显示起始点
入口参数:xy坐标
返回值:无
*************************************************/
void Lcd_SetXY(uint16_t x,uint16_t y)
{
  	Lcd_SetRegion(x,y,x,y);
}

	
/*************************************************
函数名:Gui_DrawPoint
功能:画一个点
入口参数:x,y,Data
返回值:无
*************************************************/
void Gui_DrawPoint(uint16_t x,uint16_t y,uint16_t Data)
{
	Lcd_SetRegion(x,y,x+1,y+1);
	Lcd_WriteData(Data>>8);
	Lcd_WriteData(Data);

}    

/*****************************************
函数名:Lcd_ReadPoint
函数功能:读TFT某一点的颜色                          
出口参数:Data  点颜色值                                 
******************************************/
unsigned int Lcd_ReadPoint(uint16_t x,uint16_t y)
{
  unsigned int Data;
  Lcd_SetXY(x,y);

  //Lcd_ReadData();//丢掉无用字节
  //Data=Lcd_ReadData();
  Lcd_WriteData(Data);
  return Data;
}
/*************************************************
函数名:Lcd_Clear
功能:全屏清屏函数
入口参数:填充颜色Color
返回值:无
*************************************************/
void Lcd_Clear(uint16_t Color)               
{	
   unsigned int i,m;
   Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);
   Lcd_WriteIndex(0x2C);
   for(i=0;i<128;i++)
    for(m=0;m<160;m++)
    {	
	  	Lcd_WriteData(Color>>8);
			Lcd_WriteData(Color);
    }   
}

上面值得注意的是F103的BSRR置位寄存器和BRR复位寄存器在F407中都已经变成


如果屏幕边上有花屏,表示像素没填充够,修改Lcd_Driver.c和GUI.c内循环体数值即可

而整个屏幕图形显示函数的编写实现实际上就是点亮对应坐标像素并显示颜色


 好了到这里全部工作就已经全部完成,烧录看一下效果。


运行效果

 可以看见屏幕刷新率还是蛮快的,得益于STM32F407IO速率的提升

而F103则相对慢一些


取模部分

图片取模

 文字取模


 当然了STM32F103C8T6HAL库也移植有,如果有需要在评论留言。

代码我已经上传,有积分的好兄弟给点,没有的评论留个邮箱

完整代码

版权声明:本文为CSDN博主「fbuilke」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_50846041/article/details/119433305

        找了好久没找到能用的,就自己移植HAL库,现在分享一下

        最近屏幕涨价不少,为了图便宜就在某宝花了23买了一块1.8寸无触摸TFT(ST7735)的屏幕,买回来后发现跟其他的有些许不太一样,网上没看见相关参考,仅有几个店家给的例程,但是例程里面的针脚定义跟我拿到手的也不一样,没办法控制背光,我拿到的就是下面这块屏幕

 可以看到仅有CLK、SDA(MOSI)、RS、RST、CS五个有效引脚,少了控制背光LED引脚的,但是这并不是大问题,因为项目其他功能都是使用HAL库开发,所以就只能把STM32F103固件库的驱动例程自己改一下移植到STM32F407HAL库上。


目录

硬件平台

 接线方式

STM32CubeMX配置

代码部分

运行效果

取模部分


硬件平台

 本次使用的硬件平台是STM32F407VET6核心板

软件则用的是 Keil5.35 和 STM32CubeMX


 接线方式

  •  VCC              3.3V(5V容易烧坏屏幕)
  • GND               GND
  • GND               GND
  • NC                  悬空
  • NC                  悬空
  • NC                  悬空
  • CLK                PD0
  • SDA/MOSI      PD1
  • RS/DC            PD2
  • RST/RES        PD3
  • CS/CE             PD4

STM32CubeMX配置

第一步选择芯片:

 然后找到你开发板上的芯片型号(我推荐是把自己开发板上的芯片型号点哪个星星收藏一下,下次直接点搜索框旁边的收藏夹就能直接选择了)

 第二步开启调试(防止芯片锁住)并配置IO口

 选择使用外部高速时钟HSE

 配置IO

后面的四个配置方式一样无上下拉,推挽输出,并把IO速率开到最高very high(为了屏幕刷新快一点 )

 

第三步配置时钟

因为板子上带的是8M的晶振所以需要改一下,cubemx默认25M晶振 

 第四步设置工程配置

 

 最后一步生成代码

先生成报告,得到一个cubemx的ioc文件等后续还可以继续配置

接着点右上角生成代码(生成代码的路径不能存在中文,否则生成代码会失败)

 

 生成成功后直接点击打开工程

 打开工程后配置一下下载

 接着选择pack取消掉(防止下载后不会复位运行)

完成之后先编译一遍工程

 

 然后回到工程目录创建一文件用来装移植过来的程序

打开里面放移植的程序

 

回到keil接着点这个

 接着新建一个

 选中新键的往里面添加文件

找到刚刚移植过来的C文件添加进去再点ok

 

 接着添加头文件目录

 

 接着新建一个路径,点旁边序号选择头文件路径

 

 然后点ok

到这里大部分移植过程已经完成了,接下来就是改代码


代码部分

Lcd_Driver.h(部分代码)

#include "stm32f4xx_hal.h"
#include "stm32f407xx.h"

#define RED  	0xf800
#define GREEN	0x07e0
#define BLUE 	0x001f
#define WHITE	0xffff
#define BLACK	0x0000
#define YELLOW  0xFFE0
#define GRAY0   0xEF7D   	//灰色0 3165 00110 001011 00101
#define GRAY1   0x8410      	//灰色1      00000 000000 00000
#define GRAY2   0x4208      	//灰色2  1111111111011111




#define LCD_CTRL   	  	GPIOD		//定义TFT数据端口
#define LCD_RS         	GPIO_PIN_2	//TFT --RS/DC
#define LCD_CS        	GPIO_PIN_4  //TFT --CS/CE
#define LCD_RST     		GPIO_PIN_3	//TFT --RST
#define LCD_SCL        	GPIO_PIN_0	//TFT --SCL/SCK
#define LCD_SDA        	GPIO_PIN_1	//TFT --SDA/DIN



#define	LCD_CS_SET  	LCD_CTRL->BSRR=LCD_CS    
#define	LCD_RS_SET  	LCD_CTRL->BSRR=LCD_RS    
#define	LCD_SDA_SET  	LCD_CTRL->BSRR=LCD_SDA    
#define	LCD_SCL_SET  	LCD_CTRL->BSRR=LCD_SCL    
#define	LCD_RST_SET  	LCD_CTRL->BSRR=LCD_RST    
#define	LCD_LED_SET  	LCD_CTRL->BSRR=LCD_LED 




void LCD_GPIO_Init(void);
void Lcd_WriteIndex(uint8_t Index);
void Lcd_WriteData(uint8_t Data);
void Lcd_WriteReg(uint8_t Index,uint8_t Data);
uint16_t Lcd_ReadReg(uint8_t LCD_Reg);
void Lcd_Reset(void);
void Lcd_Init();
void Lcd_Clear(uint16_t Color);
void Lcd_SetXY(uint16_t x,uint16_t y);
void Gui_DrawPoint(uint16_t x,uint16_t y,uint16_t Data);
unsigned int Lcd_ReadPoint(uint16_t x,uint16_t y);

Lcd_Driver.c(部分代码)

/******************************************************************************
接口定义在Lcd_Driver.h内
#define LCD_CTRL   	  	GPIOD		
#define LCD_SCL        	GPIO_Pin_0	//SCL/SCK
#define LCD_SDA        	GPIO_Pin_1	//SDA/DIN
#define LCD_RS         	GPIO_Pin_2	//RS/DC
#define LCD_RST     	GPIO_Pin_3	//RST
#define LCD_CS        	GPIO_Pin_4  //CS/CE
*******************************************************************************/
void LCD_GPIO_Init(void)
{

	GPIO_InitTypeDef GPIO_InitStruct = {0};
	      
	 __HAL_RCC_GPIOD_CLK_ENABLE();
	
	GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
      
}


/****************************************************************************
* 名    称:Lcd_WriteIndex(uint8_t Index)
* 功    能:写 ST7735 控制器寄存器地址
* 入口参数:Index   寄存器地址
* 出口参数:无
* 说    明:调用前需先选中控制器,内部函数
* 调用方法:Lcd_WriteIndex(0xB1);
****************************************************************************/
void Lcd_WriteIndex(uint8_t Index)
{
   uint8_t i=0;
   //SPI 写命令时序开始
   LCD_CS_CLR;
   LCD_RS_CLR;

   for(i=8;i>0;i--)
   {
    if(Index&0x80){	
	  LCD_SDA_SET; }//输出数据
    else 
	  LCD_SDA_CLR; 

      LCD_SCL_CLR;      
      LCD_SCL_SET;
      Index<<=1; 
   }
   LCD_CS_SET;
}

/****************************************************************************
* 名    称:void Lcd_WriteData(uint8_t Data)
* 功    能:写 ST7735 寄存器数据
* 入口参数:Data     寄存器数据
* 出口参数:无
* 说    明:向控制器指定地址写入数据,调用前需先写寄存器地址,内部函数
* 调用方法:Lcd_WriteData(0x01);
****************************************************************************/
void Lcd_WriteData(uint8_t Data)
{
   uint8_t i=0;
   LCD_CS_CLR;
   LCD_RS_SET;

   for(i=8;i>0;i--)
   {
      if(Data&0x80)	{
	  LCD_SDA_SET;} //输出数据
      else LCD_SDA_CLR;
	   
      LCD_SCL_CLR;       
      LCD_SCL_SET;
      Data<<=1; 
   }
   LCD_CS_SET; 
}

/*************************************************
函数名:Lcd_WriteReg
功能:写寄存器
入口参数:Index,Data
返回值:无
*************************************************/
void Lcd_WriteReg(uint8_t Index,uint8_t Data)
{
	Lcd_WriteIndex(Index);
   	Lcd_WriteData(Data);
}

/*************************************************
函数名:Lcd_Reset
功能:重置LCD
入口参数:无
返回值:无
*************************************************/
void Lcd_Reset(void)
{
	LCD_RST_CLR;
	HAL_Delay(100);
	LCD_RST_SET;
	HAL_Delay(50);
}


/*************************************************
函数名:Lcd_SetRegion
功能:设置lcd显示区域,在此区域写点数据自动换行
入口参数:x_start起点,y_start起点,x_end,y_end终点
返回值:无
*************************************************/
void Lcd_SetRegion(uint16_t x_start,uint16_t y_start,uint16_t x_end,uint16_t y_end)
{		
	Lcd_WriteIndex(0x2a);
	Lcd_WriteData(0x00);
	Lcd_WriteData(x_start);
	Lcd_WriteData(0x00);
	Lcd_WriteData(x_end);

	Lcd_WriteIndex(0x2b);
	Lcd_WriteData(0x00);
	Lcd_WriteData(y_start);
	Lcd_WriteData(0x00);
	Lcd_WriteData(y_end);

	Lcd_WriteIndex(0x2c);

}

/*************************************************
函数名:Lcd_SetXY
功能:设置lcd显示起始点
入口参数:xy坐标
返回值:无
*************************************************/
void Lcd_SetXY(uint16_t x,uint16_t y)
{
  	Lcd_SetRegion(x,y,x,y);
}

	
/*************************************************
函数名:Gui_DrawPoint
功能:画一个点
入口参数:x,y,Data
返回值:无
*************************************************/
void Gui_DrawPoint(uint16_t x,uint16_t y,uint16_t Data)
{
	Lcd_SetRegion(x,y,x+1,y+1);
	Lcd_WriteData(Data>>8);
	Lcd_WriteData(Data);

}    

/*****************************************
函数名:Lcd_ReadPoint
函数功能:读TFT某一点的颜色                          
出口参数:Data  点颜色值                                 
******************************************/
unsigned int Lcd_ReadPoint(uint16_t x,uint16_t y)
{
  unsigned int Data;
  Lcd_SetXY(x,y);

  //Lcd_ReadData();//丢掉无用字节
  //Data=Lcd_ReadData();
  Lcd_WriteData(Data);
  return Data;
}
/*************************************************
函数名:Lcd_Clear
功能:全屏清屏函数
入口参数:填充颜色Color
返回值:无
*************************************************/
void Lcd_Clear(uint16_t Color)               
{	
   unsigned int i,m;
   Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);
   Lcd_WriteIndex(0x2C);
   for(i=0;i<128;i++)
    for(m=0;m<160;m++)
    {	
	  	Lcd_WriteData(Color>>8);
			Lcd_WriteData(Color);
    }   
}

上面值得注意的是F103的BSRR置位寄存器和BRR复位寄存器在F407中都已经变成


如果屏幕边上有花屏,表示像素没填充够,修改Lcd_Driver.c和GUI.c内循环体数值即可

而整个屏幕图形显示函数的编写实现实际上就是点亮对应坐标像素并显示颜色


 好了到这里全部工作就已经全部完成,烧录看一下效果。


运行效果

 可以看见屏幕刷新率还是蛮快的,得益于STM32F407IO速率的提升

而F103则相对慢一些


取模部分

图片取模

 文字取模


 当然了STM32F103C8T6HAL库也移植有,如果有需要在评论留言。

代码我已经上传,有积分的好兄弟给点,没有的评论留个邮箱

完整代码

版权声明:本文为CSDN博主「fbuilke」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_50846041/article/details/119433305

生成海报
点赞 0

fbuilke

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

rt_thread hc32f460开发四:pwm驱动移植

RT-Thread 驱动开发简介 RT-Thread驱动开发最开始应该是要阅读官方的文档,理解驱动的运行原理和使用方法。PWM部分的文档在这里https://www.rt-thread.org/document/site/#/rt

w25qxx spi flash WP写保护引脚的正确使用方式

WP引脚使用方式 spi flash有一个外部写保护引脚WP, 此引脚并不是直接保护flash上的数据内容,而是保护状态寄存器不被异常改写.flash上的内容写保护是通过状态寄存器的BPxbit的不同组合来实现的. 对于环境相对恶劣的使用场景