背景介绍

我使用的是中景园的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的任务不会开始调用。

简单参考程序

基于STM32L152驱动中景园LCD(LVGL)

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐