2.4寸 TFT LCD 240*320屏幕点亮

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_块刷

相关推荐
染不尽的流年6 天前
LCD AMOLED TDDI MicroLED 技术差异 图解
lcd·测试机
染不尽的流年6 天前
AMOLED(有源矩阵有机发光二极管)全面解析
lcd·测试机
染不尽的流年6 天前
MiniLED与MicroLED技术差异深度解析
lcd·测试机
hwmxrhx2 个月前
解析DTS时序参数:1920×1200屏幕配置详解
lcd·dts
&拾玖3 个月前
常见屏幕驱动接口总结
lcd
张世争4 个月前
RT-Thread qemu LVGL9.5 显示驱动更新 lv_port_disp.c
lcd·qemu·rt-thread·lvgl9.5
林政硕(Cohen0415)1 年前
ARM Linux LCD上实时预览摄像头画面
lcd·uvc·arm linux
打酱油的工程师1 年前
w803|联盛德|WM IoT SDK2.X测试|window11|TOML 文件|外设|TFT_LCD|测试任务|(5):TFT_LCD_LVGL示例
单片机·物联网·lcd·tft·w80x
Android小码家1 年前
ESP32云开发二( http + led + lcd)
lcd·esp32·wokwi