改SPI DMA数据宽度;LCD中加入color翻转

This commit is contained in:
不吃油炸鸡
2026-03-15 22:31:09 +08:00
parent b5e005a7a0
commit ce9093cf8c
3 changed files with 25 additions and 23 deletions

View File

@@ -25,6 +25,18 @@ void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
} }
} }
#include "stm32f4xx_hal.h" // 确保引入了HAL库里面包含了 __REV16 指令
// 极速翻转显存缓冲区
// px_cnt: 像素总数 (比如 240 * 20 = 4800)
static void swap_rgb565_buffer_fast(uint16_t * buf, uint32_t px_cnt)
{
for(uint32_t i = 0; i < px_cnt; i++) {
// 安全翻转高低字节
buf[i] = (buf[i] >> 8) | (buf[i] << 8);
}
}
/****************************************************************************** /******************************************************************************
函数说明:在指定区域填充颜色 函数说明:在指定区域填充颜色
入口数据xsta,ysta 起始坐标 入口数据xsta,ysta 起始坐标
@@ -34,17 +46,15 @@ void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
******************************************************************************/ ******************************************************************************/
void LCD_Color_Render_Async(u16 xsta, u16 ysta, u16 xend, u16 yend, u16 *color_p) void LCD_Color_Render_Async(u16 xsta, u16 ysta, u16 xend, u16 yend, u16 *color_p)
{ {
// 1. 设置地址 (命令是 8 位的,此时 SPI 必须是 8 位模式) // 设置地址
LCD_Address_Set(xsta, ysta, xend, yend); LCD_Address_Set(xsta, ysta, xend, yend);
// 计算总数据量 // 计算像素总数
uint32_t count = (xend - xsta + 1) * (yend - ysta + 1); uint32_t pixel_count = (xend - xsta + 1) * (yend - ysta + 1);
// 2. 安全切换到 16-bit 模式 // 发送给 DMA 前,利用 CPU 极速翻转内存数组的高低字节!
// 必须先关 SPI改寄存器再开 SPI swap_rgb565_buffer_fast(color_p, pixel_count);
__HAL_SPI_DISABLE(&hspi2); // 启动 DMA 传输
hspi2.Instance->CR1 |= SPI_CR1_DFF; // 置位 DFF启用 16 位数据帧 // 注意:因为现在是纯 8-bit 发送1 个像素(16位)要发 2 个字节,所以 count = pixel_count * 2
__HAL_SPI_ENABLE(&hspi2); HAL_SPI_Transmit_DMA(&hspi2, (uint8_t*)color_p, pixel_count * 2);
// 3. 启动 DMA 传输
HAL_SPI_Transmit_DMA(&hspi2, (uint8_t*)color_p, count);
} }
static void *lcd_ready_cb = NULL; static void *lcd_ready_cb = NULL;
@@ -61,15 +71,7 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{ {
if (hspi->Instance == SPI2) if (hspi->Instance == SPI2)
{ {
// 1. 死等 SPI 总线发完最后 1 bit // 通知 LVGL 渲染结束,执行回调函数
while (hspi->Instance->SR & SPI_FLAG_BSY);
// 2. 安全切回 8-bit 模式 (为下一次发送命令做准备)
__HAL_SPI_DISABLE(hspi);
hspi->Instance->CR1 &= ~SPI_CR1_DFF; // 清除 DFF回退到 8 位
__HAL_SPI_ENABLE(hspi);
// 3. 通知 LVGL 渲染结束,执行回调函数
if (lcd_ready_cb) { if (lcd_ready_cb) {
LCD_CallbackFunc_t func = (LCD_CallbackFunc_t)lcd_ready_cb; LCD_CallbackFunc_t func = (LCD_CallbackFunc_t)lcd_ready_cb;
func(); func();

View File

@@ -91,8 +91,8 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi2_tx.Init.Mode = DMA_NORMAL; hdma_spi2_tx.Init.Mode = DMA_NORMAL;
hdma_spi2_tx.Init.Priority = DMA_PRIORITY_LOW; hdma_spi2_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_spi2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; hdma_spi2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

View File

@@ -39,10 +39,10 @@ Dma.RequestsNb=2
Dma.SPI2_TX.0.Direction=DMA_MEMORY_TO_PERIPH Dma.SPI2_TX.0.Direction=DMA_MEMORY_TO_PERIPH
Dma.SPI2_TX.0.FIFOMode=DMA_FIFOMODE_DISABLE Dma.SPI2_TX.0.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.SPI2_TX.0.Instance=DMA1_Stream4 Dma.SPI2_TX.0.Instance=DMA1_Stream4
Dma.SPI2_TX.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD Dma.SPI2_TX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.SPI2_TX.0.MemInc=DMA_MINC_ENABLE Dma.SPI2_TX.0.MemInc=DMA_MINC_ENABLE
Dma.SPI2_TX.0.Mode=DMA_NORMAL Dma.SPI2_TX.0.Mode=DMA_NORMAL
Dma.SPI2_TX.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD Dma.SPI2_TX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.SPI2_TX.0.PeriphInc=DMA_PINC_DISABLE Dma.SPI2_TX.0.PeriphInc=DMA_PINC_DISABLE
Dma.SPI2_TX.0.Priority=DMA_PRIORITY_LOW Dma.SPI2_TX.0.Priority=DMA_PRIORITY_LOW
Dma.SPI2_TX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode Dma.SPI2_TX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode