大学生
最后登录1970-1-1
在线时间 小时
注册时间2016-2-5
|
这两天看到论坛上好多大佬们说littleVGL(lvgl),下了来试着在野火429上移植一下。看了一天官方英文移植文档,还是有点吃力的,不过好在有了emwin的经验的话还是比较容易看懂的。
github上有官方源码和429discovery开发板的例子可以用。
https://github.com/littlevgl/lv_port_stm32f429_disco_sw4stm32
对lvgl的配置基本都在lvgl_conf.h中,其中有个内存管理的,名字记不得了。在初始化lvgl的时候,会分配一个数组做它的内存,默认32k。这个配置为这块内存指定地址。
下面说这个429的例子,lvgl最多用两个缓存在后台绘图,当然还有一块显示缓存,供ltdc驱动显示器用。
为了数据传输,官方的例子将DMA2D给了后台缓存,后台缓存到显示缓存是用的一个dma。
问题就在这个dma上。在这个dma中断中,它要判断是否传输完所有数据,如果没有,要重新计算地址,并再次启动dma。如果绘制的只是屏幕中的一部分,lvgl会给出绘图区域的坐标,以及数据源的地址。默认lvgl使用rgb565格式,每个像素占两个字节。dma是一行一行地传送的数据,再次启动dma传输前,源数据地址应该是下一行的地址(初始地址+绘图区域的宽度*2)。这个官方例子中,下一次传输的例子的数据源地址计算有误,把乘以2遗漏了。在这个地方花了很长时间调试,最后才发现。所以写出来。
static void DMA_TransferComplete(DMA_HandleTypeDef *han)
{
y_fill_act ++;
if(y_fill_act > y2_fill) {
lv_disp_flush_ready(&disp_drv);
} else {
/* 问题就在这里 */
buf_to_flush += x2_flush - x1_flush + 1;
/*##-7- Start the DMA transfer using the interrupt mode ####################*/
/* Configure the source, destination and buffer size DMA fields and Start DMA Stream transfer */
/* Enable All the DMA interrupts */
if(HAL_DMA_Start_IT(han,(uint32_t)buf_to_flush, (uint32_t)&my_fb[y_fill_act * TFT_HOR_RES + x1_flush],
(x2_flush - x1_flush + 1)) != HAL_OK)
{
while(1); /*Halt on error*/
}
}
} |
|