背景介绍
我使用的是中景园的1.3寸,240*240的LCD,主控是STM32L152系列
https://item.taobao.com/item.htm?spm=3688y.1.14.16.1916264bJ5QnqC&id=565591692266&ns=1&abbucket=2#detail
1、第一坑-驱动
开始以为驱动这个屏幕应该不难,因为有例程,结果第一坑就来了。我使用的是STM32L152系列,刚好有个PB12~PB15这对SPI2引脚引出,就把屏幕接到了这个上,但是没有使用SPI功能,只是作为普通IO口用。于是移植了例程中STM32F103系列的到STM32L152上,但是就是无法驱动,始终黑屏。
没办法,重新换管脚到PA0~PA4上,结果立马正常显示了。
目前没有找到问题,只能怀疑PB引脚驱动力不够
第二坑-LVGL无法显示
搞定驱动后就要移植LVGL。
此处是参考这个大神的教程,写的真的很棒。
https://blog.csdn.net/weixin_42111891/article/details/124989266
移植完毕后发现还是无法驱动,是花屏。
猜测是因为我的disp_flush()中填的那个驱动函数不对。
于是查看驱动代码发现
大神用的是正点原子的屏幕。所用的填充函数如下:
注意最后一个参数是u16*color是一个指针。
//在指定区域内填充指定颜色块
//(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex-sx+1)*(ey-sy+1)
//color:要填充的颜色
void LCD_Color_Fill(u16 sx, u16 sy, u16 ex, u16 ey, u16 *color)
{
u16 height, width;
u16 i, j;
width = ex - sx + 1; //得到填充的宽度
height = ey - sy + 1; //高度
for (i = 0; i < height; i++)
{
LCD_SetCursor(sx, sy + i); //设置光标位置
LCD_WriteRAM_Prepare(); //开始写入GRAM
for (j = 0; j < width; j++)
{
LCD->LCD_RAM=color[i * width + j]; //写入数据
}
}
}
而中景园自带的驱动中只有这两个函数
LCD_Fill只能填单个颜色块。
void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color);
LCD_ShowPicture只能绘制8字节的图片数组。
void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[])
所以必须要重新写一个。
一开始是仿照正点原子的驱动去写,但是怎么修改都是花屏。
于是开始找资料,但是网上用这块LCD的都是ESP32,也只能看看这个资料看看他们是怎么驱动的。
于是找到了这个老哥的资料
https://www.bilibili.com/video/av847784236/
https://gitee.com/gsm-wheather-project
下载查看代码后,找到这个函数
void LCD_Fill_Colors(u16 xsta,u16 ysta,u16 xend,u16 yend,lv_color_t* color_p)
{
uint32_t x=0,y=0;
uint16_t width = (xend-xsta+1);
uint16_t height = (yend-ysta+1);
long len=width*height;
//xSemaphoreTakeRecursive(_spi_mux, portMAX_DELAY);
#if 0
LCD_Address_Set(xsta,ysta,xend,yend);//设置显示范围
for(y = 0; y <width*height; y++)
{
LCD_WR_DATA(color_p->full);
color_p++;
}
for(y = ysta; y <= yend; y++) {
for(x = xsta; x <= xend; x++) {
LCD_DrawPoint(x, y, (color_p->full));
color_p++;
}
}
#else
#define lcd_spi_dat_len 50
esp_err_t ret;
spi_transaction_t t;
int cnt=0,i=0;
int tx_mode=0;
int tx_len = lcd_spi_dat_len;
int break_cnt=0;
uint16_t buf[lcd_spi_dat_len];
memset(buf,RED,lcd_spi_dat_len);
LCD_Address_Set(xsta,ysta,xend,yend);//设置显示范围
if(len<lcd_spi_dat_len)
{
tx_len = len;
tx_mode=1;
}
while(1)
{
for(i=0;i<tx_len;i++)
{
buf[i]=SWAPBYTES(color_p[cnt*tx_len+i].full);
}
memset(&t, 0, sizeof(t));
t.length=2*8*tx_len;
t.tx_buffer=&buf[0];
t.user=(void*)0;
ret=spi_device_transmit(lcd_spi, &t);
if(tx_mode==1)
break;
cnt++;
if(len>lcd_spi_dat_len)
{
len-=tx_len;
}else
{
tx_len=len;
len-=tx_len;
if(++break_cnt>1)
break;
}
}
#endif
//xSemaphoreGiveRecursive(_spi_mux);
}
于是稍加改造,得到
void LCD_Color_Fill(u16 sx, u16 sy, u16 ex, u16 ey, lv_color_t *color)
{
u16 i,j;
u32 k=0;
uint32_t x=0,y=0;
u16 height, width;
width = ex - sx + 1; //得到填充的宽度
height = ey - sy + 1; //高度
LCD_Address_Set(sx,sy,ex,ey);
for(y = 0; y <width*height; y++)
{
LCD_WR_DATA(color->full);
color++;
}
}
注意,在LVGL中使用也要修改如下。
/*Flush the content of the internal buffer the specific area on the display
*You can use DMA or any hardware acceleration to do this operation in the background but
*'lv_disp_flush_ready()' has to be called when finished.*/
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,color_p);
/*IMPORTANT!!!
*Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
}
到此,LVGL和中景园的LCD可以驱动起来。但是目前还存在刷新速度很慢的问题。还需要继续解决,目前先记录。
第三坑 编译警告坑
移植后编译会有报错和警告,
报错一般是找不到这个路径include “…/…/lv_conf.h”,若头文件#include "lvgl/lvgl.h"包含报错,可以添加宏定义LV_CONF_INCLUDE_SIMPLE。
警告是warning: #188-D: enumerated type mixed with another type lv_slider_set_。。。。。。。
这个需要在魔术棒的那个设置中添加–diag_suppress=188,546,68,111,含义就是消除警告编号为188,546.68,11这这类警告,并不是解决了警告,而是屏蔽。
ESP32+TFT_eSPI+LVGL
本项目基于VSCode+Platform
首先创建一个ESP32的工程,然后在Platform主页的libraries中搜索TFT_eSPI,并把他添加到工程中,然后首先先驱动LCD屏幕确保屏幕没问题。
参考链接 https://www.jianshu.com/p/8631a10b5533
添加LVGL,也是在在Platform主页的libraries中搜索LVGL,添加到工程中。
驱动的方式可以参考下文连接,但是不用做1,2条,因为可以直接添加LGVL到工程中,我已经尝试成功。
https://blog.csdn.net/weixin_41711422/article/details/126354263
显示第一帧画面后无反应
1、主函数循环中是否有添加lv_task_handler(); // lvgl的事务处理
2、在定时器中断中要添加lv_tick_inc(1);//lvgl的1ms中断,并且要确认定时器是可以正常工作的,否则LVGL的任务不会开始调用。文章来源:https://www.toymoban.com/news/detail-457770.html
简单参考程序
基于STM32L152驱动中景园LCD(LVGL)文章来源地址https://www.toymoban.com/news/detail-457770.html
到了这里,关于关于驱动中景园LCD和LVGL踩的一些坑的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!