LCD-TFT控制总结

最近学到LCD了,但是在将野火的代码转移到CubeMX时却遇到了大麻烦,屏幕一直是花的,只有一次正常显示一下下,但是过一段时间就又没了,好几天的时间都找不到问题。

说说如何找到问题的

找到问题的方法是我昨天才想到的,前些天就像无头苍蝇一样到处乱窜,花了很多时间,但是没有用对方法,都是无用功。

后来想到,LCD使用SDRAM最为显存,那么只需要读取SDRAM中的数据就知道为什么显示会有问题了。

通过访问SDRAM中的显存的地址,就可以直接得到SDRAM中的数据。

首先测试清屏函数,读取SDRAM中的数据在清屏前和清屏后的数据有什么不同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
printf("%s\n","-----D000 after clear-----");
uint32_t i;
uint8_t ubReaddata_8b=0;
for (i=0; i<200; i++) {
ubReaddata_8b = *(__IO uint8_t*)(0xD0000000 + i);
printf("%x ",ubReaddata_8b);
}
printf("\n%s\n","-----D000 after clear-----");
printf("%s\n","-----D020 after clear-----");
for (i=0; i<200; i++) {
ubReaddata_8b = *(__IO uint8_t*)(0xD0200000 + i);
printf("%x ",ubReaddata_8b);
}
printf("\n%s\n","-----D020 after clear-----");

发现清屏前后数据没有变化,都是一些随机的数据,因此可以推断清屏函数出了问题。

再看看清屏函数(LCD_Clear),调用了另外一个函数,可以推断应该是LL_FillBuffer这个函数出了问题。

1
static void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex)

之前使用的DMA2D的R2M模式,我使用M2M模式显示图片发现正常,方法参照微雪课堂,再次确认LL_FillBuffer这个函数出了问题。

看看LL_FillBuffer这个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
static void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex) 
{
Dma2d_Handler.Init.Mode = DMA2D_R2M;
if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565)
{
Dma2d_Handler.Init.ColorMode = DMA2D_RGB565;
}
else if(Ltdc_Handler.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
...

/* DMA2D 初始化 */
if(HAL_DMA2D_Init(&Dma2d_Handler) == HAL_OK)
{
if(HAL_DMA2D_ConfigLayer(&Dma2d_Handler, LayerIndex) == HAL_OK)
{
if (HAL_DMA2D_Start(&Dma2d_Handler, ColorIndex, (uint32_t)pDst, xSize, ySize) == HAL_OK)
{
/* DMA轮询传输 */
HAL_DMA2D_PollForTransfer(&Dma2d_Handler, 100);
}
}
}
}

它这里操作的是Dma2d_Handler这个结构体,但是我用CubeMX生成代码使用的是hdma2d这个结构体,再我将Dma2d_Handler替换为hdma2d后,程序运行正常。

简单介绍一下LCD使用到的外设资源

LTDC

液晶面板的信号线如下

信号名称 说明
R[7:0] 红色数据
G[7:0] 绿色数据
B[7:0] 蓝色数据
CLK 像素同步时钟信号
HSYNC 水平同步信号
VSYNC 垂直同步信号
DE 数据使能信号

LTDC作为液晶控制器可以使用SDRAM中的部分空间作为显存,直接控制液晶面板。

我们需要做的就是参考液晶屏的资料,将液晶屏的像素、控制时序等对LTDC进行初始化,LTDC就会自动对液晶屏进行刷新控制。

DMA2D

DMA2D用于图像数据搬运、混合及格式转换

有四种模式:DMA2D_M2M、DMA2D_M2M_PFC、DMA2D_M2M_BLEND、DMA2D_R2M

暂时只用过M2M和R2M,觉得M2M最好用了,将图片转为数组,开启存储器到存储器的DMA,通过HAL_DMA2D_Start_IT传输就好了。

FMC

FMC用于操作SDRAM,通过不断刷新SDRAM保证数据的正确性


代码已上传github