定时器的理论和使用
文章目录
- 一、定时器理论
- 1.1定时器创建和使用
- 二、定时器实践
- 2.1周期触发定时器
- 2.2按键消抖
一、定时器理论
定时器是一种允许在特定时间间隔后或在将来的某个时间点调用回调函数的机制。对于需要周期性任务或延迟执行任务的嵌入式应用程序特别有用。
软件定时器: FreeRTOS 提供的用于实现定时操作的功能。与硬件定时器不同,软件定时器在 FreeRTOS 的任务调度机制之上运行。
定时器回调函数: 当定时器到期时,FreeRTOS 将调用用户定义的回调函数。
定时器类型分为以下两种:
一次性定时器(One-shot Timer):定时器在到期后自动停止,仅调用一次回调函数。
周期性定时器(Auto-reload Timer):定时器在到期后自动重新启动,周期性地调用回调函数。
1.1定时器创建和使用
回调函数
pxCallbackFunction可以使用pvTimerID分辨是哪个定时器
返回值: 成功则返回TimerHandle_t, 否则返回NULL
TimerHandle_t xTimerCreate( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction );
在RTOS中,每隔一个固定的时间产生中断,中断函数里面可以去判断定时器时间有没有超时,超时后就唤醒守护任务去执行回调函数
其他任务要配置和使用定时器时,是通过定时器命令队列(timer command queue)和守护任务交互,所以守护任务优先级要尽可能高

所以在启动定时器要有一个
xTicksToWait,当队列满了要设置等待时间
BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );
定时器状态:冬眠(Dormant)和运行(Running)、


二、定时器实践
2.1周期触发定时器
创建定时器
static TimerHandle_t xMyTimerHandle;xMyTimerHandle = xTimerCreate("mytimer", 100, pdTRUE, NULL, MyTimerCallbackFunction);
回调函数
void MyTimerCallbackFunction( TimerHandle_t xTimer )
{static int cnt = 0;flagTimer = !flagTimer;printf("MyTimerCallbackFunction_t cnt = %d\r\n", cnt++);
}
启动定时器:把命令通过 定时器队列 发给守护任务,由守护任务来启动定时器
void Task1Function(void * param)
{volatile int i = 0;xTimerStart(xMyTimerHandle, 0);while (1){printf("Task1Function ...\r\n");}
}
结果:每隔100ms进入回调函数


2.2按键消抖
在嵌入式开发中,我们使用机械开关时经常碰到抖动问题:引脚电平在短时间内反复变化。针对这个问题,我们在中断函数中添加定时器,在产生中断后定时器延时20ms,假如由于抖动再次进入中断,继续延时20ms直到按键趋于稳定。

创建定时器, 设置一次触发,延时20ms
static TimerHandle_t xMyTimerHandle;xMyTimerHandle = xTimerCreate("mytimer", 2000, pdFALSE, NULL, MyTimerCallbackFunction);
在回调函数中记录定时器中断次数
cnt
void MyTimerCallbackFunction( TimerHandle_t xTimer )
{static int cnt = 0;flagTimer = !flagTimer;printf("Get GPIO Key cnt = %d\r\n", cnt++);
}
按键中断函数中使用定时器消除抖动,通过复位函数
xTimerReset往定时器队列写入数据,由守护任务根据队列命令来复位定时器。在这里多次产生中断会多次调用复位函数xTimerReset。时间到达后进入回调函数
void EXTI0_IRQHandler(void)
{static int cnt = 0;if(EXTI_GetITStatus(EXTI_Line0) != RESET){printf("EXTI0_IRQHandler cnt = %d\r\n", cnt++);/* 使用定时器消除抖动 */xTimerReset(xMyTimerHandle, 0); /* Tcur + 2000 */EXTI_ClearITPendingBit(EXTI_Line0); //清除中断}
}
相关文章:
定时器的理论和使用
文章目录 一、定时器理论1.1定时器创建和使用 二、定时器实践2.1周期触发定时器2.2按键消抖 一、定时器理论 定时器是一种允许在特定时间间隔后或在将来的某个时间点调用回调函数的机制。对于需要周期性任务或延迟执行任务的嵌入式应用程序特别有用。 软件定时器: …...
【架构-17】通信系统架构设计理论
通信系统网络架构 1. 局域网网络架构 拓扑结构:星型、总线型、环型、树型。 网络架构:单核心架构(结构简单,地理范围受限)、双核心架构(网络拓扑结构可靠,投资较单核高)、环型架构…...
网络中的基本概念
网络初识 局域网:把若干个电脑组成在一起,通过路由器进行组网。 广域网:把局域网进一步的连接,构成更复杂的网络体系。 IP地址:区分主机。 端口号:区分主机上不同的程序。 协议:是一种约定&…...
手撸XXL-JOB(二)——定时任务管理
在上一节中,我们介绍了SpringBoot中关于定时任务的执行方式,以及ScheduledExecutorService接口提供的定时任务执行方法。假设我们现在要写类似XXL-JOB这样的任务调度平台,那么,对于任务的管理,是尤为重要的。接下来我们…...
DEV--C++小游戏(吃星星(0.2))
目录 吃星星(0.2) 简介 本次更新 分部代码 头文件(增) 命名空间变量(增) 副函数(新,增) 清屏函数 打印地图函数(增) 移动函数 选择颜色…...
Lua 协程池
协程池 在 使用 Lua 协程模拟 Golang 的 go defer 编程模式 中介绍了 Lua 协程的使用,模仿 golang 封装了下 还可以做进一步的优化 原来的 go 函数是这样实现的: function go(_co_task)local co coroutine.create(function(_co_wrap)_co_task(_co_w…...
[Linux][网络][协议技术][DNS][ICMP][ping][traceroute][NAT]详细讲解
目录 1.DNS1.DNS背景2.域名简介 2.ICMP协议1.ICMP功能2.ICMP两类报文 3.ping命令4.traceroute5.NAT技术1.NAT技术背景2.NAT IP转换过程3.静态地址NAT && 动态地址NAT4.网络地址端口转换NAPT5.NAT技术的缺陷6.NAT和代理服务器 6.总结1.数据链路层2.网络层3.传输层4.应用…...
Android 集成Bugly完成线上的异常Exception收集及处理
文章目录 (一)添加产品APP(二)集成SDK(三)参数配置权限混淆 (四)初始化 (一)添加产品APP 一)在个人头像 -> 我的头像 -> 新建产品 二&…...
Redis——Redis的数据库结构、删除策略及淘汰策略
Redis是一个高性能的key-value存储系统,它支持多种数据结构,并提供了丰富的删除策略和淘汰策略。以下是关于Redis的数据库结构、删除策略及淘汰策略的详细介绍: Redis的数据库结构 Redis是一个key-value数据库,数据存储是以一个…...
【Vue3笔记03】Vue3项目工程中使用vue-router路由
这篇文章,主要介绍Vue3项目工程中如何使用vue-router路由。 目录 一、vue-router路由 1.1、下载vue-router路由 1.2、创建router.js文件 1.3、main.js配置路由...
并行执行的4种类别——《OceanBase 并行执行》系列 4
OceanBase 支持多种类型语句的并行执行。在本篇博客中,我们将根据并行执行的不同类别,分别详细阐述:并行查询、并行数据操作语言(DML)、并行数据定义语言(DDL)以及并行 LOAD DATA 。 《并行执行…...
函数练习.
1.打印乘法口诀表 口诀表的行数和列数自己指定如:输入9,输出99口诀表,输出12,输出1212的乘法口诀表。 multiplication(int index) { if (index 9) { int i 0; for (i 1; i < 10; i) { int j 0; for (j 1; j &…...
Git 分支命令操作详解
目录 1、分支的特点 2、分支常用操作 3、分支的使用 3.1、查看分支 3.2、创建分支 3.3、修改分支 3.4、切换分支 3.5、合并分支 3.6、产生冲突 3.7、解决冲突 3.8、创建分支和切换分支说明 1、分支的特点 同时并行推进多个功能开发,提高开发效率。各个分…...
十二生肖Midjourney绘画大挑战:释放你的创意火花
随着AI艺术逐渐进入大众视野,使用Midjourney绘制十二生肖不仅能够激发我们的想象力,还能让我们与传统文化进行一场新式的对话。在这里,我们会逐一提供给你创意满满的绘画提示词,让你的作品别具一格。而且,我们还精选了…...
【C++】priority_queues(优先级队列)和反向迭代器适配器的实现
目录 一、 priority_queue1.priority_queue的介绍2.priority_queue的使用2.1、接口使用说明2.2、优先级队列的使用样例 3.priority_queue的底层实现3.1、库里面关于priority_queue的定义3.2、仿函数1.什么是仿函数?2.仿函数样例 3.3、实现优先级队列1. 1.0版本的实现…...
Go语言函数
在Go语言中,函数是一种基本的构建块,用于组织代码并执行特定任务。它们是可重复使用的代码段,可以接收输入参数,执行一系列操作,并可返回结果。以下是Go语言中函数的详细介绍及其使用方法: 基本语法 Go语…...
如何使用EasyExcel导入百万数据
摘要: 本文将详细探讨如何利用EasyExcel库,以及结合Java编程,高效地导入大规模数据至应用程序中。我们将逐步介绍导入流程、代码实现细节,并提供性能优化建议,旨在帮助读者在处理百万级别数据时,提高效率与…...
【解决】Unity Build 应用程序运行即崩溃问题
开发平台:Unity 2021.3.7f1c1 一、问题描述 编辑器 Build 工程结束,但控制台 未显示 Build completed with a result of Succeeded [时间长度] 信息。该情况下打包流程正常,但应用程序包打开即崩溃。 二、问题测试记录 测试1…...
C++数据结构——红黑树
前言:本篇文章我们继续来分享C中的另一个复杂数据结构——红黑树。 目录 一.红黑树概念 二.红黑树性质 三.红黑树实现 1.基本框架 2.插入 3.判断平衡 四.完整代码 总结 一.红黑树概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个…...
Java并发编程:学习路线图
文章目录 一、操作系统内核原理1、进程管理详解2、内存管理详解3、IO输入输出系统详解4、进程间通信机制详解5、网络通信原理剖析 二、Java内存模型三、并发集合1、Map(1)ConcurrentHashMap(2)ConcurrentSkipListMap 2、List&…...
tan(Π/2)是无定义的,为什么是无定义?
正弦函数 sin(θ) 和余弦函数 cos(θ) 确实定义在所有实数域上,包括任意角(正、负或零),因为它们的定义基于单位圆上的 y-坐标和 x-坐标,无论 θ 的值如何,都总有对应的值(范围在 [-1, 1] 内&am…...
Qwen3-ASR-0.6B真实效果:直播间弹幕语音→实时字幕滚动+敏感词过滤联动
Qwen3-ASR-0.6B真实效果:直播间弹幕语音→实时字幕滚动敏感词过滤联动 1. 开篇:直播间语音转文字的痛点 做直播的朋友都知道,实时字幕是个让人又爱又恨的功能。爱的是它能提升观众体验,让不方便开声音的人也能看懂内容ÿ…...
AI 模型推理性能瓶颈排查与分析
AI 模型推理性能瓶颈排查与分析 随着AI技术的广泛应用,模型推理性能成为影响实际落地的关键因素。无论是实时推荐系统还是自动驾驶,延迟或吞吐量不达标都可能导致业务损失。性能瓶颈往往隐藏于模型结构、硬件资源或数据处理流程中,需要系统化…...
实战指南:RegRipper3.0 Windows注册表深度取证分析完整方案
实战指南:RegRipper3.0 Windows注册表深度取证分析完整方案 【免费下载链接】RegRipper3.0 RegRipper3.0 项目地址: https://gitcode.com/gh_mirrors/re/RegRipper3.0 RegRipper3.0 是一个专业的 Windows 注册表分析工具,专为数字取证和事件响应设…...
Ansys Circuit新手必看:导入IBIS模型时,Pin Import和Buffer Import到底怎么选?
Ansys Circuit实战指南:IBIS模型导入的Pin与Buffer选择策略 第一次打开Ansys Circuit准备进行SIPI仿真时,那个看似简单的IBIS模型导入界面往往会让新手工程师陷入沉思——Pin Import和Buffer Import这两个选项到底有什么区别?选择错误会导致仿…...
FireRedASR-AED-L模型Node.js后端调用实战:构建高并发语音处理API
FireRedASR-AED-L模型Node.js后端调用实战:构建高并发语音处理API 语音转文字的需求现在越来越普遍,从会议记录到客服录音分析,到处都能用上。如果你手头有一个像FireRedASR-AED-L这样强大的语音识别模型服务,怎么把它集成到你的…...
霜儿-汉服-造相Z-Turbo应用指南:打造你的江南庭院古风AI摄影师
霜儿-汉服-造相Z-Turbo应用指南:打造你的江南庭院古风AI摄影师 1. 模型介绍与核心功能 1.1 什么是霜儿-汉服-造相Z-Turbo 霜儿-汉服-造相Z-Turbo是一款专注于生成古风汉服人像的AI文生图模型。它基于强大的Z-Image-Turbo基础模型,通过LoRA(…...
5个理由让你选择LAV Filters:解决媒体播放兼容性问题的全能解码方案
5个理由让你选择LAV Filters:解决媒体播放兼容性问题的全能解码方案 【免费下载链接】LAVFilters LAV Filters - Open-Source DirectShow Media Splitter and Decoders 项目地址: https://gitcode.com/gh_mirrors/la/LAVFilters 在数字媒体爆炸的时代&#x…...
StructBERT模型监控方案:性能与质量实时追踪
StructBERT模型监控方案:性能与质量实时追踪 1. 引言 当你把StructBERT模型部署到生产环境后,最担心的是什么?是服务突然崩溃,还是响应速度变慢,或者是模型预测质量下降?这些问题如果等到用户投诉才发现&…...
M2LOrder模型生成Typora风格技术博客:Markdown排版与内容组织
M2LOrder模型生成Typora风格技术博客:Markdown排版与内容组织 不知道你有没有过这样的经历:脑子里有一堆技术想法,打开文档准备写篇博客分享,结果光是调整标题层级、插入代码块、排版表格就耗掉了大半热情。最后内容虽然不错&…...
