µCOS-III从入门到精通 第十四章(软件定时器)

news2025/3/14 10:35:45

参考教程:【正点原子】手把手教你学UCOS-III实时操作系统_哔哩哔哩_bilibili

一、软件定时器简介

1、定时器的概念与种类

(1)定时器的概念:从指定的时刻开始,经过一个指定时间,然后触发一个超时事件,用户可自定义定时器的周期。

(2)定时器的种类:

①硬件定时器:芯片本身自带的定时器模块,硬件定时器的精度一般很高,每次在定时时间到达之后就会自动触发一个中断,用户在中断服务函数中处理信息。

②软件定时器:具有定时功能的软件,可设置定时周期,当指定时间到达后要调用回调函数(也称超时函数),用户在回调函数中处理信息。

2、软件定时器的优缺点

(1)优点:硬件定时器数量有限,而软件定时器理论上只需有足够内存,就可以创建多个,且使用简单、成本低。

(2)缺点:软件定时器相对硬件定时器来说,精度没有那么高(因为它以系统时钟为基准,系统时钟中断优先级又是最低,容易被打断),对于需要高精度要求的场合,不建议使用软件定时器。

二、µC/OS-III软件定时器

1、µC/OS-III软件定时器的种类和状态

(1)µC/OS-III提供了两种软件定时器:

①单次定时器:单次定时器的一旦定时超时,只会执行一次其软件定时器超时回调函数,不会自动重新开启定时,不过可以被手动重新开启。

②周期定时器:周期定时器的一旦启动以后就会在执行完回调函数以后自动的重新启动 ,从而周期地执行其软件定时器回调函数。

(2)软件定时器共有4种状态:

①未使用态:当软件定时器被定义但还未被创建或软件定时器被删除时,软件定时器就处于未使用态。

②停止态:当软件定时器被创建但还未开启定时器或被停止时,软件定时器就处于停止态。

③运行态:运行态的定时器,当指定时间到达之后,它的超时回调函数会被调用。

④完成态:当单次定时器定时超时后,软件定时器处于完成态。

2、µC/OS-III软件定时器特点

(1)软件定时器支持裁剪,如需使能软件定时器,需将OS_CFG_TMR_EN配置项配置成1。

(2)软件定时器的超时回调函数是由软件定时器服务任务调用的,软件定时器的超时回调函数本身不是任务,因此不能在该回调函数中使用可能会导致任务阻塞的API函数。

(3)软件定时器的频率由宏OS_CFG_TMR_TASK_RATE_HZ决定,要注意软件定时器的频率并不等于系统时钟节拍的频率,但软件定时器是依靠系统节拍实现定时的,所以需要进行换算:

软件定时器时间分辨率 = OS_CFG_TICK_RATE_HZ / OS_CFG_TMR_TASK_RATE_HZ

//例如:在例程中将宏OS_CFG_TMR_TASK_RATE_HZ设置为10,也就是将软件定时器时钟信号频率设置为10HZ(100ms),假设现在开启一个定时时长为10的软件定时器,那么他大约在10 * 100ms = 1000ms后超时

3、µC/OS-III软件定时器相关API函数

(1)µC/OS-III软件定时器相关API函数概览:

函数

描述

OSTmrCreate

创建一个软件定时器

OSTmrDel

删除一个软件定时器

OSTmrRemainGet

获取软件定时器的剩余超时时间

OSTmrSet

设置软件定时器的延时时间、周期、超时回调函数及其参数等

OSTmrStart

开启软件定时器定时

OSTmrStateGet

获取软件定时器的状态

OSTmrStop

停止软件定时器定时

(2)OSTmrCreate函数:

void OSTmrCreate
(
    OS_TMR* 					p_tmr,
	CPU_CHAR* 				p_name,
	OS_TICK 					dly,
	OS_TICK 					period,
	OS_OPT 					opt,
	OS_TMR_CALLBACK_PTR 	p_callback,
	void* 						p_callback_arg,
	OS_ERR* 					p_err
) 

形参

描述

p_tmr

指向软件定时器结构体指针

p_name

指向软件定时器名的字符串指针

dly

软件定时器的开启延时时间,注意单次定时器必须大于0(也就是开启之后多久超时)

period

周期定时器的定时周期时间,注意周期定时器必须大于0

opt

OS_OPT_TMR_ONE_SHOT(单次定时器)

OS_OPT_TMR_PERIODIC(周期定时器)

p_callback

指向超时回调函数的指针

p_callback_arg

超时回调函数入口参数

p_err 

指向接收错误代码变量的指针

①周期软件定时器的时序图:

②单次软件定时器的时序图:

(3)OSTmrDel函数:

CPU_BOOLEAN OSTmrDel  //返回OS_TRUE表示删除成功,OS_FALSE表示删除失败
(
    OS_TMR* 	p_tmr, 
    OS_ERR* 	p_err
) 

形参

描述

p_tmr

指向软件定时器结构体指针

p_err 

指向接收错误代码变量的指针

(4)OSTmrStart函数:

CPU_BOOLEAN OSTmrStart  //返回OS_TRUE表示开启成功,OS_FALSE表示开启失败
(
    OS_TMR*	p_tmr,
    OS_ERR* 	p_err
) 

形参

描述

p_tmr

指向软件定时器结构体指针

p_err 

指向接收错误代码变量的指针

(5)OSTmrStop函数:

CPU_BOOLEAN OSTmrStop
(
	OS_TMR* 	p_tmr,
	OS_OPT 	opt,
	void* 		p_callback_arg,
	OS_ERR* 	p_err
) 

形参

描述

p_tmr 

指向软件定时器结构体的指针

opt 

函数操作选项

p_callback_arg 

传给软件定时器超时回调函数的参数

p_err 

指向接收错误代码变量的指针

        可选的函数操作选项如下:

Opt

描述

OS_OPT_TMR_CALLBACK

执行一次回调函数,代入原始参数

OS_OPT_TMR_CALLBACK_ARG

执行一次回调函数,代入指定参数

OS_OPT_TMR_NONE

仅停止软件定时器

三、µC/OS-III软件定时器实验

1、原理图与实验目标

(1)原理图:

(2)实验目标:

①设计2个任务——start_task、task1:

[1]start_task:用于创建task1任务,创建两个定时器并启动之(分别为单次和周期型,其回调函数中分别需要翻转LED1和LED2的状态)。

[2]task1:用于按键扫描,并对两个软件定时器进行开启、停止操作,按下按键2即开始两个软件定时器,按下按键1反之。

②预期实验现象:

[1]程序下载到板子上后,LED1灯状态仅变更一次,LED2灯持续闪烁。

[2]按下按键1,LED1和LED2状态冻结。

[3]按下按键2,LED1灯状态仅变更一次,LED2恢复持续闪烁。

2、实验步骤

(1)将“任务创建和删除实验”的工程文件夹复制一份,在拷贝版中进行实验。

(2)删除UCOS_experiment.c文件中关于task2和task3的内容,在start_task中创建一个单次定时器和周期定时器,并编写回调函数,同时更改task1函数的具体实现,如下所示。

#include "stm32f10x.h"                  // Device header
#include "os.h"
#include "cpu.h"
#include "LED.h"
#include "Key.h"
#include <stdio.h>

/* START_TASK 任务 配置
 * 包括: 任务优先级 任务栈大小 任务控制块 任务栈 任务函数
 */
#define     START_TASK_PRIO          1
#define     START_TASK_STACK_SIZE   256
CPU_STK     start_task_stack[START_TASK_STACK_SIZE];
OS_TCB      start_task_tcb;
void start_task(void);

/* TASK1 任务 配置
 * 包括: 任务优先级 任务栈大小 任务控制块 任务栈 任务函数
 */
#define     TASK1_PRIO               4
#define     TASK1_STACK_SIZE        256
CPU_STK     task1_stack[TASK1_STACK_SIZE];
OS_TCB      task1_tcb;
void task1(void);

OS_TMR timer1,timer2;
void timer_callback(OS_TMR *pxTimer, void *p_arg);
void timer_callback(OS_TMR *pxTimer, void *p_arg);

void UCOS_Test(void)
{
	OS_ERR err;
	
	OSInit(&err);    //初始化μC/OS-III

	//创建Start Task
    OSTaskCreate (&start_task_tcb,
                  "start_task",
                  (OS_TASK_PTR)start_task,
                  NULL,
                  START_TASK_PRIO,
                  start_task_stack,
                  START_TASK_STACK_SIZE / 10,
                  START_TASK_STACK_SIZE,
                  0,
                  0,
                  0,
                  (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                  &err);
    
    /* 开始任务调度 */
    OSStart(&err);
}

void start_task(void)              
{
    OS_ERR err;     //接收错误代码使用,对错误代码进行分情况处理可增强程序鲁棒性
    CPU_Init();     //初始化CPU库
    CPU_SR_ALLOC();
	
	OSTmrCreate(&timer1,"timer1", 10, 0, 
				OS_OPT_TMR_ONE_SHOT, 
				(OS_TMR_CALLBACK_PTR)timer_callback,
				NULL, &err);   //创建单次定时器
	OSTmrCreate(&timer2,"timer2", 0, 10, 
				OS_OPT_TMR_PERIODIC, 
				(OS_TMR_CALLBACK_PTR)timer_callback,
				NULL, &err);   //创建周期定时器
    
	//滴答定时器重装载值 = 系统主频 / 滴答定时器中断频率(滴答定时器是递减计数)
    CPU_INT32U cnts = SystemCoreClock / OS_CFG_TICK_RATE_HZ;
    OS_CPU_SysTickInit(cnts);   //配置Systick中断及优先级
    
    CPU_CRITICAL_ENTER();           //进入临界区(关中断)
	
    //创建task1
    OSTaskCreate (&task1_tcb,
                  "task1",
                  (OS_TASK_PTR)task1,
                  0,
                  TASK1_PRIO,
                  task1_stack,
                  TASK1_STACK_SIZE / 10,
                  TASK1_STACK_SIZE,
                  0,
                  0,
                  0,
                  (OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                  &err);

	OSTmrStart(&timer1, &err);  //启动定时器1
	OSTmrStart(&timer2, &err);  //启动定时器2
	
    CPU_CRITICAL_EXIT();            //退出临界区(开中断)
    OSTaskDel(NULL, &err);   //删除任务自身
}

void task1(void)
{
	OS_ERR err;
	uint8_t key = 0;
	while(1)
	{
		key = Key_GetNum();    //读取按键键值
		if(key == 1)
		{
			OSTmrStop(&timer1, OS_OPT_TMR_NONE, NULL, &err);  //停止定时器1
			OSTmrStop(&timer2, OS_OPT_TMR_NONE, NULL, &err);  //停止定时器1
		}
		if(key == 2)
		{
			OSTmrStart(&timer1, &err);  //启动定时器1
			OSTmrStart(&timer2, &err);  //启动定时器2
		}
		OSTimeDly(10,OS_OPT_TIME_DLY,&err);
	}
}

/* 软件定时器的超时回调函数 */
void timer_callback(OS_TMR *pxTimer, void *p_arg)  //第一个参数是调用回调函数的定时器的指针,第二个是函数参数
{
	if(pxTimer == &timer1)  //根据传入的定时器指针判断执行什么操作
	{
		LED1_Turn();
	}
    else if(pxTimer == &timer2)
	{
		LED2_Turn();
	}
}

(3)程序完善好后点击“编译”,然后将程序下载到开发板上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2314809.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL数据库复杂的增删改查操作

在前面的文章中&#xff0c;我们主要学习了数据库的基础知识以及基本的增删改查的操作。接下去将以一个比较实际的公司数据库为例子&#xff0c;进行讲解一些较为复杂且现时需求的例子。 基础知识&#xff1a; 一文清晰梳理Mysql 数据库基础知识_字段变动如何梳理清楚-CSDN博…

KCD 北京站丨Volcano 邀您畅聊云原生智能调度技术与应用

AI与云原生技术正以前所未有的速度改变着我们的世界&#xff0c;而云原生技术则如同一座坚实的桥梁&#xff0c;连接着传统IT与现代化的数字世界。当AI与云原生相遇&#xff0c;它们相互赋能&#xff0c;相互促进&#xff0c;为开发者们打开了一个全新的技术宇宙。 3 月 15 日&…

BLEU评估指标

一、介绍 用于评估模型生成的句子和实际句子差异的指标&#xff0c;取值在[0,1]&#xff0c;匹配度高就距离1近&#xff0c;反之距离0近。这个指标计算代价小&#xff0c;容易理解&#xff0c;与语言无关&#xff0c;与人类评价结果高度相关。 BLEU主要基于n-gram匹配&#x…

高效自动化测试:打造Python+Requests+Pytest+Allure+YAML的接口测试框架

一、背景 在快节奏的开发周期中&#xff0c;如何确保接口质量&#xff1f;自动化测试是关键。通过构建标准化、可复用的测试框架&#xff0c;能显著提升测试效率与准确性&#xff0c;为项目质量保驾护航[1][7]。 二、目标 ✅ 核心目标&#xff1a; ● 实现快速、高效的接口测试…

BSides Vancouver: 2018 (Workshop)

BSides Vancouver: 2018 (Workshop) 来自 <https://www.vulnhub.com/entry/bsides-vancouver-2018-workshop,231/> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23…

rStar论文精读

论文简介 论文标题&#xff1a;《Mutual reasoning makes smaller LLMs stronger problem-solvers》 论文地址&#xff1a;https://arxiv.org/abs/2408.06195 录用会议&#xff1a;ICLR2025 背景与挑战 挑战1&#xff1a;在SLM中平衡exploration与exploitation。一些方法有很…

247g 的工业级电调,如何让无人机飞得更 “聪明“?——STONE 200A-M 深度测评

一、轻量化设计背后的技术取舍 当拿到 STONE 200A-M 时&#xff0c;247g 的重量让人意外 —— 这个接近传统 200A 电调 70% 的重量&#xff0c;源自 1205624.5mm 的紧凑结构&#xff08;0.1mm 公差控制&#xff09;。实测装机显示&#xff0c;相比同规格产品&#xff0c;其体积…

Node.js:快速启动你的第一个Web服务器

Node.js 全面入门指南 文章目录 Node.js 全面入门指南一 安装Node.js1. Windows2. MacOS/Linux 二 配置开发环境1. VSCode集成 三 第一个Node.js程序1. 创建你的第一个Node.js程序 四 使用Express框架1. 快速搭建服务器 一 安装Node.js 1. Windows 以下是Windows环境下Node.j…

自定义日志回调函数实现第三方库日志集成:从理论到实战

一、应用场景与痛点分析 在开发过程中&#xff0c;我们经常会遇到以下场景&#xff1a; 日志格式统一&#xff1a;第三方库使用自己的日志格式&#xff0c;导致系统日志混杂&#xff0c;难以统一管理和分析。日志分级过滤&#xff1a;需要动态调整第三方库的日志输出级别&…

Linux练级宝典->任务管理和守护进程

任务管理 进程组概念 每个进程除了进程ID以外&#xff0c;还有一个进程组&#xff0c;进程组就是一个或多个进程的集合 同一个进程组&#xff0c;代表着他们是共同作业的&#xff0c;可以接收同一个终端的各种信号&#xff0c;进程组也有其唯一的进程组号。还有一个组长进程&a…

C语言:计算并输出三个整数的最大值 并对三个数排序

这是《C语言程序设计》73页的思考题。下面分享自己的思路和代码 思路&#xff1a; 代码&#xff1a; #include <stdio.h> int main() {int a,b,c,max,min,mid ; //设置大中小的数分别为max&#xff0c;mid&#xff0c;min&#xff0c;abc为输入的三个数printf("ple…

工具(十二):Java导出MySQL数据库表结构信息到excel

一、背景 遇到需求&#xff1a;将指定数据库表设计&#xff0c;统一导出到一个Excel中&#xff0c;存档查看。 如果一个一个弄&#xff0c;很复杂&#xff0c;耗时长。 二、写一个工具导出下 废话少絮&#xff0c;上码&#xff1a; 2.1 pom导入 <dependency><grou…

ACL初级总结

ACL–访问控制列表 1.访问控制 在路由器流量流入或者流出的接口上,匹配流量,然后执行相应动作 permit允许 deny拒绝 2.抓取感兴趣流 3.ACL匹配规则 自上而下逐一匹配,若匹配到了则按照对应规则执行动作,而不再向下继续匹配 思科:ACL列表末尾隐含一条拒绝所有的规则 华为:AC…

调优案例一:堆空间扩容提升吞吐量实战记录

&#x1f4dd; 调优案例一&#xff1a;堆空间扩容提升吞吐量实战记录 &#x1f527; 调优策略&#xff1a;堆空间扩容三部曲 # 原配置&#xff08;30MB堆空间&#xff09; export CATALINA_OPTS"$CATALINA_OPTS -Xms30m -Xmx30m"# 新配置&#xff08;扩容至120MB&am…

C语言 —— 此去经年梦浪荡魂音 - 深入理解指针(卷一)

目录 1. 内存和地址 2. 指针变量和地址 2.1 取地址操作符&#xff08;&&#xff09; 2.2 指针变量 2.3 解引用操作符 &#xff08;*&#xff09; 3. 指针的解引用 3.1 指针 - 整数 3.2 void* 指针 4. const修饰指针 4.1 const修饰变量 4.2 const修饰指针变量 5…

计算机毕业设计:留守儿童的可视化界面

留守儿童的可视化界面mysql数据库创建语句留守儿童的可视化界面oracle数据库创建语句留守儿童的可视化界面sqlserver数据库创建语句留守儿童的可视化界面springspringMVChibernate框架对象(javaBean,pojo)设计留守儿童的可视化界面springspringMVCmybatis框架对象(javaBean,poj…

golang算法二叉树对称平衡右视图

100. 相同的树 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&#xff1a…

Chatbox通过百炼调用DeepSeek

解决方案链接&#xff1a;评测&#xff5c;零门槛&#xff0c;即刻拥有DeepSeek-R1满血版 方案概览 本方案以 DeepSeek-R1 满血版为例进行演示&#xff0c;通过百炼模型服务进行 DeepSeek 开源模型调用&#xff0c;可以根据实际需求选择其他参数规模的 DeepSeek 模型。百炼平台…

【数据结构】6栈

0 章节 3&#xff0e;1到3&#xff0e;3小节。 认知与理解栈结构&#xff1b; 列举栈的操作特点。 理解并列举栈的应用案例。 重点 栈的特点与实现&#xff1b; 难点 栈的灵活实现与应用 作业或思考题 完成学习测试&#xff12;&#xff0c;&#xff1f; 内容达成以下标准(考核…

PyTorch 入门学习

目录 PyTorch 定义 核心作用 应用场景 Pytorch 基本语法 1. 张量的创建 2. 张量的类型转换 3. 张量数值计算 4. 张量运算函数 5. 张量索引操作 6. 张量形状操作 7. 张量拼接操作 8. 自动微分模块 9. 案例-线性回归案例 PyTorch 定义 PyTorch 是一个基于 Python 深…