STM32系列-CubeIDE、CubeMX配置LTDC、DMA2D教程(图文快速上手)
文章目录
一,基本配置
1,芯片型号选择
2,自定义项目名称
3,时钟配置
二,LTDC配置
1,LCD、LTDC引脚配置
2,LTDC参数配置
这是我使用的LCD显示屏的参数,来源于其数据手册,需要根据这些参数来配置LTDC的参数。
2.1 LTDC时钟配置
2.2 LTDC背景层参数配置
下图中480为屏幕宽度像素,272为屏幕高度像素。
此时,在不进行进步一设置的情况下,如果生成代码并烧录,可以发现屏幕已经变绿了(如下图所示),这说明LTDC的背景层已经设置成功。如果屏幕没有显示你设置的颜色,可能你需要:1)检查你的GPIO引脚配置是否和电路原理图保持一致;2)GPIO引脚速度是否被配置成了“Very High”;3)LTDC的时钟是否在规定的范围内。
2.3 LTDC前景层参数配置
此时,在不进行进一步设置的情况下,如果生成代码并编译会报错如下:
因此,需要进行以下设置:
然后,再编译程序便不会报错,然后烧录程序。
会发现,屏幕全黑,并没有显示此前设置的默认蓝色。解释如下:
1,在设置背景层参数时设置了屏幕大小:宽高分辨率(480-272),这是硬件参数。当完成此步骤时,前景层的宽高分辨率也被自动设置为(480-272)。
2,在前景层中设置的Windows Position是屏幕中显示区域的大小,因此它需要指定水平和垂直方向上的起始像素和结束像素,这个区域大小是由此处的数值决定的(软件决定)。如果将Windows Position中的参数按以下参数配置:
Windows Position | |
---|---|
Window Horizontal Start | 50 |
Window Horizontal Stop | 430 |
Window Vertical Start | 30 |
Window Vertical Stop | 242 |
然后生成代码并烧录,就可以得到以下实验现象:
从上图中可知,前景层中显示区域为黑色,非显示区域则为我们设置的默认蓝色,这表面前景层配置成功。
2.4 测试
在ltdc.c中添加下方函数定义(来源于正点原子),并在ltdc.h中添加函数声明。
该函数用于在屏幕中以指定的颜色绘制一个点,请查看代码注释,并做适当修改。
// 将该函数添加到ltdc.c中,并在ltdc.h中声明
void LTDC_Draw_Point(uint16_t x,uint16_t y,uint32_t color)
{
*(uint16_t*)((uint32_t)LTDCFrameBuffer+2*(480*y+x))=color;
// 上方代码中:2为每个像素颜色值的大小,意为2字节,如果颜色格式大于RGB565,则为4字节,480为本文中使用的屏幕宽度像素值,
}
然后在main.c中while循环之前添加下列代码,
uint32_t RED=0xF800; // 定义红色
uint32_t WHITE=0xFFFF; // 定义白色
uint16_t x = 100, y=100; // 初始坐标
// 从点(x=100,y=100)画一条指向点(x=200,y=100)的红色直线(长度为100)
for (uint8_t i = 0;i<100;i++)
LTDC_Draw_Point(x+i,y,RED);
x = 350, y=100; // 初始坐标
// 从点(x=350,y=100)画一条指向点(x=450,y=100)的白色直线(长度为100)
for (uint8_t i = 0;i<100;i++)
LTDC_Draw_Point(x+i,y,WHITE);
添加之后的效果如下:
编译烧录,效果如下:
如图所示,红色线段完全显示,白色线段超出显示区域后不显示。
自此LTDC的基本配置完成,也让我们明白了前景层中Windows Position的参数的影响效果,就是划定屏幕中显示区域。
然后将前景层中Windows Position配置改回2.3小节第一张图所示即可。
三、DMA2D配置
按上述操作完成配置,并生成代码;
在ltdc.c中添加下方两个函数,并在ltdc.h中添加函数声明,两个函数均来源于正点原子;请查看代码注释,并做适当修改;
void LTDC_Fill(uint16_t sx,uint16_t sy,uint16_t ex,uint16_t ey,uint32_t color)
{
uint32_t psx,psy,pex,pey; //锟???? LCD 闈㈡澘涓哄熀鍑嗙殑鍧愭爣锟????,涓嶉殢妯珫灞忓彉鍖栵拷?锟藉彉锟????
uint32_t timeout=0;
uint16_t offline;
uint32_t addr;
// 按屏幕使用方式对坐标进行变换
if(1)// 横屏
{
psx=sx;psy=sy;
pex=ex;pey=ey;
}else // 竖屏
{
psx=sy;psy=272-ex-1; // 272为屏幕高度像素
pex=ey;pey=272-sx-1;
}
offline=480-(pex-psx+1); // 480为屏幕宽度像素
addr=((uint32_t)LTDCFrameBuffer+2*(480*psy+psx)); // 2为像素字节大小,480为屏幕宽度像素
DMA2D->CR&=~(DMA2D_CR_START); //停止DMA2D
DMA2D->CR=DMA2D_R2M; //DMA2D配置为寄存器到内存
DMA2D->OOR=offline; //行偏移
DMA2D->OMAR=addr; //颜色输出地址
DMA2D->NLR=(pey-psy+1)|((pex-psx+1)<<16); //设定行数寄存器
DMA2D->OCOLR=color; //颜色输入地址
DMA2D->CR|=DMA2D_CR_START; //启动 DMA2D
while((DMA2D->ISR&(DMA2D_FLAG_TC))==0) //等待传输完成
{
timeout++;
if(timeout>0X1FFFFF)break;//超时退出
}
DMA2D->IFCR|=DMA2D_FLAG_TC;//清除传输完成标志
}
void LTDC_Color_Fill(uint16_t sx,uint16_t sy,uint16_t ex,uint16_t ey,uint16_t* color)
{
uint32_t psx,psy,pex,pey;
uint32_t timeout=0;
uint16_t offline;
uint32_t addr;
// 按屏幕使用方式对坐标进行变换
if(1) // 横屏
{
psx=sx;psy=sy;
pex=ex;pey=ey;
}else // 竖屏
{
psx=sy;psy=272-ex-1; // 272为屏幕高度像素
pex=ey;pey=272-sx-1;
}
offline=480-(pex-psx+1);// 480为屏幕宽度像素
addr=((uint32_t)LTDCFrameBuffer+2*(480*psy+psx)); // 2为像素字节大小,480为屏幕宽度像素
DMA2D->CR&=~(DMA2D_CR_START); //停止DMA2D
DMA2D->CR=DMA2D_M2M; //DMA2D配置为内存到内存
DMA2D->FGMAR=(uint32_t)color; // 需要传输的颜色数据地址
DMA2D->OMAR=addr; //输出存储器地址
DMA2D->FGOR=0; // 前景层偏移
DMA2D->OOR=offline; //行偏移
DMA2D->NLR=(pey-psy+1)|((pex-psx+1)<<16); //设定行数寄存器
DMA2D->CR|=DMA2D_CR_START; //启动 DMA2D
while((DMA2D->ISR&(DMA2D_FLAG_TC))==0) //等待传输完成
{
timeout++;
if(timeout>0X1FFFFF)break;//超时退出
}
DMA2D->IFCR|=DMA2D_FLAG_TC;//清除传输完成标志
}
在main.c函数中while循环之前调用函数如下:LTDC_Fill(50,50,100,100,GREEN);该函数用于在指定区域内填充一种颜色,可用于清屏。效果如下:
LTDC_Color_Fill()函数用于在指定区域内填充一段不同的颜色数据,比如由图像生成的数组。
测试方法如下:
使用Img2Lcd软件左上角导入一张480*272分辨率的自然人文图片,然后按照自己的格式,点击左上角保存导出为img.h文件,里面就是一个数组。
将该头文件复制进stm32cubeide中的“Core/Inc”目录下,并在main.c中引用,在while循环之前添加代码:
LTDC_Color_Fill(0,0,479,271,(uint16_t*)gImage_img);
// gImage_img是img.h中的数组名字
编译烧录,由于h750vbt6的flash只有128kb,因此编译报错提示flash不够用,但实际上h7系列有2M的flash,因此只需要将下图所示的文件中将flash信息改为2M后便能够成功编译。
但不能使用cubeide烧录,可以使用STM32 ST-LINK Utility软甲对编译生成的.bin或.hex文件进行烧录。cubeide默认不生成这两个文件,需要在配置“Project-Properties-C/C++build-Setting-MCU Post build outputs”中勾选第一个和第二个。最终效果如下:
至此,结束。