在STM32高性能芯片中,可以使用DMA2D外设专门用来给LCD显示加速,有LTDC外设的型号中,通常也会配套有DMA2D。
DMA2D外设主要提供了两个功能:
DMA数据搬运:常用从寄存器到存储器、存储器到存储器两种模式,快速高效,并且不占用cpu资源;
2D图形加速:支持快速格式转换和混合;
更改LCD_PIXEL_FORMAT宏为RTGRAPHIC_PIXEL_FORMAT_RGB565
1static void lcd_fb_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
2{
3 uint32_t OffLineSrc = LV_HOR_RES_MAX - (area->x2 - area->x1 + 1);
4 uint32_t addr = (uint32_t) LtdcHandle.LayerCfg[0].FBStartAdress + 2 * (LV_HOR_RES_MAX * area->y1 + area->x1);
5
6 // 中断传输
7 // 模式 TC 中断使能
8 DMA2D->CR = 0x00000000UL | (1 << 9);
9 // 源地址
10 DMA2D->FGMAR = (uint32_t) (uint16_t*) (color_p);
11 // 目标地址
12 DMA2D->OMAR = (uint32_t) addr;
13 // 输入偏移
14 DMA2D->FGOR = 0;
15 // 输出偏移
16 DMA2D->OOR = OffLineSrc;
17 /* 前景层和输出区域都采用的RGB565颜色格式 */
18 DMA2D->FGPFCCR = DMA2D_OUTPUT_RGB565;
19 DMA2D->OPFCCR = DMA2D_OUTPUT_RGB565;
20
21 // 多少行
22 DMA2D->NLR = (area->y2 - area->y1 + 1) | ((area->x2 - area->x1 + 1) << 16);
23 // 开启中断
24 DMA2D->CR |= DMA2D_IT_TC | DMA2D_IT_TE | DMA2D_IT_CE;
25 /* 启动传输 */
26 DMA2D->CR |= DMA2D_CR_START;
27 g_gpu_state = 1;
28}
29
30void DMA2D_IRQHandler(void)
31{
32 rt_interrupt_enter();
33 /*中断传输完成*/
34 if ((DMA2D->ISR & DMA2D_FLAG_TC) != 0U)
35 {
36 if ((DMA2D->CR & DMA2D_IT_TC) != 0U)
37 {
38 DMA2D->CR &= ~DMA2D_IT_TC; /*关闭中断*/
39 DMA2D->IFCR = DMA2D_FLAG_TC;/*清除传输完成中断*/
40 if (g_gpu_state == 1)
41 {
42 g_gpu_state = 0;
43 /*lvgl刷屏接口*/
44 lv_disp_flush_ready(&g_disp_drv);
45 }
46 }
47 }
48 rt_interrupt_leave();
49}
50
51void LTDC_IRQHandler(void)
52{
53 rt_interrupt_enter();
54 /* USER CODE END LTDC_IRQn 0 */
55 HAL_LTDC_IRQHandler(&LtdcHandle);
56 /* USER CODE END DMA2D_IRQn 1 */
57 rt_interrupt_leave();
58}
触摸显示接口
1static bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
2{
3 static uint16_t last_x = 0;
4 static uint16_t last_y = 0;
5
6 //触摸按下了
7 if (tp_dev.sta & TP_PRES_DOWN)
8 {
9 last_x = tp_dev.x[0];
10 last_y = tp_dev.y[0];
11 data->point.x = last_x;
12 data->point.y = last_y;
13 data->state = LV_INDEV_STATE_PR;
14 }
15 else//触摸松开了
16 {
17 data->point.x = last_x;
18 data->point.y = last_y;
19 data->state = LV_INDEV_STATE_REL;
20 }
21
22 //返回false代表没有缓冲的数据
23 return false;
24}
打开lv_conf.h中LV_USE_PERF_MONITOR的宏
帧率的优化与编译器的优化等级也有关系,这里我使用的是O2等级进行编译
可以看到,通过DMA2D的加速,LVGL可以流畅的显示最高33FPS,对于后续LVGL的应用层编写打下了基础。
你可以添加微信17775982065为好友,注明:公司+姓名,拉进RT-Thread官方微信交流群!
👇 点击阅读原文进入原帖