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

FreeRTOS与软件定时器(七)

一、软件定时器介绍

1.1 介绍

软件定时器分两种类型:一次性定时器周期性定时器

一次性定时器:启动后,到达设定时间触发一次回调,之后自动停止。(如定时器按键)

周期性定时器:启动后,每隔设定时间触发一次回调,循环执行。(如周期性采集数据)

软件定时器和硬件定时器的功能一样,都是定时器,只不过软件定时器是基于FreeRTOS心跳基准(比如滴答定时器)软件编写的定时器功能

软件定时器实际工程场景:周期性数据采集、设备初始化延时、通信超时检测等典型应用等。

软件定时器需要用到回调函数,本质上软件定时器回调函数也是一个系统性任务,他和Task任务稍有不同,软件定时器更注重周期性的运行。与Task任务相比,软件定时器比Task任务更适合传感器周期性采集数据。且回调函数不能使用阻塞 API(如vTaskDelayqueueReceive),否则会阻塞整个定时器服务。

1.2 在实际开发中,什么时候用"软件定时器"方案,什么时候用"任务 +vTaskDelay"方案好?

简单的、周期性的事情用软件定时器方案

当定时触发的操作逻辑复杂、耗时较长,或需要灵活调整周期时,用“任务 +vTaskDelay” 方案

并且资源占用上:

软件定时器方案:一个定时器句柄(约几十字节)+ 定时器服务任务栈(固定)。

任务 +vTaskDelay”方案:一个任务的独立栈空间(每个通常几百字节,总和更大)

1.3 在实际开发中,工程师们是如何协调使用软件定时器和任务之间的运行的?

核心原则:分离 “触发” 与 “处理”

软件定时器的核心职责是按时间触发事件(轻量操作),而复杂逻辑(如数据处理、外设控制、网络交互等)必须交给独立任务处理。两者通过 IPC 机制(队列、信号量、事件标志组等)衔接,形成 “定时器回调发通知→任务等通知并处理” 的协作模式。

实际开发中的 “混合用法”:

多数工程中两者是配合使用的,例如:

  • 用软件定时器(1 秒周期)触发 “传感器原始数据读取”(轻量操作),回调中通过消息队列将数据发给 “数据处理任务”;

  • “数据处理任务”(用vTaskDelay控制 10 秒周期)从队列中取数据,执行滤波、校准、计算等复杂操作,再上传到云端。

由于内容并不复杂,接下来直接讲软件定时器的例程,通过看例程学习软件定时器相关的API函数

二、软件定时器例程

定义结构体和变量

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>// 全局变量:存储传感器数据
float g_temperature = 0.0f;  // 温度
float g_humidity = 0.0f;     // 湿度
uint8_t g_device_status = 0; // 设备状态(0-正常,1-异常)// 定时器句柄(用于操作定时器)
TimerHandle_t xSensorTimer;   // 传感器采集定时器
TimerHandle_t xReportTimer;   // 数据上报定时器
TimerHandle_t xCheckTimer;    // 状态检查定时器

创建任务

创建三个软件定时器,并使用了3个定时器回调函数

/*** @brief 传感器采集定时器回调函数(每2秒执行一次)* 功能:模拟读取温湿度传感器数据*/
void vSensorTimerCallback(TimerHandle_t xTimer)
{g_temperature = Read_TempVal();//读取传感器温度值g_humidity = Read_HumiVal();//读取传感器湿度值printf("[传感器采集] 温度: %.1f℃, 湿度: %.1f%%\r\n", g_temperature, g_humidity);
}/*** @brief 数据上报定时器回调函数(每10秒执行一次)* 功能:将采集的温湿度数据上报到服务器*/
void vReportTimerCallback(TimerHandle_t xTimer)
{// 实际工程中这里会通过网络(WiFi/4G等)发送数据printf("\r\n[数据上报] 开始向服务器上报数据...\r\n");printf("[数据上报] 上报内容:温度=%.1f℃, 湿度=%.1f%%, 设备状态=%s\r\n",g_temperature, g_humidity, (g_device_status == 0) ? "正常" : "异常");printf("[数据上报] 上报完成!\r\n\r\n");
}/*** @brief 状态检查定时器回调函数(每5秒执行一次)* 功能:检查设备运行状态(如电源、网络)*/
void vCheckTimerCallback(TimerHandle_t xTimer)
{// 这里随机模拟偶尔出现异常(10%概率)if(rand() % 10 < 1){g_device_status = 1; // 异常printf("[状态检查] 警告:设备状态异常!\r\n");}else{g_device_status = 0; // 正常printf("[状态检查] 设备运行正常\r\n");}
}

main函数

int main(void)
{BSP_Init();//环境监测设备初始化// 2. 创建软件定时器// 参数说明:定时器名称、周期(ms)、是否自动重载、定时器ID、回调函数xTimerCreate("SensorTimer",       // 定时器名称(调试用)pdMS_TO_TICKS(2000), // 周期2000mspdTRUE,              // 自动重载(周期性执行)NULL,                // 不需要IDvSensorTimerCallback // 回调函数);xTimerCreate("ReportTimer",pdMS_TO_TICKS(10000), // 周期10000mspdTRUE,NULL,vReportTimerCallback);xTimerCreate("CheckTimer",pdMS_TO_TICKS(5000),  // 周期5000mspdTRUE,NULL,vCheckTimerCallback);// 3.启动定时器(从现在开始计时)// 参数:定时器句柄、阻塞时间(0表示不阻塞)xTimerStart(xSensorTimer, 0);xTimerStart(xReportTimer, 0);xTimerStart(xCheckTimer, 0);}// 启动调度器vTaskStartScheduler();return 0;
}

三、总结

看了一遍例程和例程注释,对软件定时器的API函数有一定的认识了

这个例程是不是很像我们之前刚学创建Task任务时的写法?没错,这俩玩意是一样的逻辑。

和我开篇说的一样:

软件定时器回调函数与任务中间的"桥梁"用IPC机制联系通信

简单的、周期性的事情用软件定时器方案

当定时触发的操作逻辑复杂、耗时较长,或需要灵活调整周期时,用“任务 +vTaskDelay” 方案

http://www.dtcms.com/a/455262.html

相关文章:

  • 什么网站可以做问卷扬州做网站的
  • 实惠的网站建设做网站需要找人优化吗
  • 做图片视频的网站建设网站要什么资料
  • 苏州做网站品牌公司假网站怎么做
  • 怎么查看网站是哪家公司做的php网站后台上传图片有没有推荐到首页的功能
  • 体育馆路网站建设qq网站 直接登录
  • MySQL表的操作:创建—修改—删除流程解析
  • 网站专题方案工程建设标准网站
  • 企业网站建设 调研芜湖市建设厅网站
  • 使用Xenon工具搭建高可用MySQL集群实战(上)
  • MySQL包安装 -- Debian系列(离线DEB包安装MySQL)
  • 有哪些网站建设的方法做母婴网站赚钱
  • 想把公司的外部网站替换东营建设信息网(东营市住房和城乡建设局)
  • 做旅游广告在哪个网站做效果好国外素材网站
  • 网站设计怎么收费网站空间代理加盟
  • 网站制作现状解决方案域名反查网站
  • 河北建设厅官网站首页北京服装设计公司前十名
  • 做网站是什么软件seo快速排名利器
  • 主要网站 开发语言教做衣服网站
  • 深圳网站制作07551python做网站的书
  • 完整网站开发看什么书wordpress做成公众号
  • 合肥企业建站系统模板免费黄页营销网站
  • 网站的ftp怎么登陆做房地产一级市场的看什么网站
  • 外贸企业网站系统源码代前导页的网站
  • 网站外部链接如何建设网站建设与推广方案
  • 新洲建设投标网站网站建设国标行业分类
  • 平安保险网站官方网址做健身网站步骤
  • 怎么给一个网站做seo智联招聘网站怎么做微招聘
  • 网页模板网站互联网平台有哪些
  • 可以免费下源码的网站电商网站首页图片