当前位置: 首页 > news >正文

学习空闲任务函数

一、user_StopEnterTask 停止 进入任务

/* Private includes -----------------------------------------------------------*/
//includes
#include "user_TasksInit.h"
#include "user_MPUCheckTask.h"#include "ui.h"
#include "ui_HomePage.h"
#include "ui_OffTimePage.h"#include "main.h"
#include "stm32f4xx_it.h"
#include "lcd_init.h"
#include "CST816.h"
#include "key.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/
uint16_t IdleTimerCount = 0;/* Private function prototypes -----------------------------------------------*//* Tasks ---------------------------------------------------------------------*//*** @brief  Enter Idle state* @param  argument: Not used* @retval None*/
void IdleEnterTask(void *argument)
{uint8_t Idlestr=0;uint8_t IdleBreakstr=0;while(1){//light get darkif(osMessageQueueGet(Idle_MessageQueue,&Idlestr,NULL,1)==osOK){LCD_Set_Light(5);}//resume light if light got dark and idle state breaked by key pressing or screen touchingif(osMessageQueueGet(IdleBreak_MessageQueue,&IdleBreakstr,NULL,1)==osOK){IdleTimerCount = 0;LCD_Set_Light(ui_LightSliderValue);}osDelay(10);}
}/*** @brief  enter the stop mode and resume* @param  argument: Not used* @retval None*/
void StopEnterTask(void *argument)
{uint8_t Stopstr;uint8_t HomeUpdataStr;uint8_t Wrist_Flag=0;while(1){if(osMessageQueueGet(Stop_MessageQueue,&Stopstr,NULL,0)==osOK){/***** your sleep operations *****/sleep:IdleTimerCount = 0;//sensors//lcdLCD_RES_Clr();LCD_Close_Light();//touchCST816_Sleep();/*********************************/vTaskSuspendAll();//Disnable Watch Dog//WDOG_Disnable();//systick intCLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);//enter stop modeHAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFI);//here is the sleep period//resume run mode and reset the sysclkSET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq));SystemClock_Config();//WDOG_Feed();xTaskResumeAll();/***** your wakeup operations *****//*//MPU Checkif(user_MPU_Wrist_EN){uint8_t hor;hor = MPU_isHorizontal();if(hor && user_MPU_Wrist_State == WRIST_DOWN){user_MPU_Wrist_State = WRIST_UP;Wrist_Flag = 1;//resume, go on}else if(!hor && user_MPU_Wrist_State == WRIST_UP){user_MPU_Wrist_State = WRIST_DOWN;IdleTimerCount  = 0;goto sleep;}}*///if(!KEY1 || HardInt_Charg_flag || Wrist_Flag){Wrist_Flag = 0;//resume, go on}else{IdleTimerCount  = 0;goto sleep;}//lcdLCD_Init();LCD_Set_Light(ui_LightSliderValue);//touchCST816_Wakeup();//check if is Charging/*if(ChargeCheck()){HardInt_Charg_flag = 1;}*///send the Home Updata messageosMessageQueuePut(HomeUpdata_MessageQueue, &HomeUpdataStr, 0, 1);/**********************************/}osDelay(100);}
}void IdleTimerCallback(void *argument)
{IdleTimerCount+=1;//make sure the LightOffTime<TurnOffTimeif(IdleTimerCount == (ui_LTimeValue*10)){uint8_t Idlestr=0;//send the Light off messageosMessageQueuePut(Idle_MessageQueue, &Idlestr, 0, 1);}if(IdleTimerCount == (ui_TTimeValue*10)){uint8_t Stopstr = 1;IdleTimerCount  = 0;//send the Stop messageosMessageQueuePut(Stop_MessageQueue, &Stopstr, 0, 1);}
}

1.1 头文件包含部分

#include "user_TasksInit.h"
#include "user_MPUCheckTask.h"#include "ui.h"
#include "ui_HomePage.h"
#include "ui_OffTimePage.h"#include "main.h"
#include "stm32f4xx_it.h"
#include "lcd_init.h"
#include "CST816.h"
#include "key.h"

user_TasksInit.h 包含了任务初始化相关的函数声明、结构体等,用于初始化整个系统中的各种任务,确保各个任务能正常启动和运行

user_MPUCheckTask.h 应该是检查MPU6050 核心板没用到

ui.hui_HomePage.hui_OffTimePage.h 这些头文件应该是和用户界面不同页面相关的定义

main.h 通常包含主程序模块相关的一些通用定义,例如全局变量声明、主函数中使用到的宏等。

stm32f4xx_it.h 一般是 STM32F4 系列单片机的中断相关的头文件,可能包含了中断服务函数的声明以及一些与中断处理相关的宏定义等内容,用于处理单片机的各种中断事件。

lcd_init.h 应该是与 LCD 显示屏初始化及相关操作有关的头文件,里面会有 LCD 初始化函数(如 LCD_Init)以及亮度设置函数(如 LCD_Set_Light)等的声明,用于控制显示屏的显示状态。

CST816.h 推测是与触摸传感器(可能是型号为 CST816 的触摸芯片)相关的头文件,包含触摸传感器的操作函数声明,如睡眠(CST816_Sleep)、唤醒(CST816_Wakeup等函数,用于管理触摸功能的开启和关闭。

key.h 很可能包含了按键相关的函数声明,像按键扫描函数等,以及按键引脚定义等与硬件按键相关的内容,用于检测按键操作情况。

uint16_t IdleTimerCount = 0;

定义了一个 uint16_t 类型的全局变量 IdleTimerCount,初始值设为 0。从后续代码来看,这个变量用于计时,可能是记录设备处于空闲状态的时长,通过与不同的时间阈值(如 ui_LTimeValue 和 ui_TTimeValue)进行比较,来决定是否执行相应的操作,比如关闭屏幕灯光或者进入停止模式等

1.2 IdleEnterTask函数 空闲任务(用于调节屏幕亮度)

void IdleEnterTask(void *argument)
{uint8_t Idlestr = 0;uint8_t IdleBreakstr = 0;while (1){//light get darkif (osMessageQueueGet(Idle_MessageQueue, &Idlestr, NULL, 1) == osOK){LCD_Set_Light(5);}//resume light if light got dark and idle state breaked by key pressing or screen touchingif (osMessageQueueGet(IdleBreak_MessageQueue, &IdleBreakstr, NULL, 1) == osOK){IdleTimerCount = 0;LCD_Set_Light(ui_LightSliderValue);}osDelay(10);}
}

定义了两个 uint8_t 类型的局部变量 Idlestr 和 IdleBreakstr,初始值都设为 0,它们可能用于接收来自消息队列的相关消息内容,以判断设备的状态变化情况。

当通过 osMessageQueueGet 函数从 Idle_MessageQueue 消息队列中成功获取到消息(返回值为 osOK)时,会执行 LCD_Set_Light(5) 语句,即将 LCD 的亮度设置为 5,这可能表示在接收到特定的空闲相关消息后,调暗屏幕亮度,使屏幕灯光变暗(具体亮度值的含义取决于 LCD_Set_Light 函数的实现和项目中的亮度设定标准)。

当从 IdleBreak_MessageQueue 消息队列中成功获取到消息时,首先将 IdleTimerCount 清零,意味着设备的空闲计时重新开始,然后通过 LCD_Set_Light(ui_LightSliderValue) 将 LCD 的亮度设置为用户界面上设置的亮度滑块值所对应的亮度,这表示当设备从空闲被打断(比如通过按键按下或者屏幕触摸操作)后,恢复屏幕到之前用户设定的亮度

我理解的是一个消息队列用于使屏幕变暗,估计是osMessageQueueGet 获得值,另一个消息队列是用于触发唤醒屏幕。进入空闲状态就息屏省电

1.3 StopEnterTask 函数 

定义了三个 uint8_t 类型的局部变量 StopstrHomeUpdataStr 和 Wrist_Flag,分别用于接收消息队列中的消息、可能用于后续向其他任务发送更新首页相关的消息以及作为一个标志来记录与设备姿态(手腕相关,从代码中对 MPU 和手腕状态的处理推测)有关的情况,初始时 Wrist_Flag 设为 0

 if (osMessageQueueGet(Stop_MessageQueue, &Stopstr, NULL, 0) == osOK)

同样是一个无限循环 while(1)持续检测 Stop_MessageQueue 消息队列中的消息,以决定是否进入停止模式以及后续的唤醒操作等相关处理。

这里有个sleep 估计是要用到goto语句吗?

sleep:IdleTimerCount = 0;//sensors//lcdLCD_RES_Clr();LCD_Close_Light();//touchCST816_Sleep();/*********************************/vTaskSuspendAll();//Disnable Watch Dog//WDOG_Disnable();//systick intCLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);//enter stop modeHAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);//here is the sleep period//resume run mode and reset the sysclkSET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq));SystemClock_Config();//WDOG_Feed();xTaskResumeAll();

先将 IdleTimerCount 清零,用于重置空闲计时(因为即将进入停止模式,相当于空闲状态结束)。然后对各个硬件设备进行相应的关闭或睡眠操作,包括对 LCD 显示屏进行复位引脚操作(LCD_RES_Clr)和关闭灯光(LCD_Close_Light),以及让触摸传感器进入睡眠模式(CST816_Sleep),这些操作都是为了降低设备在停止模式下的功耗。

通过 vTaskSuspendAll 函数暂停所有任务(在支持任务管理的操作系统环境下),接着进行一些与系统时钟和看门狗相关的操作(虽然部分代码被注释掉了,像禁用看门狗 WDOG_Disnable,但整体思路是进行进入停止模式前的系统准备工作),然后通过 CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk) 操作关闭系统滴答定时器中断(SysTick 相关操作),最后使用 HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI) 函数进入停止模式(这里选择了主调节器开启以及等待中断唤醒的方式进入停止模式,具体的电源模式和唤醒方式可根据实际硬件和项目需求选择)。

 /***** your wakeup operations *****//*//MPU Checkif (user_MPU_Wrist_EN){uint8_t hor;hor = MPU_isHorizontal();if (hor && user_MPU_Wrist_State == WRIST_DOWN){user_MPU_Wrist_State = WRIST_UP;Wrist_Flag = 1;//resume, go on}else if (!hor && user_MPU_Wrist_State == WRIST_UP){user_MPU_Wrist_State = WRIST_DOWN;IdleTimerCount = 0;goto sleep;}}*///if (!KEY1 || HardInt_Charg_flag || Wrist_Flag){Wrist_Flag = 0;//resume, go on}else{IdleTimerCount = 0;goto sleep;}//lcdLCD_Init();LCD_Set_Light(ui_LightSliderValue);//touchCST816_Wakeup();//check if is Charging/*if (ChargeCheck()){HardInt_Charg_flag = 1;}*///send the Home Updata messageosMessageQueuePut(HomeUpdata_MessageQueue, &HomeUpdataStr, 0, 1);/**********************************/

这里有一部分代码被注释掉了,原本是关于 MPU(根据陀螺仪,可能用于检测设备姿态,比如手腕是朝上还是朝下)的检测逻辑,根据 MPU 检测到的设备水平状态以及之前记录的手腕状态(user_MPU_Wrist_State,虽然其赋值等操作在当前代码片段不太完整)来决定是否更新手腕状态标志以及是否再次进入睡眠(通过 goto sleep 语句)。
之后的代码根据不同条件判断来决定是否继续执行后续操作还是再次进入睡眠(通过判断按键 KEY1 是否按下充电标志 HardInt_Charg_flag 是否为真以及 Wrist_Flag 的值等情况)。如果满足相应条件(比如按键按下或者正在充电等),则将 Wrist_Flag 清零,准备继续正常运行;否则,将 IdleTimerCount 清零并通过 goto sleep 语句再次进入停止模式相关的睡眠操作。

最后,对硬件设备进行重新初始化和唤醒操作,包括初始化 LCD 显示屏(LCD_Init)并设置其亮度为用户界面设定的亮度值(LCD_Set_Light(ui_LightSliderValue)),唤醒触摸传感器(CST816_Wakeup),并且可以根据需要检查设备是否正在充电(代码中相关部分被注释掉了),

最后通过 osMessageQueuePut 函数向 HomeUpdata_MessageQueue 消息队列发送一个消息(具体消息内容通过 HomeUpdataStr 传递,虽然目前代码中没有对其进行详细赋值等操作,但应该是用于通知其他任务首页相关的更新情况)。

 osDelay(100);

在循环的末尾通过 osDelay(100) 函数让任务暂停 100 个时间单位(同样具体时间单位取决于操作系统配置),以合适的时间间隔来检测 Stop_MessageQueue 消息队列,避免过于频繁检测而占用过多资源,同时也能及时响应进入停止模式的相关消息

1.4 IdleTimerCallback 空闲时间回调函数

void IdleTimerCallback(void *argument)
{IdleTimerCount += 1;//make sure the LightOffTime<TurnOffTimeif (IdleTimerCount == (ui_LTimeValue * 10)){uint8_t Idlestr = 0;//send the Light off messageosMessageQueuePut(Idle_MessageQueue, &Idlestr, 0, 1);}if (IdleTimerCount == (ui_TTimeValue * 10)){uint8_t Stopstr = 1;IdleTimerCount = 0;//send the Stop messageosMessageQueuePut(Stop_MessageQueue, &Stopstr, 0, 1);}
}

函数每次被调用时,会将 IdleTimerCount 变量的值加 1,用于对设备处于空闲状态的时长进行计时。然后通过两个 if 条件判断来决定是否发送相应的消息
当 IdleTimerCount 的值等于 ui_LTimeValue 乘以 10 时(这里乘以 10 可能是因为计时单位和时间阈值的单位换算关系,具体取决于项目设定),会定义一个 uint8_t 类型变量 Idlestr 并初始化为 0,然后通过 osMessageQueuePut 函数向 Idle_MessageQueue 消息队列发送这个消息,这可能是用于触发屏幕灯光调暗等相关的空闲操作(从 IdleEnterTask 函数中对 Idle_MessageQueue 消息的处理逻辑可推测)。
当 IdleTimerCount 的值等于 ui_TTimeValue 乘以 10 时,定义一个 uint8_t 类型变量 Stopstr 并赋值为 1,接着将 IdleTimerCount 清零,再通过 osMessageQueuePut 函数向 Stop_MessageQueue 消息队列发送这个消息,这大概率是用于触发设备进入停止模式相关的操作(从 StopEnterTask 函数中对 Stop_MessageQueue 消息的处理逻辑可推测)

在空闲任务里的时常为 time1时间不操作就进入低亮度状态, 长时间 time2 不操作就进入停止状态,

回调函数作为重复启用的软件定时器的函数  100ms启用1次 也就是100ms计数值自加一次

osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {


 

uint8_t ui_LTimeValue = 10;if(IdleTimerCount == (ui_LTimeValue*10))

那ui_LTimeValue*10 = 100 那就是100ms*100=10s 10s空闲任务时间  就会让系统进入降低显示器屏幕的状态,15s进入关断状态 只能由按键 姿态 充电唤醒

http://www.lryc.cn/news/486688.html

相关文章:

  • Hyper-v中ubuntu与windows文件共享
  • 【软件工程】一篇入门UML建模图(类图)
  • Windows 安装Docker For Desktop概要
  • 解决循环依赖报错问题
  • 代码随想录第46期 单调栈
  • 中仕公考怎么样?事业编面试不去有影响吗?
  • OMV7 树莓派 tf卡安装
  • Go语言24小时极速学习教程(五)Go语言中的SpringMVC框架——Gin
  • 【汇编】c++游戏开发
  • Android Studio | 修改镜像地址为阿里云镜像地址,启动App
  • Rocky linux8 安装php8.0
  • Ubuntu 18 EDK2 环境编译
  • C语言项⽬实践-贪吃蛇
  • 智慧安防丨以科技之力,筑起防范人贩的铜墙铁壁
  • Spring:IoC/DI加载properties文件
  • Docker 篇-Docker 详细安装、了解和使用 Docker 核心功能(数据卷、自定义镜像 Dockerfile、网络)
  • 深挖C++赋值
  • 【免越狱】iOS砸壳 可下载AppStore任意版本 旧版本IPA下载
  • 【python笔记02】面向对象思想
  • Java基础-Java多线程机制
  • MySQL技巧之跨服务器数据查询:基础篇-A数据库与B数据库查询合并--封装到存储过程中
  • MATLAB向量元素的引用
  • leetcode-44-通配符匹配
  • 基于YOLOv8深度学习的智慧课堂学生专注度检测系统(PyQt5界面+数据集+训练代码)
  • vue项目使用eslint+prettier管理项目格式化
  • Java基础-组件及事件处理(中)
  • UNIX网络编程-TCP套接字编程(实战)
  • python编写一个自动清理三个月以前的邮件脚本
  • C++组合复用中,委托的含义与作用
  • 自制C++游戏头文件:C++自己的游戏头文件!!!(后续会更新)