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);}}}
}
stm32 DMA2D使用中断LVGL,提高LVGL帧率相关推荐
- 【LVGL应用开发--基于STM32】第1章 初识LVGL
文章目录 前言 1.1 LVGL简介 1.2 LVGL移植要求 1.3 LVGL源码下载与介绍 前言 在实际应用中,我们时常需要制作 UI 界面来实现人机交互,简单的 UI 可以直接编写代码,但对于那 ...
- STM32的“外部中断”和“事件”区别和理解
凡从事过ST MCU应用开发的人往往会遇到事件.中断事件 中断三个概念或术语.这三个概念彼此关联,有时会让人有点混淆或犯迷糊. 先拿一件生活中的事情打比方对上述三个概念做个基本的粗略理解,之后再分享一 ...
- STM32单片机外部中断配置讲解
2019独角兽企业重金招聘Python工程师标准>>> 单片机外部中断简介 所谓外部中断,就是通过外部信号所引起的中断,如单片机引脚上的电平变化(高电平.低电平).边沿变化(上升沿. ...
- STM32网络之中断
之前的推文已经将STM32网络的三大件讲完了 ①PHY接口,<STM32网络电路设计> ②MAC控制器,<STM32网络之MAC控制器> ③DMA控制器,<STM32网络 ...
- stm32: 串口空闲中断的实现(HAL库)
STM32利用串口空闲中断来分包(HAL库) 文章目录 STM32利用串口空闲中断来分包(HAL库) 1. 开发环境 2. 串口中断接收的问题和解决办法 3. 串口空闲中断分包的原理 4. STM32 ...
- stm32入门——定时器中断和中断优先级简介
stm32入门--定时器中断 产生定时中断是定时器的用法之一,与定时器用来进行PWM输出和输入捕获相比,定时器中断更容易理解.掌握. 原理简介 使用通用定时器进行中断的原理,其实和开发板Systick ...
- 深入浅出地理解STM32中的中断系统——从原理到简单工程示例——保姆级教程
深入浅出地理解STM32中的中断系统 一.什么是中断?什么是异常? 二.如何管理中断? 三.NVIC 1 NVIC 特点 2 中断优先级 (1) 优先级分组 3 中断向量表 4 中断服务函数 (1)中 ...
- stm32学习笔记-中断系统
文章目录 问题引入 1.中断系统概述. 1.1 为什么要中断(中断意义) 中断和轮询比较: 1.2 中断处理过程 1.3 中断笔试题 1.4 中断服务函数 2.STM32中断的体系结构. 2.1 结构 ...
- STM32系列 USART中断接收 注意事项 (USART_IT_ORE)
ZHL学习笔记 STM32系列USART中断接受注意事项 之 USART_IT_ORE USART_IT_ORE含义:接收溢出,尚未处理上一拍就迎来了下一拍数据: USART_IT_ORE使能:该中断 ...
最新文章
- (完全解决)(numba)TypingError: Failed in nopython mode pipeline( Invalid use of Function)
- 传统数据中心穿上“云”外衣 任重而道远
- Unable to instantiate application
- 当前计算机无法连接,win7系统无法连接wifi提示此计算机当前已将连接限制为xxx的解决方法...
- 03-Flutter移动电商实战-底部导航栏制作
- 宾利为什么卖这么贵?
- 2019 PC 台式机垃圾佬 记录
- 12. 指针、句柄、引用的区别
- OCP大会 | 腾讯开放光网络平台(附PDF)
- 将《先生请出山》放到桌面上,聊聊如何将视频做成动态壁纸
- 嵌入式实践教程--Android HAL自定义HAL代码教程
- iOS开发工程师常见面试题及答案
- SFDC数据导出的几种方式
- 计算机内存容量影响游戏的吗,内存容量对整机游戏性能影响有多大?
- 《图解HTTP》摘录
- MPX200 ROM DIY指南[转]
- 汉诺塔问题——递归算法
- Scala class和case class的区别
- 三十行代码轻松破解山东理工大学教务系统的登录问题
- Windows Server 2012 R2 部署JavaWeb项目之环境、软件、配置
热门文章
- win10怎么连接android手机,如何将手机与Win10电脑关联以在电脑上继续任务?
- ggplot2画图——点图想要描边但是又需要去除边框
- 启动错误:Could not resolve placeholder 'spring.datasource.url' in value ${spring.datasource.url}
- 最详细的教程axure新手入门:Axure教程
- DW大学生网页作业制作设计 中华饮食文化(HTML+CSS+JavaScript) Web前端大作业
- 双连通图强连通图概念解释以及tarjan算法求解该类问题总结
- java计算机毕业设计社区生活超市管理系统源程序+mysql+系统+lw文档+远程调试
- 部署Kubernetes时出现ImagePullBackOff或ErrImagePull情况
- 必备武器-skycc营销软件
- mysql报错3009_MySQL修改密码方法汇总