简介:
开发版是野火STM32F429V2版本 5寸屏 800*480;
lvgl版本是V8.3;
1、获取lvgl_v8.3版本源码
笔者使用的是v8.3版本
使用dowload zip或git clone下载
2、STM32F429电容触摸屏驱动demo
采用野火库函数版本触摸屏驱动例程。
这里踩了一个坑,一开始是百度网盘下载的例程代码,这个例程只支持gt9157触摸芯片,笔者开发版是23年3月份买的,触摸芯片对不上。或者直接在g5xx.h,使能UPDATE_CONFIG
最好从野火大学堂拉取最新的例程代码,支持gt9157/gt911/gt5688触摸芯片。
3、导入lvgl相关文件
3.1移植效果
现在屏驱动文件中新建两个文件夹 gui 和 gui_app,gui放置lvgl源码,gui_app放置lvgl_demo文件。如下是已经移植好的。
3.2lvgl源码移植内容
lvgl文件夹下examples,src和lvgl.h, lv_conf_template.h拷贝到gui文件夹下面,lv_conf_template.h需要修改为lv_conf.h。
demo文件夹,视个人需要,拷贝一个就可以了;笔者只拷贝了widgets。
将examples文件夹中的porting拷贝到gui目录下。
porting文件夹下是lvgl源码中的disp屏幕显示驱动,fs文件系统和indev输入设备驱动(触摸,鼠标,键盘等)。
原文件如下所示,需要将文件名中的template去掉。
3.3、添加源码
添加gui目录下所有.C文件
添加gui目录下所有.C文件
头文件路径设置
4、代码修改
4.1、lv_conf.h
打开行10 的 #if 1,使用lv_conf.h.
#define MY_DISP_HOR_RES 800 //设置屏幕参数 宽
#define MY_DISP_VER_RES 480 //设置屏幕参数 高
#define LV_COLOR_DEPTH 16 //设置颜色格式
如果最终屏幕显示不完全,可以改大LV_MEM_SIZE这个参数,如下是笔者设置的大小
STM32F429这款芯片是支持DMA2D的,如果要使用这个技术,就使能LV_USE_GPU_STM32_DMA2D,截止发稿,笔者的DMA2D还没有调好,开启之后会花屏,所以关闭了。
4.2lv_port_disp.c
lvgl的显示文件,需要补充屏幕初始化disp_init(),也可以直接拷贝main()函数里面的屏幕初始化。
注意lvgl.h和lv_conf.h的文件路径,不然会报错。
LCD_Init();
LCD_DisplayOn();
/* LCD 第二层初始化 */
LCD_LayerInit(0, LCD_FB_START_ADDRESS, RGB565);
/*选择LCD第一层*/
LCD_SelectLayer(0);
LCD_SetTransparency(0, 255);
/*第二层清屏,显示全黑*/
LCD_Clear(LCD_COLOR_TRANSPARENT);
补充disp_flush()
屏幕显示函数,可以采用打点的方式,一个个像素点显示,效率最慢,最简单的方式
也可以使用DMA2D,数据填充的方式。
笔者采用的是打点显示,LCD_DrawPixel函数的功能可以在bsp_lcd.c中找到。
补充lv_port_disp_init()
1、将数组存储到SDRAM中,增加数据读写速度,实际效果不是很大
2、设置lvgl屏幕显示大小
4.3lv_port_indev.c
lv_port_indev_init输入设备初始化,保留touch触摸,其他都注释掉。
获取触摸的x,y坐标值
int GTP_Execu( int16_t *x,int16_t *y)
{
uint8_t end_cmd[3] = {GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF, 0};
uint8_t point_data[2 + 1 + 8 * 1 + 1]={GTP_READ_COOR_ADDR >> 8, GTP_READ_COOR_ADDR & 0xFF};
uint8_t touch_num = 0;
uint8_t finger = 0;
uint8_t client_addr=GTP_ADDRESS;
int32_t input_x = 0;
int32_t input_y = 0;
int32_t ret = -1;
static uint16_t pre_touch = 0;
static uint8_t pre_id[GTP_MAX_TOUCH] = {0};
uint8_t* coor_data = NULL;
uint8_t id = 0;
int32_t i = 0;
GTP_DEBUG_FUNC();
ret = GTP_I2C_Read(client_addr, point_data, 12);//10字节寄存器加2字节地址
if (ret < 0)
{
GTP_ERROR("I2C transfer error. errno:%d\n ", ret);
return 0;
}
finger = point_data[GTP_ADDR_LENGTH];//状态寄存器数据
if (finger == 0x00) //没有数据,退出
{
return 0;
}
if((finger & 0x80) == 0)//判断buffer status位
{
goto exit_work_func;//坐标未就绪,数据无效
}
touch_num = finger & 0x0f;//坐标点数
if (touch_num > GTP_MAX_TOUCH)
{
goto exit_work_func;//大于最大支持点数,错误退出
}
if (touch_num > 1)//不止一个点
{
uint8_t buf[8 * GTP_MAX_TOUCH] = {(GTP_READ_COOR_ADDR + 10) >> 8, (GTP_READ_COOR_ADDR + 10) & 0xff};
ret = GTP_I2C_Read(client_addr, buf, 2 + 8 * (touch_num - 1));
memcpy(&point_data[12], &buf[2], 8 * (touch_num - 1)); //复制其余点数的数据到point_data
}
if (pre_touch>touch_num) //pre_touch>touch_num,表示有的点释放了
{
for (i = 0; i < pre_touch; i++) //一个点一个点处理
{
uint8_t j;
for(j=0; j<touch_num; j++)
{
coor_data = &point_data[j * 8 + 3];
id = coor_data[0] & 0x0F; //track id
if(pre_id[i] == id)
break;
if(j >= touch_num-1) //遍历当前所有id都找不到pre_id[i],表示已释放
{
GTP_Touch_Up( pre_id[i]);
}
}
}
}
if (touch_num)
{
for (i = 0; i < touch_num; i++) //一个点一个点处理
{
coor_data = &point_data[i * 8 + 3];
id = coor_data[0] & 0x0F; //track id
pre_id[i] = id;
input_x = coor_data[1] | (coor_data[2] << 8); //x坐标
input_y = coor_data[3] | (coor_data[4] << 8); //y坐标
{
*x = input_x;
*y = input_y;
}
}
}
else
{
goto exit_work_func;
}
exit_work_func:
{
//清空标志
ret = GTP_I2C_Write(client_addr, end_cmd, 3);
if (ret < 0)
{
GTP_INFO("I2C write end_cmd error!");
return 0;
}
}
return touch_num;
}
tick时钟
5、main.c和demo
main函数如下
lv_demo_conf.h
使能LV_USE_DEMO_WIDGETS,如果编译有报错,需要开启字体的宏
5、编译下载
显示不全可以增大栈和堆的空间