FreeRTOS实时操作系统(十四)软件定时器

news2024/11/24 4:21:19

系列文章目录


文章目录

  • 系列文章目录
  • 软件定时器
  • API函数
  • 实验测试


软件定时器

定时器的作用:经过一段指定时间,触发超时事件

在裸机开发中,应用的是芯片自带的定时器模块,精度很高,在中断服务函数中处理信息,包括实现PWM等功能(硬件定时器)

软件定时器是指具有定时功能的软件,可以设置定时周期,在回调函数中进行信息处理,只要内存够可以创建非常多。

软件定时器优点:
硬件定时器数量有限,而软件定时器理论上只需有足够内存,就可以创建多个;
使用简单、成本低;
缺点:
软件定时器相对硬件定时器来说,精度没有那么高(因为它以系统时钟为基准,系统时钟中断优先级又是最低,容易被打断)。 对于需要高精度要求的场合,不建议使用软件定时器。

软件定时器特点:
可裁剪:使能软件定时器,需将configUSE_TIMERS 配置项配置成 1
单次和周期:软件定时器支持设置成:单次定时器或周期定时器
软件定时器服务任务的优先级为 configTIMER_TASK_PRIORITY = 31;
定时器的命令队列长度为 configTIMER_QUEUE_LENGTH = 5

要点:
1.软件定时器的超时回调函数是由软件定时器服务任务调用的,软件定时器的超时回调函数本身不是任务,因此不能在该回调函数中使用可能会导致任务阻塞的 API 函数。
2.在调用函数 vTaskStartScheduler()开启任务调度器的时候,会创建一个用于管理软件定时器的任务,prvTimerTask( ) ,这个任务就叫做软件定时器服务任务。
3.软件定时器的超时回调函数是在软件定时器服务任务中被调用的,服务任务不是专为某个定时器服务的,它还要处理其他定时器。回调函数要尽快实行,不能进入阻塞状态,即不能调用那些会阻塞任务的 API 函数,如:vTaskDelay() ,访问队列或者信号量的非零阻塞时间的 API 函数也不能调用。

工作方式:API函数通过往定时器队列写入消息,用户不能直接访问
在这里插入图片描述

软件定时器有两种状态:
休眠态:软件定时器可以通过其句柄被引用,但因为没有运行,所以其定时超时回调函数不会被执行
运行态:运行态的定时器,当指定时间到达之后,它的超时回调函数会被调用
新创建的软件定时器处于休眠状态 ,也就是未运行的!,只有发送命令队列后才行。

FreeRTOS提供了两种软件定时器:
单次定时器:单次定时器的一旦定时超时,只会执行一次其软件定时器超时回调函数,不会自动重新开启定时,不过可以被手动重新开启。
周期定时器:周期定时器的一旦启动以后就会在执行完回调函数以后自动的重新启动 ,从而周期地执行其软件定时器回调函数。

单次定时器:
在这里插入图片描述

周期定时器:
在这里插入图片描述

API函数

软件定时器句柄结构体成员:

 typedef  struct tmrTimerControl
    {
        const char * 					pcTimerName		/* 软件定时器名字 */
        ListItem_t 					xTimerListItem		/* 软件定时器列表项 */
        TickType_t 					xTimerPeriodInTicks;        	/* 软件定时器的周期 */     
        void * 						pvTimerID			/* 软件定时器的ID */
        TimerCallbackFunction_t	 		pxCallbackFunction; 	/* 软件定时器的回调函数 */
        #if ( configUSE_TRACE_FACILITY == 1 )
         UBaseType_t 					uxTimerNumber		/*  软件定时器的编号,调试用  */
        #endif
        uint8_t 						ucStatus;                     		/*  软件定时器的状态  */
    } xTIMER;

常见的API函数:

函数描述
xTimerCreate()动态方式创建软件定时器
xTimerCreateStatic()静态方式创建软件定时器
xTimerStart()开启软件定时器定时
xTimerStartFromISR()在中断中开启软件定时器定时
xTimerStop()停止软件定时器定时
xTimerStopFromISR()在中断中停止软件定时器定时
xTimerReset()复位软件定时器定时
xTimerResetFromISR()在中断中复位软件定时器定时
xTimerChangePeriod()更改软件定时器的定时超时时间
xTimerChangePeriodFromISR()在中断中更改定时超时时间

1.创建软件定时器:

TimerHandle_t   xTimerCreate(    const char * const pcTimerName,   //软件定时器名字
								 const TickType_t 	xTimerPeriodInTicks,   //定时超时时间,单位:系统时钟节拍
								 const UBaseType_t 	 uxAutoReload,       //定时器模式,pdTRUE:周期定时器,pdFALSE:单次定时器
								 void * const 	pvTimerID,       //软件定时器ID,用于多个如那件定时器公用一个回调函数
								 TimerCallbackFunction_t pxCallbackFunction  );  //软件定时器超时回调函数

返回值:
NULL 创建失败
其他值:创建成功,返回其句柄

2.开启软件定时器

BaseType_t   xTimerStart( 	TimerHandle_t 	xTimer,const TickType_t 	xTicksToWait  ); 

形参:
xTimer:要开启的软件定时器句柄
xTickToWait:发送命令到软件定时器命令队列的最大等待时间

返回值:
pdPASS:开启成功
pdFAIL:开启失败

3.停止软件定时器

BaseType_t   xTimerStop(  TimerHandle_t 	xTimer,const TickType_t 	xTicksToWait); 

形参:
xTimer:软件定时器句柄
xTickToWait:发送命令到软件定时器命令队列的最大等待时间

返回值:
pdPASS:停止成功
pdFAIL:停止失败

4.复位软件定时器

BaseType_t  xTimerReset( TimerHandle_t 	xTimer,const TickType_t 	xTicksToWait); 

形参:
xTimer:软件定时器句柄
xTickToWait:发送命令到软件定时器命令队列的最大等待时间

返回值:
pdPASS:成功
pdFAIL:失败

5.更改软件定时器的超时时间

BaseType_t  xTimerChangePeriod( TimerHandle_t 		xTimer,
								const TickType_t 	xNewPeriod,
								const TickType_t 	xTicksToWait); 

形参:
xTimer:软件定时器句柄
xNewPeriod:新的定时超时时间,单位:系统时钟节拍
xTickToWait:发送命令到软件定时器命令队列的最大等待时间

返回值:
pdPASS:成功
pdFAIL:失败

实验测试

TimerHandle_t timer1_handle = 0;    /* 单次定时器 */
TimerHandle_t timer2_handle = 0;    /* 周期定时器 */

void timer1_callback( TimerHandle_t pxTimer );
void timer2_callback( TimerHandle_t pxTimer );
 
 void vOtherFunction( void )
 {
	   /* 单次定时器 */
    timer1_handle = xTimerCreate( "timer1", 
                                    500,
                                    pdFALSE,
                                    (void *)1,
                                    timer1_callback );
                            
    /* 周期定时器 */
    timer2_handle = xTimerCreate( "timer2", 
                                    2000,
                                    pdTRUE,
                                    (void *)2,
                                    timer2_callback );
									
	xTaskCreate( vTaskCode, "tak1", 128, NULL, 1, &task1_handler );
	vTaskStartScheduler(); 
 }

void task1( void * pvParameters )
{
	xTimerStart(timer1_handle,portMAX_DELAY);
	xTimerStart(timer2_handle,portMAX_DELAY);
    while(1) 
    {
		vTaskDelay(10);
    }
}

void task2( void * pvParameters )
{
    while(1)
    {
		vTaskDelay(10);
    }
}

/* timer1的超时回调函数 */
void timer1_callback( TimerHandle_t pxTimer )
{
    static uint32_t timer = 0;
    printf("timer1的运行次数:%d\r\n",++timer);
}

/* timer2的超时回调函数 */
void timer2_callback( TimerHandle_t pxTimer )
{
    static uint32_t timer = 0;
    printf("timer2的运行次数:%d\r\n",++timer);
}

周期性任务在不断执行,单次定时器只执行了一次。
在这里插入图片描述

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

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

相关文章

大模型基础知识 - 语言模型及其演进 公开版

本文为作者内部分享文档,由于不涉敏可以公开,分享本身是课程形式,有什么疑问欢迎在评论区留言。 开场白 人工智能发展到现在,在2个重要领域取得了重大突破,有望达到人类水平: 计算机视觉 (Com…

【电路原理学习笔记】第2章:电压、电流和电阻:本章习题

第2章:电压、电流和电阻 以后还是分开做,每一节习题都按节做,不集中在一起做了,太累了,而且要忙其他事,好不容易凑了几天时间做这个题 本章习题 同步练习 (2-1)3C电荷对应于多少…

【数据网格架构】数据网格架构详解

“我想指出,所提供的链接都不是附属的,我从本文中提到的公司中没有任何收获。我做这一切是因为直到最近我才听说过数据网格,我很期待这次活动,并希望在此之前深入了解一下。我还认为这可能会让其他人感兴趣,并付出了额…

pytorch2.0版本简介

PyTorch 2.0 中发布了大量足以改变 PyTorch 使用方式的新功能,它提供了相同的 eager mode 和用户体验,同时通过 torch.compile 增加了一个编译模式,在训练和推理过程中可以对模型进行加速,从而提供更佳的性能和对 Dynamic Shapes …

JVM解析:class结构和常量及方法初始化

文件结构 推荐官方文档:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-3.html ClassFile {u4 magic;u2 minor_version;u2 major_version;u2 constant_pool_count;cp_info constant_pool[cons…

通过python的signal库模拟电源设备的csine波形

import numpy as np import matplotlib.pyplot as plt import random from scipy import signal def csin(length, amp,lenf,n):"""生成模拟CSIN波形的函数:param length: 波形长度:param amp: 波形振幅:return: CSIN波形数据"""amp 100 if (am…

函数和控制流

专栏简介:本专栏作为Rust语言的入门级的文章,目的是为了分享关于Rust语言的编程技巧和知识。对于Rust语言,虽然历史没有C、和python历史悠远,但是它的优点可以说是非常的多,既继承了C运行速度,还拥有了Java…

基于Springboot的宠物店管理系统(源代码+数据库)087

基于Springboot的宠物店管理系统(源代码数据库)087 一、系统介绍 本系统分为管理员、店员两种角色 店员角色包含以下功能: 登录、宠物主人管理、宠物管理、宠物医疗管理、宠物销售管理、宠物寄养管理、宠物用品管理、宠物日常服务管理、宠物常见问题、个人中心、…

基于JavaSwing+MySQL的仓库商品管理系统

点击以下链接获取源码: https://download.csdn.net/download/qq_64505944/88046204?spm1001.2014.3001.5503 JDK1.8 MySQL5.7 功能:管理员与员工两个角色登录,增删改查用户信息,修改密码,增删改查商品信息&#xff0c…

Java文件与IO

文章目录 前言认识文件绝对路径与相对路径普通文件与二进制文件 Java中的操作文件File 类文件的读写 前言认识文件 狭义上的文件(file)。针对硬盘这种持久化存储的I/O设备,当我们想要进行数据保存时,往往不是保存成一个整体,而是独立成一个个…

RocketMQ基础概念

目录 1.简介 2.架构 3.核心概念 1.简介 RocketMQ 是一款开源的分布式消息中间件,最初由阿里巴巴集团开发并开源。它旨在为分布式系统提供可靠、高性能、可扩展的消息通信能力。RocketMQ和RabbitMQ、KAFKA一起并列为现在主流的三大消息中间件。 一般MQ可以从三个…

Python(八)字符编码

❤️ 专栏简介:本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中,我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 :本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

06_HDMI 显示器驱动设计与验证

06_HDMI 显示器驱动设计与验证 1. HDMI 接口及引脚定义1.1 HDMI A Type 接口引脚图1.2 HDMI A Type 接口引脚定义 2. HDMI 原理2.1 HDMI 显示原理2.2 TMDS 传输原理 3. 实验目标4. 程序框图4.1 顶层模块4.2 时钟生成模块4.3 HDMI 驱动控制模块4.3.1 第一个步骤4.3.2 编码模块参…

反垄断在中国

中国通过反垄断法 中国通过了具有里程碑意义的反托拉斯立法,外国企业表示谨慎性的欢迎,希望该法案能带来更大的开放性,但需要观察它是如何实施的。(华尔街日报 2007年8月32日报道) 反垄断法禁止垄断协议和诸如卡特尔及价格操纵,但允许能促进创新和技术进步的垄断之存在。…

微软亚洲研究院推出AI编译器界“工业重金属四部曲”

编者按:编译器在传统计算科学中一直是一个重要的研究课题。在人工智能技术快速发展和广泛应用的今天,人工智能模型需要部署在多样化的计算机硬件架构上。同时,训练和部署大型人工智能模型时又对硬件性能有着更高的要求,有时还需根…

c#示例-json序列化和json树

序列化 由于指针和引用类型的存在,在运行中的程序中,数据不一定是整块的。 可能东一块西一块散落在内存的各个地方。 序列,是指连续且有序的一个整体。序列化就是把数据变为连续有序整体的过程。 经过这样处理后的数据就可以方便的进行传输…

1130 - Host XXX‘ is not allowed to connect to this MySQL server

mysql 连接报错 这个问题是因为在数据库服务器中的mysql数据库中的user的表中没有没有用户 解决的方法: 登入mysql后,更改 “mysql” 数据库里的 “user” 表里的 “host” 项,从”localhost”改称’%’。 1、连接服务器: mysql -u root -p…

万字解读 | 数据可视化平台--FineBI

什么是BI 学习目标 知道什么是BI 知道FineBI的优势 1. 商业智能: BI(Business Intelligence)是指通过收集、分析和解释企业内外部数据,为企业决策提供支持和指导的一种技术和工具。商业智能的目标是帮助企业管理者和决策者更好地理解企业…

vivado 添加 pynq-z2板

以vivado2019.02版本为例 1下载地址 https://www.tulembedded.com/FPGA/ProductsPYNQ-Z2.html 2.点击下载 3.解压添加 注:如果没有board_files 可以自己创建一个 4.重新打开vivado

跨境电商企业实施WMS仓储管理系统有什么要注意的

在跨境电商行业中,仓储管理是关键的环节之一。为了提高仓储效率和准确性,许多跨境电商企业选择实施WMS仓储管理系统解决方案。然而,实施电商企业WMS系统并不是一项简单的任务,需要注意一些关键要点。本文将介绍跨境电商企业实施WM…