【STM32】litleVGL实例教程------任务系统

欢迎来到矽芯硬翌的科技主义教室!

记录STM32入土路上的艰苦旅程,加油UPUPUP
@Author: 矽芯硬翌!
👇 想要我的财宝吗?想要的话可以全部给你,去找出来吧,这世上所有的一切都在那里! 👇
ONE PIECE地址:矽芯硬翌的博客


前言

记录一下学习STM32GUI的路程,也是为了自己以后可以快速翻阅代码查漏补缺 加油
以下是介绍littleVGL的任务系统,下面案例可供参考

一、littleVGL任务系统

  • littleVGL 的任务管理系统类似于软件定时器,他们俩者之间具有许多相同的特性。,它支持6个任务优先级,高优先级的任务可以抢占低优先级的任务,注意,此任务管理系统是非实时的,因为任务的时效性是取决于 lv_task_handler()函数的调用,而 lv_task_handler()函数一般放在 main 函数主循环中进行调用,所以你也要确保 main 函数主循环中不能有其他过大的延时存在。
  • littleVGL 的任务管理系统主要是由 3 个数据类型和 13 个 API 接口组成的

二、主要的数据类型

2.1 任务优先级数据类型

下面是任务优先级数据类型:

在这里插入图片描述


2.2 任务管理句柄数据类型

lv_task_t 是任务句柄数据类型,也可以说是任务对象数据类型,俩者的意思是一样的,只是不同的叫法,以后我统统以句柄为例,我们一般是不直接修改 lv_task_t 句柄的属性的,都是通过其他的 API 接口来操作的。

下面是任务优先级数据类型:

当我们知道PWM的计算方法之后,该怎么使用这脉宽调制来控制舵机呢?实际上只要只要控制好PWM的占空比就可以驱动舵机了(PS:具体可以通过搜索你使用舵机的型号,查阅手册得到具体的占空比要求)


三、API接口

  • 事务处理器lv_task_handler(void);
    lv_task_handler 这个 API 接口是非常重要的,littleVGL 内部的所有事务都是通过这个接口来处理的,所以我称它为事务处理器,它需要不断的被周期性调用,我们通常把它放到 main 函数的主循环中去。
  • 创建任务lv_task_t * lv_task_create(lv_task_cb_t task_xcb, uint32_t period, lv_task_prio_t prio, void * user_data);参考lv_task_t基本数据类型
    创建任务一般都是通过这个API接口来进行的,可以一步到位,其实 lv_task_create 的实现原理是先通过调用 lv_task_create_basic 来创建最基本的任务,然后再通过其他的 API 接口来对其进行属性设置。
  • 删除任务void lv_task_del(lv_task_t * task);
    当我们不需要某任务时,需要通过此接口来删除任务,释放在堆上占用的资源。
  • 设置任务回调函数void lv_task_set_cb(lv_task_t * task, lv_task_cb_t task_cb);
    一般不常用,除非你的项目有动态修改回调函数的需求
  • 使任务立即准备就绪void lv_task_ready(lv_task_t * task);
    通过调用此 API 接口,我们可以使刚创建出来的任务立即处于就绪状态,然后在下一个lv_task_handler 调用时,使任务回调函数立即得到运行,而不用去等它的第一个运行周期,注意了这里说的是第一个周期不用等了,但是后面的周期还是要等的。
  • 使任务回调函数只运行一次void lv_task_once(lv_task_t * task);
    通过调用此 API 接口,我们可以让任务的回调函数只运行一次,而非周期性调用,在一次调用完成之后,littleVGL 内部会通过 lv_task_del 接口来自动删除此任务的。
  • 复位任务void lv_task_reset(lv_task_t * task);
    举个例子来方便理解,假如任务 A 的回调周期是 1000ms,现在已经等待了 300ms,按理来说还需等待 700ms,任务 A 的回调函数才会被运行,但是如果此时使用 lv_task_reset 接口来复位任务 A 的话,那么之前等待的 300ms 会被作废,而是重新开始等待一个 1000ms 的完整周期。

四、示例代码

任务系统配置:

#include "task_test.h"
#include "lvgl.h"
#include "key.h"
#include "beep.h"
#include "usart.h"
#include "delay.h"
/*
 * 
 *    ┏┓   ┏┓
 *  ┏┛┻━━━┛┻┓
 *  ┃       ┃
 *  ┃   ━   ┃
 *  ┃ >   < ┃
 *  ┃       ┃
 *  ┃... ⌒ ... ┃
 *  ┃       ┃
 *  ┗━┓   ┏━┛
 *      ┃   ┃ 
 *      ┃   ┃
 *      ┃   ┃
 *      ┃   ┃  神兽保佑
 *      ┃   ┃  代码无bug  
 *      ┃   ┃
 *      ┃   ┗━━━┓
 *      ┃       ┣┓
 *      ┃       ┏┛
 *      ┗┓┓┏━┳┓┏┛
 *        ┃┫┫ ┃┫┫
 *        ┗┻┛ ┗┻┛
 */
typedef struct{
	char name[20];
	u8 age;
}USER_DATA;


lv_task_t *task1 = NULL;//任务句柄指针
USER_DATA user_data = { //user_data为用户自定义参数,数据结构一般为结构体
	.name = {"xiong jia yu"},
	.age = 25
};  //结构体初始化

//任务回调函数
void task1_cb(lv_task_t* task)
{
	USER_DATA* dat = (USER_DATA*)(task->user_data);//获取用户的自定义参数
	
	//打印tick时间(一个tick为1ms)和用户自定义参数
	printf("task1_cb_tick:%d,name:%s,age:%d\r\n",lv_tick_get(),dat->name,dat->age);
	
	//蜂鸣器鸣叫20ms进行提示
	BEEP = 1;
	delay_ms(30);
	BEEP = 0;
}

//例程入口函数
void task_test_start()
{
	//创建task1任务
	task1 = lv_task_create(task1_cb,5000,LV_TASK_PRIO_MID,&user_data);
}


//按键处理
void key_handler()
{
	u8 key = KEY_Scan(0);
	
	if(task1==NULL)
		return;
	if(key==KEY0_PRES)
	{
		//使任务复位,如果你以固定的时间间隔不断的重复按下KEY0键(间隔时间要小于5000ms的回调周期),
		//你会发现task1_cb回调函数再也得不到运行了,因为task1任务在被重复性的复位,
		//每一次复位将会导致重新等待一个完整的回调周期
		lv_task_reset(task1);
		printf("task_reset_tick:%d\r\n",lv_tick_get());
	}else if(key==KEY1_PRES)
	{
		//使任务立即准备就绪,当你按下KEY1键时,你会发现task1_cb回调函数会在下一个lv_task_handler调用时被立即运行,
		//通过串口打印,你会发现task_ready_tick的值比task1_cb_tick的值只小几个数
		lv_task_ready(task1);
		printf("task_ready_tick:%d\r\n",lv_tick_get());
	}else if(key==WKUP_PRES)//删除任务
	{
		//删除任务,当你按下KEY2键后,你会发现task1_cb回调函数将永远不会再被执行了
		lv_task_del(task1);
		task1 = NULL;
		printf("task_del_tick:%d\r\n",lv_tick_get());
	}
}


main.c:
/*
 * @Author: your name
 * @Date: 2020-09-08 20:28:51
 * @LastEditTime: 2020-09-09 10:06:10
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \USER\main.c
 */
#include "led.h"
#include "delay.h"
#include "key.h"
#include "beep.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"	 
#include "24cxx.h"
#include "w25qxx.h"
#include "touch.h"
#include "timer.h"
#include "lvgl.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"
#include "task_test.h" 


int main(void)
{	 		    
	delay_init();	    	 				//延时函数初始化	  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 				//串口初始化为115200
	 
 	LED_Init();			     				//LED端口初始化
	BEEP_Init();								//蜂鸣器初始化
	LCD_Init();					 				//LCD液晶初始化
	KEY_Init();	 				 				//按键初始化
	TIM3_Int_Init(999,71);		 	//定时器初始化(1ms中断),用于给lvgl提供心跳节拍	
 	tp_dev.init();							//触摸初始化
	 
	lv_init();									//lvgl系统初始化
	lv_port_disp_init();				//lvgl显示接口初始化,放在lv_init()的后面
	lv_port_indev_init();				//lvgl输入接口初始化,放在lv_init()的后面
	
	task_test_start();					//运行例程
	
	while(1)
	{
		tp_dev.scan(0);//触摸扫描
		lv_task_handler();//lvgl的事务处理
		key_handler();//按键处理
	}
}
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值