使用STM32 HAL库 驱动ST7789 显示屏
使用STM32 HAL库 驱动ST7789 显示屏
这是驱动好的效果图,我买的是中景园电子的一块IPS显示屏, 它的像素密度很高,显示非常细腻。
今天我用stm32 HAL库来驱动它。
使用STM32CubeMX生成代码
使用STM32CubeMX 生成功能, 其中主要设置了SPI和 驱动引脚
主要代码所示:
//引脚设置
#define LCD_D0_SCL_Pin GPIO_PIN_5
#define LCD_D0_SCL_GPIO_Port GPIOA
#define LCD_D1_SDA_Pin GPIO_PIN_7
#define LCD_D1_SDA_GPIO_Port GPIOA
#define LCD_RES_Pin GPIO_PIN_0
#define LCD_RES_GPIO_Port GPIOB
#define LCD_DC_Pin GPIO_PIN_1
#define LCD_DC_GPIO_Port GPIOB
#define LCD_CS_Pin GPIO_PIN_10
#define LCD_CS_GPIO_Port GPIOB
/* SPI1 init function */
static void MX_SPI1_Init(void)
{
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER; //主机模式
hspi1.Init.Direction = SPI_DIRECTION_2LINES; //只使能发送,两线制,因为买到的模块只能设置, 不能读数据。
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; //默认时钟位, 应当为低
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; //上升沿采集数据
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; //SPI时钟,使用72M主频,4分频
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, LCD_RES_Pin|LCD_DC_Pin|LCD_CS_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : LCD_RES_Pin LCD_DC_Pin LCD_CS_Pin */
GPIO_InitStruct.Pin = LCD_RES_Pin|LCD_DC_Pin|LCD_CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA7 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = LCD_D0_SCL_Pin|LCD_D1_SDA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
}
移植官方例程
中景园官方给的资料全是使用标准库的,很无奈, 不过看了一下,改动应该非常简单。
首先是改动驱动包里面的lcd.c
文件:
#include "lcd.h"
#include "oledfont.h"
#include "delay.h"
#include "bmp.h"
u16 BACK_COLOR; //背景色
/******************************************************************************
函数说明:LCD串行数据写入函数
入口数据:dat 要写入的串行数据
返回值: 无
******************************************************************************/
void LCD_Writ_Bus(u8 dat)
{
u8 i;
OLED_CS_Clr();
for(i=0;i<8;i++)
{
OLED_SCLK_Clr();
if(dat&0x80)
OLED_SDIN_Set();
else
OLED_SDIN_Clr();
OLED_SCLK_Set();
dat<<=1;
}
OLED_CS_Set();
}
/*把上面的函数改成下面这种, 因为中景园给的例程是使用模拟spi的时序的,刷新非常慢,
我们改成如下这种,在使用的时候要事先初始化单片机SPI模块*/
void LCD_Writ_Bus(u8 dat)
{
u8 i;
OLED_CS_Clr();
HAL_SPI_Transmit(&hspi1, &dat, 1, 0xffff);
OLED_CS_Set();
}
再改动lcd.h
文件:
//-----------------OLED端口定义----------------
#define OLED_SCLK_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_5)
#define OLED_SCLK_Set() GPIO_SetBits(GPIOA,GPIO_Pin_5)
#define OLED_SDIN_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_7)//DIN
#define OLED_SDIN_Set() GPIO_SetBits(GPIOA,GPIO_Pin_7)
#define OLED_RST_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_0)//RES
#define OLED_RST_Set() GPIO_SetBits(GPIOB,GPIO_Pin_0)
#define OLED_DC_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_1)//DC
#define OLED_DC_Set() GPIO_SetBits(GPIOB,GPIO_Pin_1)
#define OLED_CS_Clr() GPIO_ResetBits(GPIOA,GPIO_Pin_4)//CS
#define OLED_CS_Set() GPIO_SetBits(GPIOA,GPIO_Pin_4)
#define OLED_BLK_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_10)//BLK
#define OLED_BLK_Set() GPIO_SetBits(GPIOB,GPIO_Pin_10)
/*上面是原来例程里面的程序,我改成下面这种的, 因为已经使用了硬件SPI ,所以去掉了时钟线与数据线的设置,
其他的仍保留,使用固件库HAL_GPIO_WritePin() 函数来设置引脚电平*/
//-----------------OLED端口定义----------------
#define OLED_RES_Clr() HAL_GPIO_WritePin(LCD_RES_GPIO_Port, LCD_RES_Pin, GPIO_PIN_RESET)//RES
#define OLED_RES_Set() HAL_GPIO_WritePin(LCD_RES_GPIO_Port, LCD_RES_Pin, GPIO_PIN_SET)
#define OLED_DC_Clr() HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_RESET)//DC
#define OLED_DC_Set() HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET)
#define OLED_CS_Clr() HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET)///CS
#define OLED_CS_Set() HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET)
// #define OLED_BLK_Clr() HAL_GPIO_WritePin(, LCD_DC_Pin, GPIO_PIN_RESET)///BLK
// #define OLED_BLK_Set() HAL_GPIO_WritePin(, LCD_DC_Pin, GPIO_PIN_SET)
接着,再把初始化函数里面的引脚初始化部分注释掉,也把里面的延时函数更改成HAL库的:
至此,程序移植已经可以了,在main里面执行初始化屏幕的函数就可以了。
/*=================IPS显示屏初始化=============*/
Lcd_Init();
LCD_Clear(GREEN);
BACK_COLOR = GREEN;
posted on
2019-08-06 21:02 Gentleaves 阅读(
...) 评论(
...) 编辑 收藏