第二章:从理论到实践 —— STM32上的LVGL移植之旅
目录
2.1 引言
2.2 准备工作
2.3 下载和配置LVGL
2.4 移植LVGL到STM32
2.4.1 初始化显示驱动和触摸驱动
2.4.1.2 根据你的显示屏类型,编写或使用现有的显示驱动代码。
2.4.2 初始化lvgl的时基
2.5 编写示例应用程序
2.6 编译和调试
2.7 本章小结
2.1 引言
在这一章,我们将把理论转化为实践,手把手带你完成在STM32微控制器上移植LVGL图形库的过程。我们将通过一系列的步骤,确保你能够顺利地在STM32平台上运行LVGL,并创建出基本的图形界面。
2.2 准备工作
在开始移植之前,我们需要做一些准备工作:
2.3 下载和配置LVGL
第一步解压github中下载的文件并跟着正点原子进行裁剪文件
………
裁剪并将文件添加到相应的库中后即可开始下面的步骤
2.4 移植LVGL到STM32
2.4.1 初始化显示驱动和触摸驱动
2.4.1.2 根据你的显示屏类型,编写或使用现有的显示驱动代码。
在这里disp文件修改你的显示屏接口与lvgl对接。
如下图先初始化屏幕
然后在写绘制函数
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
LCD_Address_Set(area->x1,area->y1,area->x2,area->y2);//设置光标位置
for(int i=area->y1;i<area->y2+1;i++)
{
for(int j=area->x1;j<area->x2+1;j++)
{
LCD_WR_DATA((uint16_t)color_p->full);
color_p++;
}
}
/*IMPORTANT!!!
*Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
}
上图是一个重点 ,这个函数是刷一个矩形区域(也即是一行一行刷)的相比单纯一个个打点函数效率上提高了。
这个是之前打点函数一个个打点的。
int32_t x;
int32_t y;
for(y = area->y1; y <= area->y2; y++) {
for(x = area->x1; x <= area->x2; x++) {
/*Put a pixel to the display. For example:*/
/*put_px(x, y, *color_p)*/
LCD_DrawPoint(x,y,(uint16_t)color_p->full);
color_p++;
}
在index文件里修改你的输入设配(触摸屏)的反馈信息
先将不要的输入设配注释或删除掉(如键盘鼠标编码器)
首先先初始化电容触摸平
、
随后将按键的扫描函数加入到lvgl自身的输入设备检测函数中
/*Will be called by the library to read the touchpad*/
static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
static lv_coord_t last_x = 0;
static lv_coord_t last_y = 0;
// lv_coord_t chickx=TOUCH_GetX();
// lv_coord_t chicky=TOUCH_GetY();
/*Save the pressed coordinates and the state*/
//从扫描函数取X Y坐标 /* 触摸屏 */
if(tp_dev.scan(0))
{
last_x=(int16_t)tp_dev.x[0];
last_y=(int16_t)tp_dev.y[0];
data->point.x=last_x;
data->point.y=last_y;
data->state=LV_INDEV_STATE_PR;
}
else{
data->point.x=last_x;
data->point.y=last_y;
data->state=LV_INDEV_STATE_REL;
}
// if(touchpad_is_pressed()) {
// touchpad_get_xy(&last_x, &last_y);
// data->state = LV_INDEV_STATE_PR;
// } else {
// data->state = LV_INDEV_STATE_REL;
// }
// /*Set the last pressed coordinates*/
// data->point.x = last_x;
// data->point.y = last_y;
}
/*Return true is the touchpad is pressed*/
static bool touchpad_is_pressed(void)
{
/*Your code comes here*/
tp_dev.scan(0); //从扫描函数取X Y坐标 /* 触摸屏 */
// if(TOUCH_PenInt())
// {
// return true;
// }
return false;
}
///*Get the x and y coordinates if the touchpad is pressed*/
static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
{
/*Your code comes here*/
(*x) = 0;
(*y) = 0;
}
至此lcd的触摸输入设备和显示设备已经移植完成 。
2.4.2 初始化lvgl的时基
将sysick的中断优先级提高至较高级。并在systick的中断中添加lvgl的时基(也即是节拍心跳)设置为1ms一个节拍。
2.5 编写示例应用程序
在main函数中先初始化 lvgl和相应输入输出设备。
在对应的while循环中加入他的回调机制相关的处理函数。
这样lvgl基本移植完成。
2.6 编译和调试
编写一个按钮(与c语言hello world一样的重要!!!)
一般我们会另外创建ui的.c与.h文件进行ui的规范编写,但这里仅仅是测试所以我们直接在main函数里完成。
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_TIM3_Init();
MX_TIM4_Init();
MX_USART2_UART_Init();
MX_RTC_Init();
MX_IWDG_Init();
/* USER CODE BEGIN 2 */
lv_obj_t* button =lv_btn_create(lv_scr_act());
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// if(lv_disp_get_inactive_time(NULL)<3000)
lv_timer_handler();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
正常你因该会看到一个左上角的按钮部件并且点击屏幕可以切换状态。
点击后
最后附带本次的lcd和触摸屏的相关文件
链接:https://pan.baidu.com/s/1XuH02Gc9gF95mB81ey6r0A
提取码:rxre
2.7 本章小结
通过本章的学习,我们成功地将在STM32上移植了LVGL图形库,并且创建了一个基本的图形界面。现在,你应该具备了在STM32平台上使用LVGL进行图形设计的基础能力。在接下来的章节中,我们将进一步探索LVGL的高级功能和应用。
作者:@碌碌有为