stm32 DMA2D使用中断LVGL,提高LVGL帧率

我看了很多DMA2D教程都是用阻塞方式来刷新屏, 这样就消耗了性能 相当于没用DMA, 所以我使用DMA2D中断来传输数据

测试平台

stm32f429 + 正点原子7寸1024x600液晶屏 45MHZ刷新率 + LVGL

公有条件:

LTDC刷新率45MHZ, 开启SDRAM 突发传输, LVGL 2个全尺寸缓冲区

 

1 LVGL不使用DMA2D, 使用寄存器DMA2D传输

LVGL配置

#define LV_USE_GPU              1   /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */
#define LV_USE_GPU_STM32_DMA2D  0
/*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor
e.g. "stm32f769xx.h" or "stm32f429xx.h" */
#define LV_GPU_DMA2D_CMSIS_INCLUDE   "stm32f429xx.h"

LVGL port配置

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
	//LTDC_Color_Fill(area->x1,area->y1,area->x2,area->y2,(uint16_t*)(color_p));
   
	uint32_t h = area->y2 - area->y1;
	uint32_t w = area->x2 - area->x1;
	
	uint32_t OffLineSrc = 1024 - (area->x2 - area->x1 +1);
	uint32_t addr = LCD_FRAME_BUF_ADDR + 2*(1024*area->y1 + area->x1);
	
	
	// --- 阻塞传输---
	// 模式
	DMA2D->CR      = 0x00000000UL | (1 << 9);
	// 源地址
	DMA2D->FGMAR   = (uint32_t)(uint16_t*)(color_p);
	// 目标地址
	DMA2D->OMAR    = (uint32_t)addr;
	
	// 输入偏移
	DMA2D->FGOR    = 0;
	// 输出偏移
	DMA2D->OOR     = OffLineSrc;
	
	/* 前景层和输出区域都采用的RGB565颜色格式 */
	DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_RGB565;
	DMA2D->OPFCCR  = LTDC_PIXEL_FORMAT_RGB565;
	
		DMA2D->NLR     = (area->y2-area->y1+1) | ((area->x2 -area->x1 +1) << 16);

	/* 启动传输 */
	DMA2D->CR   |= DMA2D_CR_START;   

	/* 等待DMA2D传输完成 */
	while (DMA2D->CR & DMA2D_CR_START) {} 
		
  	lv_disp_flush_ready(disp_drv);
  }

跑benckmark大概是11fps

2  LVGL使用DMA2D, 使用寄存器DMA2D传输

#define LV_USE_GPU              0   /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */
#define LV_USE_GPU_STM32_DMA2D  1
/*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor
e.g. "stm32f769xx.h" or "stm32f429xx.h" */
#define LV_GPU_DMA2D_CMSIS_INCLUDE   "stm32f429xx.h"

加入宏定义STM32F4

3  LVGL不使用DMA2D, 使用寄存器DMA2D中断传输

 因为如果LVGL开启DMA2D之后, 会进入到DMA2D中断,所以要判断是LVGL内部中断,还是自己的刷图中断, 用volatile uint8_t g_gpu_state = 0; 这个来判断

#define LV_USE_GPU              1   /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */
#define LV_USE_GPU_STM32_DMA2D  0
/*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor
e.g. "stm32f769xx.h" or "stm32f429xx.h" */
#define LV_GPU_DMA2D_CMSIS_INCLUDE   "stm32f429xx.h"
volatile uint8_t g_gpu_state = 0;
// DMA2D传输完成回调
static void mDMA2Dcallvack(DMA2D_HandleTypeDef *hdma2d)
{
	 if(g_gpu_state==1){
		 g_gpu_state = 0;
		 lv_disp_flush_ready(&g_disp_drv);
	 }
}
// dma2D采用HAL初始化
static void dma2d_use_hal_init(void)
{

	hdma2d.Instance = DMA2D;
	hdma2d.XferCpltCallback = mDMA2Dcallvack;
  if (HAL_DMA2D_Init(&hdma2d) != HAL_OK)
  {

  }
}

/* Initialize your display and the required peripherals. */
static void disp_init(void)
{
	dma2d_use_reg_init();
}

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
	//LTDC_Color_Fill(area->x1,area->y1,area->x2,area->y2,(uint16_t*)(color_p));
   
	uint32_t h = area->y2 - area->y1;
	uint32_t w = area->x2 - area->x1;
	
	uint32_t OffLineSrc = 1024 - (area->x2 - area->x1 +1);
	uint32_t addr = LCD_FRAME_BUF_ADDR + 2*(1024*area->y1 + area->x1);
	// -- 中断传输
	// 模式
	DMA2D->CR      = 0x00000000UL | (1 << 9);
	// 源地址
	DMA2D->FGMAR   = (uint32_t)(uint16_t*)(color_p);
	// 目标地址
	DMA2D->OMAR    = (uint32_t)addr;
	
	// 输入偏移
	DMA2D->FGOR    = 0;
	// 输出偏移
	DMA2D->OOR     = OffLineSrc;
	
	/* 前景层和输出区域都采用的RGB565颜色格式 */
	DMA2D->FGPFCCR = DMA2D_OUTPUT_RGB565;
	DMA2D->OPFCCR  = DMA2D_OUTPUT_RGB565;
	
	// 多少行
		DMA2D->NLR     = (area->y2-area->y1+1) | ((area->x2 -area->x1 +1) << 16);

	// 开启中断
	DMA2D->CR |= DMA2D_IT_TC|DMA2D_IT_TE|DMA2D_IT_CE;
	
	/* 启动传输 */
	DMA2D->CR   |= DMA2D_CR_START;   
	g_gpu_state = 1;
}

4 3  LVGL使用DMA2D, 使用寄存器DMA2D中断传输

#define LV_USE_GPU              0   /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */
#define LV_USE_GPU_STM32_DMA2D  1
/*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor
e.g. "stm32f769xx.h" or "stm32f429xx.h" */
#define LV_GPU_DMA2D_CMSIS_INCLUDE   "stm32f429xx.h"
volatile uint8_t g_gpu_state = 0;
// DMA2D传输完成回调
static void mDMA2Dcallvack(DMA2D_HandleTypeDef *hdma2d)
{
	 if(g_gpu_state==1){
		 g_gpu_state = 0;
		 lv_disp_flush_ready(&g_disp_drv);
	 }
}
// dma2D采用HAL初始化
static void dma2d_use_hal_init(void)
{

	hdma2d.Instance = DMA2D;
	hdma2d.XferCpltCallback = mDMA2Dcallvack;
  if (HAL_DMA2D_Init(&hdma2d) != HAL_OK)
  {

  }
}

/* Initialize your display and the required peripherals. */
static void disp_init(void)
{
	dma2d_use_reg_init();
}

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
	//LTDC_Color_Fill(area->x1,area->y1,area->x2,area->y2,(uint16_t*)(color_p));
   
	uint32_t h = area->y2 - area->y1;
	uint32_t w = area->x2 - area->x1;
	
	uint32_t OffLineSrc = 1024 - (area->x2 - area->x1 +1);
	uint32_t addr = LCD_FRAME_BUF_ADDR + 2*(1024*area->y1 + area->x1);
	// -- 中断传输
	// 模式
	DMA2D->CR      = 0x00000000UL | (1 << 9);
	// 源地址
	DMA2D->FGMAR   = (uint32_t)(uint16_t*)(color_p);
	// 目标地址
	DMA2D->OMAR    = (uint32_t)addr;
	
	// 输入偏移
	DMA2D->FGOR    = 0;
	// 输出偏移
	DMA2D->OOR     = OffLineSrc;
	
	/* 前景层和输出区域都采用的RGB565颜色格式 */
	DMA2D->FGPFCCR = DMA2D_OUTPUT_RGB565;
	DMA2D->OPFCCR  = DMA2D_OUTPUT_RGB565;
	
	// 多少行
		DMA2D->NLR     = (area->y2-area->y1+1) | ((area->x2 -area->x1 +1) << 16);

	// 开启中断
	DMA2D->CR |= DMA2D_IT_TC|DMA2D_IT_TE|DMA2D_IT_CE;
	
	/* 启动传输 */
	DMA2D->CR   |= DMA2D_CR_START;   
	g_gpu_state = 1;
}

 

对比:

1 不使用GPU,使用寄存器DMA2D,11fps

2 使用GPU,使用寄存器DMA2D, 23fps

3 不使用GPU,使用寄存器DMA2D中断传输, 11fps 

4 使用GPU,中断传输, 30fps

另外我发现开单缓冲比双缓冲快很多, 这个bug估计未来会优化

因为1和3, fps相等是因为在颜色转换消耗了太多时间, 所以中断和阻塞方式基本上差不

听说打开优化等级和编译器等级会更快, 可以试试这个

 

另外自己写DMA2D中断和采用HAL的回调基本参没什么差距, 所以建议直接采用HAL库的回调

void DMA2D_IRQHandler(void)
{

  if ((DMA2D->ISR & DMA2D_FLAG_TC) != 0U)
  {
    if ((DMA2D->CR & DMA2D_IT_TC) != 0U)
    {

			DMA2D->CR &= ~DMA2D_IT_TC;
			DMA2D->IFCR =DMA2D_FLAG_TC;
			
			if(g_gpu_state==1){
				 g_gpu_state = 0;
				 lv_disp_flush_ready(&g_disp_drv);
			 }
    }
  }
}

 

  • 13
    点赞
  • 113
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
### 回答1: STM32F429是意法半导体(STMicroelectronics)推出的一款32位微控制器芯片,它采用了ARM Cortex-M4内核,具有丰富的外设接口和强大的计算能力。它被广泛用于嵌入式系统的设计与开发中。 DM2D是Data Matrix二维码的一种编码方式,它可以通过对二维图形进行编码来存储和传输大量的数据。DM2D码具有较高的容错能力和数据密度,可以在小尺寸的空间内储存更多的信息。 LVGL是一个开源的图形库,全称为Littlev Graphics Library。它是一个轻量级的图形库,适用于嵌入式系统的图形界面开发。LVGL提供了丰富的图形控件和界面效果,支持触摸屏、按键等外设,并且具有灵活的可扩展性。 综上所述,STM32F429 DM2D LVGL可以理解为在STM32F429微控制器上使用DM2D二维码编码方式,结合LVGL图形库进行图形界面的开发。这样我们可以通过STM32F429微控制器来实现二维码的解码与显示,并且使用LVGL图形库可以方便地设计出具有丰富功能和良好交互性的图形界面。 ### 回答2: STM32F429是ST公司推出的一款高性能的32位微控制器。它采用ARM Cortex-M4内核,主频达到180MHz,具有丰富的外设接口和强大的计算能力。DM2D是DigitalMicrograph中的一种数据文件格式,通常用于存储电子显微镜图像的原始数据。LVGL是一个开源的图形库,用于在嵌入式系统中创建图形用户界面(GUI)。 在使用STM32F429进行开发时,可以结合DM2DLVGL进行图形界面设计。STM32F429的高性能和丰富的外设接口可以保证系统的稳定和可靠性。DM2D文件格式可以用来存储从电子显微镜获取的原始图像数据,方便后续的处理和分析。而LVGL图形库可以帮助我们快速地创建出漂亮而丰富的图形用户界面,使得用户与系统之间的交互更加方便和友好。 通过使用DM2DLVGL,我们可以在STM32F429上实现许多有趣的功能。比如,可以通过电子显微镜获取图像数据后,使用DM2D文件格式存储到STM32F429的存储器中。然后使用LVGL图形库创建一个图像浏览界面,让用户可以方便地浏览这些图像。还可以通过LVGL实现一些交互功能,比如选择图像进行处理或者展示。此外,还可以结合其他外设接口,实现更丰富的功能,比如将图像数据传输到其他设备或者通过网络传输到远程服务器。 总之,STM32F429、DM2DLVGL是三个强大的工具,可以帮助我们在嵌入式系统中实现高性能的图形界面和图像处理功能。无论是用于科研、工业控制还是智能设备,它们都能发挥重要作用,提升系统的可用性和用户体验。 ### 回答3: STM32F429是一款由STMicroelectronics开发的高性能ARM Cortex-M4内核的微控制器。它具有低功耗、高速运算和丰富的外设功能,适用于嵌入式系统的开发。 DM2D是Display module 2D的缩写,是一种用于显示控制的软件库。它可以与STM32F429微控制器集成,用于控制液晶显示屏的显示功能。DM2D库可以通过简单的API接口来操作液晶显示屏,并且支持多种显示模式和图形显示功能,方便开发者实现丰富的用户界面。 LVGL(Light and Versatile Graphical Library)是一款开源的图形界面库,用于构建嵌入式系统的用户界面。它具有轻量级、灵活和易于使用的特点,适用于资源受限的嵌入式平台。LVGL提供了丰富的图形控件和动画效果,并支持触摸屏输入和多语言显示。通过集成LVGL库,可以在STM32F429微控制器上轻松实现用户友好的图形界面。 综上所述,STM32F429 DM2D LVGL的组合可以成为一套强大的嵌入式系统开发工具。STM32F429微控制器提供了高性能和丰富的外设功能,DM2D库用于控制液晶显示屏的显示,而LVGL库用于构建漂亮、交互性强的图形界面。这套组合将有助于开发者快速构建出功能强大、用户友好的嵌入式应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值