STM32 CUBE SPI+DMA+LVGL驱动ST7789 LCD屏

SPI驱动ST7789屏的资料很多,但是用DMA驱动的却很少,我用到LVGL库,用spi进行数据传输时,屏幕刷新非常慢,需改为DMA,但是按网传的一些配置方法去做时,用DMA发送数据一直遇到屏幕显色不对的问题。几经折腾才发现原因,得到可行的方案,特此记录。

引脚配置

LCD_BL控制背光,高电平有效,低电平黑屏。

SPI配置

半双工模式:收发一条数据线,匹配屏幕的半双工接口

硬件控制CS,当然也可以自己软件控制,看个人喜好

波特率不超过60M,为了刷屏快,尽可能高

数据位8或16均可,原因后面讲(大坑)

DMA数据按16位。即half word

驱动文件

st7789.c

#include "st7789.h"
#include "spi.h"

// ST7789命令定义
#define ST7789_NOP     0x00
#define ST7789_SWRESET 0x01
#define ST7789_SLPIN   0x10
#define ST7789_SLPOUT  0x11
#define ST7789_INVOFF  0x20
#define ST7789_INVON   0x21
#define ST7789_DISPOFF 0x28
#define ST7789_DISPON  0x29
#define ST7789_CASET   0x2A
#define ST7789_RASET   0x2B
#define ST7789_RAMWR   0x2C
#define ST7789_MADCTL  0x36

// MADCTL参数
#define ST7789_MADCTL_MY  0x80
#define ST7789_MADCTL_MX  0x40
#define ST7789_MADCTL_MV  0x20
#define ST7789_MADCTL_ML  0x10
#define ST7789_MADCTL_MH  0x04
#define ST7789_MADCTL_RGB 0x00
#define ST7789_MADCTL_BGR 0x08

#define ST7789_SPI_INSTANCE  hspi1
   
#define SPI_DC_LOW()        HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_RESET)
#define SPI_DC_HIGH()       HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET)
#define SPI_RST_LOW()       HAL_GPIO_WritePin(LCD_RES_GPIO_Port, LCD_RES_Pin, GPIO_PIN_RESET);
#define SPI_RST_HIGH()      HAL_GPIO_WritePin(LCD_RES_GPIO_Port, LCD_RES_Pin, GPIO_PIN_SET);
//#define SPI_WriteByte(cmd)  HAL_SPI_Transmit(&ST7789_SPI_INSTANCE, &cmd, 1, HAL_MAX_DELAY)
#define SPI_WriteByte(cmd)  HAL_SPI_Transmit_DMA(&ST7789_SPI_INSTANCE, &cmd, 1)

// 设置SPI数据大小为8位
void SPI_SetDataSize_8bit(SPI_HandleTypeDef *hspi) {
    hspi->Init.DataSize = SPI_DATASIZE_8BIT;
    if (HAL_SPI_Init(hspi) != HAL_OK) {
     
### STM32ST7789显示使用LVGL图形库 #### 配置开发环境 为了在STM32上运行带有ST7789显示的LVGL图形界面,需先配置好开发环境。这包括安装必要的IDE(如Keil MDK或STM32CubeIDE),并下载对应的固件包以及LVGL库文件[^1]。 #### 初始化硬件连接 确保STM32微控制器已正确连接至ST7789幕,并通过SPI接口完成初始化设置。具体来说,应按照数据手册中的指导来设定GPIO引脚的功能分配,使能外设时钟,并调用相应的API函数实现低层驱动程序的加载[^2]。 #### 编写主应用程序逻辑 下面是一个简单的C语言代码片段用于展示如何启动LVGL引擎并与ST7789交互: ```c #include "lvgl/lvgl.h" #include "stm32f4xx_hal.h" // 假定已经定义好了spi_handle, lcd_cs_pin等变量 void lv_port_disp_init(void){ /* Display buffer */ static lv_color_t buf[DISP_BUF_SIZE]; /* Initialize your display and the required peripherals here */ // 设置显示器刷新回调函数 disp_drv.disp_flush = my_disp_flush; // 注册显示设备到LVGL系统中 lv_disp_buf_init(&disp_buf,buf,NULL, DISP_BUF_SIZE); lv_disp_drv_register(&disp_drv); } int main(){ HAL_Init(); SystemClock_Config(); // 初始化HAL库和外部资源 MX_GPIO_Init(); MX_SPIx_Init(); // 开始LVGL任务调度器前准备 lv_init(); lv_port_disp_init(); while (true){ // 运行LVGL的任务处理循环 lv_task_handler(); HAL_Delay(5); } } ``` 此段代码展示了如何利用`lv_init()`方法初始化LVGL框架;接着通过自定义的`my_disp_flush()`函数向物理幕上绘制图像帧缓冲区的内容。最后,在无限循环内不断更新UI状态以保持流畅的操作体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值