1-移植准备
LVGL8.2
野火STM32F429_v2开发板
因为ST在STM32F4之后所有的芯片都不在有标准库,因此本篇是基于HAL库的。同时现在有许多厂商都不在有标准库了,都是根据自己的开发环境进行一些基本芯片接口的配置。像NXP,ST等。
这里不过多介绍LVGL,既然看到这个文章,大多数是奔着移植过来的。
2-开始移植
下载
我们首先去LVGL官网下载LVGL源码,当然文章末尾会给出。
下载后解压出来(我下载的是8.2版本的,其他版本的移植过程是一样的)
解压后文件夹里内容如图所示:
其中有些文件是官方的测试以及一些文档,我们只保留这几个就可以,如下图所示:
同时对examples这个文件夹只保留 porting就行,当然如果有需要可以保留。如下图所示:
移植
然后就开始移植了,找到野火28-电容触摸屏—触摸画板(屏幕兼容版)这个,
然后再文件加下建立如下结构文件,当然,具体是可以根据自己的习惯进行创建的
LVGL
|
- GUI_App
- GUI
|
-lvgl
如下图:
然后把对应的文件放入文件夹下,如图所示:lv_conf_template.h重命名为lv_conf_.h
打开工程
之后打开工程,点击这个图标修改工程名称,如下图:
之后修改工程名称,再添加分组:如下结构,当然可以根据个人的习惯进行:
进行分组命名之后,添加C文件,具体如下图所示:
添加完成就是下面这种,当然为了方面把…\LVGL\GUI\lvgl\lv_conf.h这个文件也添加进来。方便修改一些基本配置。
然后把头文件添加进来。如下图:如果报错,看看是哪个头文件没有添加进来。
开启C99模式
这个必须开启,不然会有很多的错误问题。
然后开始修改lv_conf.h文件,下面这个地方修改为1.
之后我们进行编译。
编译后,如果出现Undefined symbol __aeabi_assert这个错误,进行如下修改。
如下图:
或者去掉下图这个对号:
显示屏幕移植
把 lv_port_disp_template.c/h 的条件编译指令 #if 0 修改成 #if 1,同时添加LCD屏幕头文件。
这里有三种缓冲方式,我采用的是第一种,当然你们可以尝试剩余的两种。
红色黄框内是自己根据屏幕的水平宽度设置的,我的是800.
初始化
如下图所示,我用的是野火5寸屏,有二层显示结构,我选择的是第一层,如果你的是第二层,要保持一致,否则背景色会是其他颜色。
像素区域的填充
设置屏幕的尺寸
然后我们在定时器或者系统时钟中添加LVGL tick我使用的是系统时钟,记住要添加LVGL头文件。如下面这样:
然后就是主函数的调用:
添加下面这两个头文件,以及LVGL任务处理句柄如下图:
到这里显示部分就配置完成了。下面写一个按键看看行不行:
int main(void)
{
int i=0;
HAL_Init();
/* 系统时钟初始化成216 MHz */
SystemClock_Config();
/* LED 端口初始化 */
LED_GPIO_Config();
DEBUG_USART_Config();
/* 初始化触摸屏 */
// GTP_Init_Panel();
/* 配置透明度,最小值为0,最大值为255*/
lv_init();
lv_port_disp_init();
lv_port_indev_init();
lv_obj_t * label;
lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -40);
label = lv_label_create(btn1);
lv_label_set_text(label, "Button");
lv_obj_center(label);
lv_obj_t * btn2 = lv_btn_create(lv_scr_act());
lv_obj_align(btn2, LV_ALIGN_CENTER, 0, 40);
lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE);
lv_obj_set_height(btn2, LV_SIZE_CONTENT);
label = lv_label_create(btn2);
lv_label_set_text(label, "Toggle");
lv_obj_center(label);
//
while(1)
{
lv_task_handler();
}
}
如下测试图:
测试完成,内有问题。
触摸的添加
把 lv_port_indev_template.c/h 的条件编译指令 #if 0 修改成#if 1
然后添加触摸头文件。如下图:
我们回到触摸,野火触摸这块需要修改以下。
在触摸文件中添加下面两个函数:
static bool isTouch=0;//全局静态变量
//这个是LVGL触摸文件要用到的
bool Touch_isPressed(void)
{
if(isTouch == 1)
{
isTouch = 0;
return true;
}
return false;
}
//这个是触摸中断回调函数。
void GTP_IRQHandler(void)
{
if(__HAL_GPIO_EXTI_GET_IT(GTP_INT_GPIO_PIN) != RESET) //确保是否产生了EXTI Line中断
{
// LED2_TOGGLE;
// GTP_TouchProcess();
isTouch=1;
__HAL_GPIO_EXTI_CLEAR_IT(GTP_INT_GPIO_PIN); //清除中断标志位
}
}
/**
* @brief 触屏检测函数,本函数作为emXGUI的定制检测函数,
* 参考Goodix_TS_Work_Func修改而来, 只读取单个触摸点坐标
* @param x[out] y[out] 读取到的坐标
* @retval 坐标有效返回1,否则返回0
*/
//这个是获取x,y触摸的坐标点函数,在lv_port_indev_template有用到
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};
//2-寄存器地址 1-状态寄存器 8*1-每个触摸点使用8个寄存器
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;
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)
{
input_x = point_data[3+1] | (point_data[3+2] << 8); //x坐标
input_y = point_data[3+3] | (point_data[3+4] << 8); //y坐标
if(input_x < GTP_MAX_WIDTH && input_y < GTP_MAX_HEIGHT)
{
*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;
}
在lv_port_indev_template.h文件中只保留和触摸相关的,其他的进行注释。
触摸初始化
触摸坐标获取
到这就结束了。咱们试验一下:
源码关注V南山府嵌入式回复3000获取。因为这里上传下载,你们需要积分才能下载。