STM32系列-CubeIDE、CubeMX配置LTDC、DMA2D教程(图文快速上手)

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 Start50
Window Horizontal Stop430
Window Vertical Start30
Window Vertical Stop242

然后生成代码并烧录,就可以得到以下实验现象:
在这里插入图片描述
从上图中可知,前景层中显示区域为黑色,非显示区域则为我们设置的默认蓝色,这表面前景层配置成功。

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”中勾选第一个和第二个。最终效果如下:
在这里插入图片描述
至此,结束。

  • 44
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值