LCD刷屏
LCD刷屏演示视频
最近翻出一块吃灰的LCD,
想来可以作为图传或热成像仪的屏幕。
在假期点亮一下;

工作流程评估:
1)阅读参考程序和手册,确认引脚配置
2)使用stm32f407vet6 硬件SPI点亮屏幕
3)封装画点函数
4)利用画点函数实现图片/文字/字符/数字的显示
5)SPI改为SPI+DMA优化刷新速度
6)封装完LCD的SPI_DMA和画点函数和单元测试
7)上自定义UI框架 或 LVGL
8)对接传感器(红外或摄像头)
一、阅读参考历程和手册确认引脚

这是商家提供的引脚配置图片;
可以确定要使用以下引脚中的部分
1)GND
2)VCC
3)CLK【SPI的时钟引脚】
4)MOSI【SPI数据脚,主机发送从机接收即MCU发送数据给屏幕驱动芯片的引脚】
5)RES【复位引脚】
6)DC【数据/命令切换引脚】
7)BLK【没用到,先不关注】
8)MISO(没用到,不关注)
9)CS1【片选端口】
10)CS2【没用到】
11)PEN【没用到】
简单地说,要配置7个引脚
1)GND
2)VCC
3)CLK【SPI的时钟引脚】
4)MOSI【SPI数据脚,主机发送从机接收即MCU发送数据给屏幕驱动芯片的引脚】
5)RES【复位引脚】
6)DC【数据/命令切换引脚】
9)CS1【片选端口】
二、按照习惯,分析点亮LCD的驱动芯片和待配置的各个引脚
按照以往的习惯,
无非是SPI发送数据给寄存器,
那么现在关注一下怎么配置寄存器。
AI时代了,这种事情肯定要交给AI处理。

这个名字听着很熟悉!
我之前使用ST7789V点亮过240*280的屏幕,
这个ST7735S应该差不多。
代码里的注释是ST7735S,但是商家提供的手册是
这让我很疑惑;
打开淘宝详情页

确认驱动IC为ILI9341。

看到代码中有大量的注释ST7735S,
但是详情页和手册描述的是ILI9341,
我的 分析是商家移植了驱动代码,从ST7735S移植了很多内容,但是没有删除注释;
不管这些破事了,分析bringup的方法;
CLK、MPSI是SPI的部分
DC、RST、CS1是干什么的?
| 引脚 | 功能 |
|---|---|
| DC | 数据/命令选择脚,0命令,1数据 |
| RST | 驱动芯片复位引脚,高->低->高实现复位 |
| CS1 | SPI的片选引脚 |



三、怎么配置寄存器实现初始化
卖家提供的初始化代码
c
void LCD_IC_Init()
{
WriteComm(0x11); //Sleep out
Delay(20); //Delay 120ms
//------------------------------------ST7735S Frame Rate----------------------//
WriteComm(0xB1);
WriteData(0x05);
WriteData(0x3A);
WriteData(0x3A);
WriteComm(0xB2);
WriteData(0x05);
WriteData(0x3A);
WriteData(0x3A);
WriteComm(0xB3);
WriteData(0x05);
WriteData(0x3A);
WriteData(0x3A);
WriteData(0x05);
WriteData(0x3A);
WriteData(0x3A);
//------------------------------------End ST7735S Frame Rate------------------//
WriteComm(0xB4); //Dot inversion
WriteData(0x03);
//------------------------------------ST7735S Power Sequence-----------------------//
WriteComm(0xC0);
WriteData(0x28);
WriteData(0x08);
WriteData(0x84);
WriteComm(0xC1);
WriteData(0XC0);
WriteComm(0xC2);
WriteData(0x0D);
WriteData(0x00);
WriteComm(0xC3);
WriteData(0x8D);
WriteData(0x2A);
WriteComm(0xC4);
WriteData(0x8D);
WriteData(0xEE);
//---------------------------------End ST7735S Power Sequence---------------------------//
WriteComm(0xC5); //VCOM
WriteData(0x0C);
WriteComm(0x36); //MX, MY, RGB mode
WriteData(0xC8);
//------------------------------ST7735S Gamma Sequence----------------------------------//
WriteComm(0xE0);
WriteData(0x05);
WriteData(0x1A);
WriteData(0x0C);
WriteData(0x0E);
WriteData(0x3A);
WriteData(0x34);
WriteData(0x2D);
WriteData(0x2F);
WriteData(0x2D);
WriteData(0x2A);
WriteData(0x2F);
WriteData(0x3C);
WriteData(0x00);
WriteData(0x01);
WriteData(0x02);
WriteData(0x10);
WriteComm(0xE1);
WriteData(0x04);
WriteData(0x1B);
WriteData(0x0D);
WriteData(0x0E);
WriteData(0x2D);
WriteData(0x29);
WriteData(0x24);
WriteData(0x29);
WriteData(0x28);
WriteData(0x26);
WriteData(0x31);
WriteData(0x3B);
WriteData(0x00);
WriteData(0x00);
WriteData(0x03);
WriteData(0x12);
//------------------------------------End ST7735S Gamma Sequence-----------------//
WriteComm(0xFC); //Enable Gate Pump Clock Frequency Variable
WriteData(0x8C);
WriteComm(0x3A); //65k mode
WriteData(0x05);
WriteComm(0x2a);
WriteData(0x00);
WriteData(0x00);
WriteData(0x00);
WriteData(0x7F);
WriteComm(0x2b);
WriteData(0x00);
WriteData(0x00);
WriteData(0x00);
WriteData(0x9F);
WriteComm(0x29); //Display on
}
用AI解读一下程序











四、画点函数、字符显示、数字显示的实现

卖家有点懒,
没提供所有接口,
常规的绘制字符和数字的接口,没提供;
这个店铺我记住了,避雷。
那么回忆一下,这块屏幕吃灰,可能是当时买的时候卖家没提供资料,自己也懒得折腾。

因此要自己设计。


五、根据已经掌握的资料实现在STM32F407VET6上移植LCD的驱动程序----(一)使用cubemx生成工程,配置SPI\GPIO\串口
1-cubemx生成SPI配置和其他IO配置
2-实现初始化函数
3-实现画点函数
4-依据画点函数让AI实现刷屏函数、线条绘制、矩形绘制、字符绘制、数字绘制、波形图绘制接口等
5-自定义多级菜单框架
再把DC、RST、NSS脚的GPIO配置一下
再开一路串口

生成代码


打开代码编译

六、根据已经掌握的资料实现在STM32F407VET6上移植LCD的驱动程序----(二)封装SPI发送接口、创建驱动程序文件、创建单元测试文件、实现LCD初始化和、画点函数、刷屏函数并测试
创建BSP文件夹

创建驱动文件



DEMO,用阻塞式接口调试。
c
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
我的习惯是:先调通,再优化;
对于本次LCD项目的实现流程:
1)阅读参考程序和手册,确认引脚配置
2)使用stm32f407vet6 硬件SPI点亮屏幕
3)封装画点函数
4)利用画点函数实现图片/文字/字符/数字的显示
5)SPI改为SPI+DMA优化刷新速度
6)封装完LCD的SPI_DMA和画点函数和单元测试
7)上自定义UI框架 或 LVGL
8)对接传感器(红外或摄像头)
封装SPI接口

其实可以通过回调来封装,后面再说。
CS、DC、RST的封装

写指令和写数据的封装

移植LCD_IC_Init

实现LCD复位函数

实现刷屏函数

实现单元测试接口

main函数调用

七、全部代码
1-ILI9341_drv.h
c
#ifndef _ILI9341_DRV_H
#define _ILI9341_DRV_H
#include "gpio.h"
#define LCD_CS_GPIO GPIOC
#define LCD_CS_PIN GPIO_PIN_6
#define LCD_RS_GPIO GPIOC
#define LCD_RS_PIN GPIO_PIN_7
#define LCD_RST_GPIO GPIOC
#define LCD_RST_PIN GPIO_PIN_8
// 宏替换,保持兼容(可选,不改调用代码的话留着)
#define LCD_CS_SET HAL_GPIO_WritePin(LCD_CS_GPIO, LCD_CS_PIN, GPIO_PIN_SET)
#define LCD_CS_CLR HAL_GPIO_WritePin(LCD_CS_GPIO, LCD_CS_PIN, GPIO_PIN_RESET)
#define LCD_RS_SET HAL_GPIO_WritePin(LCD_RS_GPIO, LCD_RS_PIN, GPIO_PIN_SET)
#define LCD_RS_CLR HAL_GPIO_WritePin(LCD_RS_GPIO, LCD_RS_PIN, GPIO_PIN_RESET)
#define LCD_RST_SET HAL_GPIO_WritePin(LCD_RST_GPIO, LCD_RST_PIN, GPIO_PIN_SET)
#define LCD_RST_CLR HAL_GPIO_WritePin(LCD_RST_GPIO, LCD_RST_PIN, GPIO_PIN_RESET)
void LCD_RESET(void);//驱动芯片复位
void LCD_IC_Init();
void Display_test(void);
#endif
2-ILI9341_drv.c
c
#include "ILI9341_drv.h"
#include "stdint.h"
#include "spi.h"
//LCD_240_320/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c
//HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
#define SPI_TIMEOUT 10000
void mcu_send_spi_data_to_ILI9341(uint8_t *pbuffer,uint16_t len)
{
HAL_SPI_Transmit(&hspi1, (uint8_t *)pbuffer, len, SPI_TIMEOUT);
}
// void WriteData(u16 data)
// {
// LCD_CS_CLR;
// LCD_RD_SET;
// LCD_RS_SET;
// SendDataSPI(data);
// LCD_CS_SET;
// }
// void WriteComm(u16 data)
// {
// LCD_CS_CLR;
// LCD_RS_CLR;
// SendDataSPI(data);
// LCD_CS_SET;
// }
// ===== 发送指令(RS=0)=====
//注意:对于片选信号CS,开始发送SPI数据前要拉低,SPI发送完成后要拉高
//对于RS(DC脚),它是用来选择数据/命令的;0:发送命令,1发送数据
//对于RST引脚:它是驱动芯片的复位引脚,上电后 高->低->高 实现复位
void WriteComm(uint8_t cmd)
{
HAL_GPIO_WritePin(LCD_CS_GPIO, LCD_CS_PIN, GPIO_PIN_RESET); // CS=0
HAL_GPIO_WritePin(LCD_RS_GPIO, LCD_RS_PIN, GPIO_PIN_RESET); // RS=0 命令
HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY); // 发1字节
HAL_GPIO_WritePin(LCD_CS_GPIO, LCD_CS_PIN, GPIO_PIN_SET); // CS=1
}
// ===== 发送参数(RS=1)=====
void WriteData(uint8_t data)
{
HAL_GPIO_WritePin(LCD_CS_GPIO, LCD_CS_PIN, GPIO_PIN_RESET); // CS=0
HAL_GPIO_WritePin(LCD_RS_GPIO, LCD_RS_PIN, GPIO_PIN_SET); // RS=1 数据
HAL_SPI_Transmit(&hspi1, &data, 1, HAL_MAX_DELAY); // 发1字节
HAL_GPIO_WritePin(LCD_CS_GPIO, LCD_CS_PIN, GPIO_PIN_SET); // CS=1
}
void LCD_RESET(void)
{
LCD_RST_SET;
HAL_Delay(50);
LCD_RST_CLR;
//delay_ms(5);
HAL_Delay(100);
LCD_RST_SET;
HAL_Delay(50);
}
void LCD_IC_Init()
{
WriteComm(0x11); //Sleep out
HAL_Delay(20); //Delay 120ms
//------------------------------------ST7735S Frame Rate----------------------//
WriteComm(0xB1);
WriteData(0x05);
WriteData(0x3A);
WriteData(0x3A);
WriteComm(0xB2);
WriteData(0x05);
WriteData(0x3A);
WriteData(0x3A);
WriteComm(0xB3);
WriteData(0x05);
WriteData(0x3A);
WriteData(0x3A);
WriteData(0x05);
WriteData(0x3A);
WriteData(0x3A);
//------------------------------------End ST7735S Frame Rate------------------//
WriteComm(0xB4); //Dot inversion
WriteData(0x03);
//------------------------------------ST7735S Power Sequence-----------------------//
WriteComm(0xC0);
WriteData(0x28);
WriteData(0x08);
WriteData(0x84);
WriteComm(0xC1);
WriteData(0XC0);
WriteComm(0xC2);
WriteData(0x0D);
WriteData(0x00);
WriteComm(0xC3);
WriteData(0x8D);
WriteData(0x2A);
WriteComm(0xC4);
WriteData(0x8D);
WriteData(0xEE);
//---------------------------------End ST7735S Power Sequence---------------------------//
WriteComm(0xC5); //VCOM
WriteData(0x0C);
WriteComm(0x36); //MX, MY, RGB mode
WriteData(0xC8);
//------------------------------ST7735S Gamma Sequence----------------------------------//
WriteComm(0xE0);
WriteData(0x05);
WriteData(0x1A);
WriteData(0x0C);
WriteData(0x0E);
WriteData(0x3A);
WriteData(0x34);
WriteData(0x2D);
WriteData(0x2F);
WriteData(0x2D);
WriteData(0x2A);
WriteData(0x2F);
WriteData(0x3C);
WriteData(0x00);
WriteData(0x01);
WriteData(0x02);
WriteData(0x10);
WriteComm(0xE1);
WriteData(0x04);
WriteData(0x1B);
WriteData(0x0D);
WriteData(0x0E);
WriteData(0x2D);
WriteData(0x29);
WriteData(0x24);
WriteData(0x29);
WriteData(0x28);
WriteData(0x26);
WriteData(0x31);
WriteData(0x3B);
WriteData(0x00);
WriteData(0x00);
WriteData(0x03);
WriteData(0x12);
//------------------------------------End ST7735S Gamma Sequence-----------------//
WriteComm(0xFC); //Enable Gate Pump Clock Frequency Variable
WriteData(0x8C);
WriteComm(0x3A); //65k mode
WriteData(0x05);
WriteComm(0x2a);
WriteData(0x00);
WriteData(0x00);
WriteData(0x00);
WriteData(0x7F);
WriteComm(0x2b);
WriteData(0x00);
WriteData(0x00);
WriteData(0x00);
WriteData(0x9F);
WriteComm(0x29); //Display on
}
void LCD_Fill(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
uint32_t i; // ← 改成 uint32_t
uint32_t total;
uint8_t buf[2] = {color >> 8, color & 0xFF};
// 设置窗口
WriteComm(0x2A);
WriteData(x1 >> 8);
WriteData(x1);
WriteData(x2 >> 8);
WriteData(x2);
WriteComm(0x2B);
WriteData(y1 >> 8);
WriteData(y1);
WriteData(y2 >> 8);
WriteData(y2);
WriteComm(0x2C); // 开始写像素
total = (uint32_t)(x2 - x1 + 1) * (y2 - y1 + 1);
HAL_GPIO_WritePin(LCD_CS_GPIO, LCD_CS_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_RS_GPIO, LCD_RS_PIN, GPIO_PIN_SET);
for (i = 0; i < total; i++)
HAL_SPI_Transmit(&hspi1, buf, 2, HAL_MAX_DELAY); // ← 也改成 HAL_MAX_DELAY
HAL_GPIO_WritePin(LCD_CS_GPIO, LCD_CS_PIN, GPIO_PIN_SET);
}
// 全屏填色快捷函数
#define LCD_RED 0xF800
#define LCD_GREEN 0x07E0
#define LCD_BLUE 0x001F
#define LCD_WHITE 0xFFFF
#define LCD_BLACK 0x0000
void DispColor(uint16_t color)
{
// ST7735S: 128x160
// LCD_Fill(0, 0, 127, 159, color);
// 如果是 ILI9341: 240x320,改成:
LCD_Fill(0, 0, 239, 319, color);
}
#include "RTT_Debug.h"
void Display_test(void)
{
DBG_log("1");
DispColor(LCD_RED);
HAL_Delay(500);
DBG_log("2");
DispColor(LCD_GREEN);
HAL_Delay(500);
DBG_log("3");
DispColor(LCD_BLUE);
HAL_Delay(500);
DBG_log("4");
DispColor(LCD_WHITE);
HAL_Delay(500);
}
main.c
c
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_SPI1_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
LCD_RESET();
LCD_IC_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
Display_test();
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
spi.c
c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file spi.c
* @brief This file provides code for the configuration
* of the SPI instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "spi.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
SPI_HandleTypeDef hspi1;
/* SPI1 init function */
void MX_SPI1_Init(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
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_16;
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();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* SPI1 clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
}
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
{
if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspDeInit 0 */
/* USER CODE END SPI1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI1_CLK_DISABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
/* USER CODE BEGIN SPI1_MspDeInit 1 */
/* USER CODE END SPI1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
-------------------------------、
八、画点函数和刷屏
测试完毕,开始考虑实现画点函数,
并利用画点函数实现刷屏


c
//画点函数
void LCD_DrawPoint(uint16_t x, uint16_t y, uint16_t color)
{
// 设置窗口到单个像素
WriteComm(0x2A);
WriteData(x >> 8);
WriteData(x);
WriteData(x >> 8);
WriteData(x);
WriteComm(0x2B);
WriteData(y >> 8);
WriteData(y);
WriteData(y >> 8);
WriteData(y);
WriteComm(0x2C);
// 写入颜色
uint8_t buf[2] = {color >> 8, color & 0xFF};
HAL_GPIO_WritePin(LCD_CS_GPIO, LCD_CS_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LCD_RS_GPIO, LCD_RS_PIN, GPIO_PIN_SET);
HAL_SPI_Transmit(&hspi1, buf, 2, HAL_MAX_DELAY);
HAL_GPIO_WritePin(LCD_CS_GPIO, LCD_CS_PIN, GPIO_PIN_SET);
}
void DrawPoint_Fill(uint16_t color)
{
uint32_t x, y;
for (y = 0; y < 320; y++)
for (x = 0; x < 240; x++)
LCD_DrawPoint(x, y, color);
}
void Display_by_drawpoint(void)
{
DrawPoint_Fill(LCD_RED);
HAL_Delay(500);
DrawPoint_Fill(LCD_GREEN);
HAL_Delay(500);
DrawPoint_Fill(LCD_BLUE);
HAL_Delay(500);
}
九、为什么强调画点函数?
1-画点函数是刷屏的基石
2-可以调用画点函数实现字符、数字、图像接口的封装
3-移植LVGL时,LVGL底层调用的只有画点函数
因此其他的花里胡哨的可以不处理,但是画点函数必须做出来
十、基于画点函数实现字符显示
ILI9341.c里增加
c
// ==================== 字符显示 ====================
// 显示单个字符(5x8点阵)
// x,y: 起始坐标 fc: 前景色 bc: 背景色
void LCD_ShowChar(uint16_t x, uint16_t y, char ch, uint16_t fc, uint16_t bc)
{
uint8_t i, j;
uint8_t col_data;
const uint8_t *font;
if (ch < ' ' || ch > '~') return;
font = Font5x8[ch - ' '];
for (i = 0; i < 5; i++)
{
col_data = font[i];
for (j = 0; j < 8; j++)
{
if (col_data & (1 << j))
LCD_DrawPoint(x + i, y + j, fc);
else
LCD_DrawPoint(x + i, y + j, bc);
}
}
}
// 显示字符串(自动换行)
// x,y: 起始坐标 str: 字符串 fc: 前景色 bc: 背景色
void LCD_ShowString(uint16_t x, uint16_t y, const char *str, uint16_t fc, uint16_t bc)
{
uint16_t cur_x = x;
uint16_t cur_y = y;
while (*str)
{
if (*str == '\n')
{
cur_x = 0;
cur_y += 10;
}
else
{
LCD_ShowChar(cur_x, cur_y, *str, fc, bc);
cur_x += 6;
if (cur_x + 5 > 240) // 超出屏幕宽度,自动换行
{
cur_x = 0;
cur_y += 10;
}
}
str++;
}
}
// ==================== 数字显示 ====================
// 显示整数(右对齐)
// x,y: 起始坐标 num: 数值 len: 位数 fc: 前景色 bc: 背景色
void LCD_ShowNum(uint16_t x, uint16_t y, int32_t num, uint8_t len, uint16_t fc, uint16_t bc)
{
char buf[16];
if (len > 15) len = 15;
snprintf(buf, sizeof(buf), "%*ld", len, num);
LCD_ShowString(x, y, buf, fc, bc);
}
void INIT_LCD_UI(){
LCD_RESET();
LCD_IC_Init();
HAL_Delay(100);
DispColor(LCD_BLACK);
LCD_ShowString(10, 10, "hello world", LCD_WHITE, LCD_BLACK);
LCD_ShowNum(10, 30, 2026, 4, LCD_GREEN, LCD_BLACK);
}
这个改一下

十一、基本调通之后,考虑提速,改SPI+DMA刷屏,点刷改为块刷,
就可以把刷新速度提高了。
DMA_块刷










