针对STM32U575使用FMC驱动8位8080接口LCD的TouchGFX配置问题,以下是完整的解决方案:
// FMC配置为16位模式(实际硬件使用DB[15:8]或DB[7:0],悬空高位)
FMC_NORSRAM_TimingTypeDef Timing = {
.AddressSetupTime = 2,
.AddressHoldTime = 1,
.DataSetupTime = 5, // 根据LCD时序调整
.DataLatency = 0,
.BusTurnAroundDuration = 0
};
FMC_NORSRAM_InitTypeDef Init = {
.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE,
.MemoryType = FMC_MEMORY_TYPE_SRAM,
.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16, // 强制设为16位
.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE
};// 在FMC写操作函数中添加位掩码
void LCD_WriteData(uint8_t data) {
*((__IO uint16_t*)LCD_DATA_ADDR) = (0xFF00 | data); // DB[15:8]传输
// 或 *((__IO uint16_t*)LCD_DATA_ADDR) = (data << 8); // DB[15:8]传输
}修改CubeMX的TouchGFX设置:
// MX_TouchGFX_Init() 中更改帧缓冲格式
hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565; // 实际输出需转换创建自定义帧缓冲器(custom_framebuffer.cpp):
extern "C" {
#include "lcd_fmc_driver.h" // 包含你的硬件驱动
}
void TouchGFXHAL::configureInterfaces() {
// 重定向帧缓冲到自定义8位缓冲区
hal.setFrameBufferStartAddress((uint8_t*)customFrameBuffer,
LCD_WIDTH * LCD_HEIGHT,
BitDepth::BPP8);
}
// 实现像素格式转换
__weak void DMA2D_CopyBuffer(void* pSrc, void* pDst) {
uint8_t* src = (uint8_t*)pSrc;
uint8_t* dst = (uint8_t*)pDst;
for (uint32_t i = 0; i < BUFFER_SIZE; i++) {
dst[i] = convertRGB565toRGB332(*(uint16_t*)(&src[i*2]));
}
}// stm32u5xx_hal_ltdc.c 中修改
HAL_StatusTypeDef HAL_LTDC_Init(LTDC_HandleTypeDef *hltdc) {
// ...原有代码
hdma2d.Init.Mode = DMA2D_R2M; // 寄存器到内存
hdma2d.Init.OutputOffset = 0;
hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565;
hdma2d.LayerCfg[0].InputOffset = 0;
hdma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565;
HAL_DMA2D_Init(&hdma2d); // 显式初始化
}// 在 touchgfx/hal/HAL.cpp 添加重载
void HAL::setFrameBuffer(uint16_t* adr) {
uint8_t* converted = convertFrameBufferFormat(adr);
LTDC_Layer1->CFBAR = (uint32_t)converted; // 指向转换后缓冲
__HAL_LTDC_RELOAD_CONFIG(&hltdc);
}RGB565→RGB332转换算法:
static inline uint8_t convertRGB565toRGB332(uint16_t rgb565) {
return ((rgb565 & 0xE000) >> 8) | // R: 5bit→3bit
((rgb565 & 0x0700) >> 6) | // G: 6bit→3bit (取高位)
((rgb565 & 0x0018) >> 3); // B: 5bit→2bit
}性能优化策略:
// 使用DMA2D实时转换(在V-SYNC中断中触发)
void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *hltdc) {
HAL_DMA2D_Start_IT(&hdma2d,
(uint32_t)srcFrameBuffer,
(uint32_t)customFrameBuffer,
LCD_WIDTH, LCD_HEIGHT/10); // 分段传输减少延迟
}颜色深度补偿技术:
touchgfx_dipalette.hpp:const uint16_t palette[] = {
0x0000, 0xF800, 0x07E0, ... // RGB565格式的332调色板
};FMC时序验证:
// 使用逻辑分析仪检查时序参数
while(1) {
*((__IO uint16_t*)0x60000000) = 0xAA55; // 发送测试模式
HAL_Delay(1);
}DMA2D状态监控:
if (HAL_DMA2D_GetState(&hdma2d) == HAL_DMA2D_STATE_READY) {
debug("DMA2D Ready");
}帧率显示调试:
// 在FrameBufferAllocator.cpp中
uint32_t last_tick = 0;
void HAL::vSync() {
uint32_t now = HAL_GetTick();
debug("FPS: %d", 1000/(now - last_tick));
last_tick = now;
}最终解决方案需结合:
建议先使用STM32CubeIDE的FMC调试工具验证物理层通信,再逐步整合TouchGFX组件。实际项目中还需考虑增加双缓冲机制来弥补8位传输的性能损失。
举报
更多回帖