高级会员
- 积分
- 830
- 金钱
- 830
- 注册时间
- 2020-7-1
- 在线时间
- 110 小时
|
本帖最后由 q879524825 于 2021-9-17 14:30 编辑
最近用STM32F103ZET6做 LVGL 的移植,结果发现 画曲线图的 页面只有4FPS,,所以想办法进行优化,使用的是F1精英板 。没有使用外扩SRAM 加速 。
目前采用 显示接口函数如下: 采用双buf
- void lv_port_disp_init(void)
- {
- /*-------------------------
- * Initialize your display
- * -----------------------*/
- disp_init();
- /*-----------------------------
- * Create a buffer for drawing
- *----------------------------*/
- static lv_disp_draw_buf_t disp_buf;
- /* Example for 2) */ //240*10*2/1024= 4.7KB
- static lv_color_t buf_2_1[LV_HOR_RES_MAX * 10]; //双buf没什么提升 /*A buffer for 10 rows*/
- static lv_color_t buf_2_2[LV_HOR_RES_MAX * 10]; /*An other buffer for 10 rows*/
- lv_disp_draw_buf_init(&disp_buf, buf_2_1, buf_2_2, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
-
- /* Example for 3) also set disp_drv.full_refresh = 1 below*/
- //320*240*2*2/1024= 300KB ?? 太大了
- // static lv_color_t buf_3_1[LV_HOR_RES_MAX * LV_VER_RES_MAX]; /*A screen sized buffer*/
- // static lv_color_t buf_3_2[LV_HOR_RES_MAX * LV_VER_RES_MAX]; /*An other screen sized buffer*/
- // lv_disp_draw_buf_init(&disp_buf, buf_3_1, buf_3_2, LV_HOR_RES_MAX * LV_VER_RES_MAX); /*Initialize the display buffer*/
-
- static lv_disp_drv_t disp_drv; /*A variable to hold the drivers. Must be static or global.*/
- lv_disp_drv_init(&disp_drv); /*Basic initialization*/
- disp_drv.draw_buf = &disp_buf; /*Set an initialized buffer*/
- disp_drv.flush_cb = disp_flush; /*Set a flush callback to draw to the display*/
- disp_drv.hor_res = lcddev.width; //从LCD的结构体里获取分辨率
- disp_drv.ver_res = lcddev.height;
- lv_disp_t * disp;
- disp = lv_disp_drv_register(&disp_drv); /*Register the driver*/
-
-
- }
- static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
- {
- //LCD_Color_Fill(area->x1,area->y1,area->x2,area->y2,(u16*)color_p); //正点LVGL 源码里 使用的 是这个
- DMA2C4_LCD_Color_Fill(area->x1,area->y1,area->x2,area->y2,(u16*)color_p); //尝试用DMA吧 cpu太拉了
-
- /* IMPORTANT!!!
- * Inform the graphics library that you are ready with the flushing*/
- lv_disp_flush_ready(disp_drv);
- }
复制代码 DMA 的代码如下:本来用的是LCD_Color_Fill() 这个函数 ,我照葫芦画瓢 写了DMA2C4_LCD_Color_Fill 由于原子的 函数 是 逐行 逐列 一个点一个点的 写的 ,每一行写之前 还要 定为 坐标LCD_SetCursor(sx,sy+i); //设置光标位置 以及 LCD_WriteRAM_Prepare(); //开始写入GRAM
有些问题 感觉有点困惑 :
1.不能 将 整块字节 用DMA 写入 目前只是用DMA 写入一行 ,
2.我想要 main函数里初始化一次DMA, 然后在DMA2C4_LCD_Color_Fill 里更改 寄存器 更改DMA2_Channel4 的CNDTR 和CMAR 从而修改 缓存大小 和 内存地址,但是这样不起作用,烧录后屏幕白屏,模糊。 所以只能每次写一行 之前 都初始化一次 DMA 更改缓存大小 和 内存地址 ,感觉有点蠢。 另外就是这样用DMA 和用 原本的 刷屏函数 没什么区别啊 ,还是很卡 72M 不太好用 啊
- /*配置 DMA 内存到内存 从 数组 到 FSMC
- */
- static DMA_InitTypeDef DMA_FSMC_InitStructure; //全局变量 ,
- void DMA2C4_FSMC_Config(u32 size, u32 mem_addr)
- {
-
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); //使能DMA传输
-
- DMA_DeInit(DMA2_Channel4); //将DMA的通道 寄存器重设为缺省值
- DMA_FSMC_InitStructure.DMA_PeripheralBaseAddr = (u32)&LCD->LCD_RAM; //DMA外设基地址
- DMA_FSMC_InitStructure.DMA_MemoryBaseAddr = mem_addr; //DMA内存基地址 内存地址是?
- DMA_FSMC_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设
- DMA_FSMC_InitStructure.DMA_BufferSize = size; //DMA通道的DMA缓存的大小
- DMA_FSMC_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变 *****
- DMA_FSMC_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
- DMA_FSMC_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //数据宽度为16位
- DMA_FSMC_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
- DMA_FSMC_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常模式 传输一次后 就停止了 因为 缓存大小 被复位为0了
- DMA_FSMC_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
- DMA_FSMC_InitStructure.DMA_M2M = DMA_M2M_Enable; //DMA通道x 设置为内存到内存传输
- DMA_Init(DMA2_Channel4, &DMA_FSMC_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
-
- DMA_Cmd(DMA2_Channel4, DISABLE ); //先关闭
- }
- void DMA2C4_LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color)
- {
- u16 i=0,j=0;
- u16 height,width;
- u32 Fill_Num;
- width=ex-sx+1; //得到填充的宽度
- height=ey-sy+1; //高度
-
-
- for(i=0;i<height;i++) //一行一行的写
- {
-
- LCD_SetCursor(sx,sy+i); //设置光标位置
- LCD_WriteRAM_Prepare(); //开始写入GRAM
-
- // DMA2_Channel4->CCR &= (uint16_t)(~DMA_CCR1_EN); //关闭DMA2,
- // DMA2_Channel4->CNDTR =width; //设置buffsize 正常模式 工作一次后 该寄存器就清空了
- // DMA2_Channel4->CMAR =(u32)(color+(i*width)); //寄存器修改内存地址
- DMA2C4_FSMC_Config(width,(u32)(color+(i*width))); //每次 重新配置DMA ? 浪费时间 啊
- DMA2_Channel4->CCR |= DMA_CCR1_EN; //开启一次DMA传输
- while(DMA_GetFlagStatus(DMA2_FLAG_TC4)!=SET); //等完成 一行一行的发
- DMA2_Channel4->CCR &= (uint16_t)(~DMA_CCR1_EN); //关闭DMA2,
-
- } //可以用了 但是显示效果没什么变化
-
- //就不能 一个块 DMA 发送嘛
- }
复制代码 |
|