FreeRTOS软件定时器

软件定时器允许设置一段时间,当设置的时间达到后就执行指定的功能函数,被软件定时器调用的功能函数叫做定时器的回调函数。软件定时器的回调函数是在定时器服务任务中执行的,所以一定不能在回调函数中调用任何阻塞任务的API函数,比如VTaskDelay。
软件定时器分为两种,单次定时器和周期定时器,单次定时器就执行一次,然后停止运行,不能自动重启,但我们可以手动重新启动,周期定时器就是执行完回调函数以后自动的重新启动,这样回调函数就会周期性的执行。

0x01 定时器相关配置

定时器的配置在FreeRTOSConfig.h中

  1. configUSE_TIMES
    如果要使用软件定时器,configUSE_TIMES要设置为1。

  2. configTIMER_TASK_PRIORITY
    设置软件定时器服务任务的任务优先级

  3. configTIMER_QUEUE_LENGTH
    设置定时器命令队列的队列长度

  4. configTIMER_TASK_STACK_DEPTH
    设置定时器任务的任务堆栈大小,单位为字,对于STM32来说一个字是4字节

0x02 创建定时器

使用软件定时器首先要创建,创建定时器分为动态和静态两种创建方法。

  • xTimerCreate():使用动态方法创建软件定时器
  • xTimerCreateStatic():使用静态方法创建软件定时器
	TimerHandle_t xTimerCreate(	const char * const pcTimerName,const TickType_t xTimerPeriodInTicks,const UBaseType_t uxAutoReload,void * const pvTimerID,TimerCallbackFunction_t pxCallbackFunction ) 
  • const char * const pcTimerName:软件定时器名字
  • const TickType_t xTimerPeriodInTicks:软件定时器的定时周期,单位是时钟节拍数,可以借助portTICK_PERIOD_MS将ms单位转换为时钟节拍数,比如定时器的周期为100个时钟节拍的话,那么xTimerPeriodInTicks=100,当定时器周期为500ms的时候,xTimerPeriodInTicks =(500/portTICK_PERIOD_MS)
  • const UBaseType_t uxAutoReload:设置定时器模式,但是定时器还是周期定时器,当uxAutoReload=pdTRUE的时候创建的是周期定时器,uxAutoReload=pdFALSE是单次定时器。
  • void * const pvTimerID:定时器ID号。
  • TimerCallbackFunction_t pxCallbackFunction :定时器回调函数,当定时器周期到了以后就会调用这个函数。
	TimerHandle_t xTimerCreateStatic(	const char * const pcTimerName,const TickType_t xTimerPeriodInTicks,const UBaseType_t uxAutoReload,void * const pvTimerID,TimerCallbackFunction_t pxCallbackFunction,StaticTimer_t *pxTimerBuffer )
  • const char * const pcTimerName:软件定时器名字
  • const TickType_t xTimerPeriodInTicks:软件定时器的定时周期,单位是时钟节拍数,可以借助portTICK_PERIOD_MS将ms单位转换为时钟节拍数,比如定时器的周期为100个时钟节拍的话,那么xTimerPeriodInTicks=100,当定时器周期为500ms的时候,xTimerPeriodInTicks =(500/portTICK_PERIOD_MS)
  • const UBaseType_t uxAutoReload:设置定时器模式,但是定时器还是周期定时器,当uxAutoReload=pdTRUE的时候创建的是周期定时器,uxAutoReload=pdFALSE是单次定时器。
  • void * const pvTimerID:定时器ID号。
  • TimerCallbackFunction_t pxCallbackFunction :定时器回调函数,当定时器周期到了以后就会调用这个函数。
  • StaticTimer_t *pxTimerBuffer:参数指向一个StaticTimer_t类型的变量,用来保存定时器结构体

0x03 开启软件定时器

如果软件定时器停止运行的话可以使用FreeRTOS提供的两个开启函数来重新启动软件定时器

  • xTimerStart():开启软件定时器,用于任务中
  • xTimerStartFromISR():开启软件定时器,用于中断中
BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait )
  • TimerHandle_t xTimer:要开启的软件定时器的句柄
  • TickType_t xTicksToWait :设置阻塞时间
BaseType_t xTimerStartFromISR( 	TimerHandle_t xTimer,BaseType_t *pxHigherPriorityTaskWoken );
  • TimerHandle_t xTimer:开启的软件定时器的句柄
  • BaseType_t *pxHigherPriorityTaskWoken :标记退出此函数以后是否进行任务切换,这个变量的值函数会自动设置的,用户不用进行设置,当此值为pdTURE的时候,在退出中断服务函数之前一定要进行一次任务切换。

0x04 复位软件定时器

复位一个软件定时器会重新计算定时周期达到的时间点,这个新的时间点是相对于复位定时器的那个时刻开始的,比如说,我们有个timer1单次定时器,定时周期是5s,从0s到5s,如果没有干预的话,timer1在5s会停止运行,如果我们在3s时刻进行复位,则timer1会从3s开始,中间如果没有干预的话,会到8s停止运行,有复位的话,会从复位时刻继续运行5s。复位相关函数如下:

  • xTimerReset:复位软件定时器,用在任务中
  • xTimerResetFromISR:复位软件定时器,用在中断服务函数中
BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait )
  • TimerHandle_t xTimer:要复位的软件定时器句柄
  • TickType_t xTicksToWait:设置阻塞时间
BaseType_t xTimerResetFromISR( 	TimerHandle_t xTimer,BaseType_t *pxHigherPriorityTaskWoken );
  • TimerHandle_t xTimer:要复位的软件定时器句柄
  • BaseType_t *pxHigherPriorityTaskWoken:设置退出此函数是否进行任务切换

0x05 停止软件定时器

停止软件定时器相关中断如下:

  • xTimerStop():停止软件定时器,用于任务中
  • xTimerStopFromISR():停止软件定时器,用在中断服务函数中
BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait )
  • TimerHandle_t xTimer:要停止的软件定时器句柄
  • TickType_t xTicksToWait:设置阻塞时间
BaseType_t xTimerStopFromISR( 	TimerHandle_t xTimer,BaseType_t *pxHigherPriorityTaskWoken )
  • TimerHandle_t xTimer:要停止的软件定时器句柄
  • BaseType_t *pxHigherPriorityTaskWoken :标志退出此函数是否要进行任务切换

实验

设计两个任务:

  1. start_task:用来创建timercontrol_task和两个软件定时器,这两个定时器分别为周期定时器和单次定时器,定时周期一个为1s,另一个为2s
  2. timercontrol_task:控制两个软件定时器的开启和停止

main函数中创建start_task任务

int main(void)
{HAL_Init();                     //初始化HAL库   Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhzdelay_init(180);                //初始化延时函数uart_init(115200);              //初始化串口LED_Init();                     //初始化LED KEY_Init();                     //初始化按键BEEP_Init();                 	//初始化蜂鸣器SDRAM_Init();                   //初始化SDRAMLCD_Init();                     //初始化LCDmy_mem_init(SRAMIN);            //初始化内部内存池POINT_COLOR = RED;LCD_ShowString(30,10,200,16,16,"Apollo STM32F4/F7");	LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 15-1");LCD_ShowString(30,50,200,16,16,"KEY_UP:Start Tmr1");LCD_ShowString(30,70,200,16,16,"KEY0:Start Tmr2");LCD_ShowString(30,90,200,16,16,"KEY1:Stop Tmr1 and Tmr2");LCD_DrawLine(0,108,239,108);		//画线LCD_DrawLine(119,108,119,319);		//画线POINT_COLOR = BLACK;LCD_DrawRectangle(5,110,115,314); 	//画一个矩形	LCD_DrawLine(5,130,115,130);		//画线LCD_DrawRectangle(125,110,234,314); //画一个矩形	LCD_DrawLine(125,130,234,130);		//画线POINT_COLOR = BLUE;LCD_ShowString(6,111,110,16,16,	 "AutoTim:000");LCD_ShowString(126,111,110,16,16,"OneTim: 000");//创建开始任务xTaskCreate(start_task,"start_task",256,NULL,1,&StartTask_Handler);//启动任务调度器vTaskStartScheduler();
}

start_task来创建timercontrol_task和两个软件定时器

void start_task(void *pvParameters)
{taskENTER_CRITICAL();//创建软件周期定时器,周期定时器,周期为1s(1000个时钟节拍)AutoReloadTimer_Handler=xTimerCreate("AutoReloadTimer",1000,pdTRUE,(void *)1,AutoReloadCallback);//创建单词定时器OneShotTimer_Handler = xTimerCreate("OneShotTimer",2000,pdFALSE,(void*)2,OneShotCallback);xTaskCreate(timercontrol_task,"timercontrol_task",256,NULL,2,&TimerControlTask_Handler);taskEXIT_CRITICAL();vTaskDelete(StartTask_Handler);
}

AutoReloadCallback和OneShotCallback是两个定时器的回调函数,内容为:

void AutoReloadCallback(TimerHandle_t xTYimer)
{static u8 tmr1_num=0;tmr1_num++;LCD_ShowxNum(70,111,tmr1_num,3,16,0x80);	//显示执行次数LCD_Fill(6,131,114,313,lcd_discolor[tmr1_num%14]);
}
void OneShotCallback(TimerHandle_t xTYimer)
{static u8 tmr2_num =0;tmr2_num++;LCD_ShowxNum(190,111,tmr2_num,3,16,0x80);LCD_Fill(126,131,233,313,lcd_discolor[tmr2_num%14]);LED1 = !LED1;printf("定时器2运行结束\r\n");
}

timercontrol_task内容

void timercontrol_task(void *pvParameter)
{u8 key,num;while(1){if((AutoReloadTimer_Handler!=NULL)&&(OneShotTimer_Handler!=NULL)){key = KEY_Scan(0);switch(key){case WKUP_PRES:xTimerStart(AutoReloadTimer_Handler,0);printf("开启定时器1\r\n");break;case KEY0_PRES:xTimerStart(OneShotTimer_Handler,0);printf("开始定时器2\r\n");break;case KEY1_PRES:xTimerStop(AutoReloadTimer_Handler,0);xTimerStop(OneShotTimer_Handler,0);printf("关闭定时器1和2\r\n");break;}}num++;if(num==50){num =0;LED0 = !LED0;}vTaskDelay(10);//延时10ms}
}

start_task只是创建了定时器,并没有开启,在timercontrol_task中,如果按下KEY_UP按键,就会开启AutoReloadTimer_Handler定时器,按下KEY0就会启动OneShotTimer_Handler定时器,按下KEY1停止两个定时器

串口输出内容
在这里插入图片描述

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

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

相关文章

WP7之Application Bar控件

Microsoft.Phone.Shell命名空间中定义了ApplicationBar及其相关类(ApplicationBarIconButton和ApplicationBarMenuItem),这些类派生自Object,并完全独立于常规Silverlight编程中的DependencyObject,UIElement和FrameworkElement类层次结构。A…

TomCat使用以及端口号被占用的处理方法

一.HTTP协议 什么是HTTP协议 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。 HTTP请求 HTTP响应 2.如何处理端口被占用 方法一&#xff…

FreeRTOS事件标志组

使用信号量来同步的话,任务只能与单个事务或任务进行同步,有时候某个任务可能会需要与多个事件或任务进行同步,此时信号量就无能为力了,FreeRTOS为此提供了一个可选的解决方法,那就是事件标志组。 0x01 事件标志组 事…

FusionCharts等产品简介

以前做柱状图、饼形图等图表都是根据数据绘制出来的静态图,偶然看到别人的一套系统,居然可以让柱状图的柱子动画般的逐个出现,效果还是很不错的。不要跟我抬杠说不就是展现数据嘛,静态图表有什么不好,要知道用户一般可…

Eclipse和Tomcat绑定并且将上传资源到Tomcat上

步骤如下: 创建一个Dynamic Web Project(图一) Target runtime 选择Apache Tomcat v7.0版本(图二) 切记要选择 v7.0 和2.5 (若没有图二选项见图三) 然后,点击window --> Prefer…

FreeRTOS任务通知

从v8.2.0版本开始,FreeRTOS新增了任务通知这个功能,可以使用任务通知来代替信号量、消息队列、事件标志组等这些东西,使用任务通知的话效率会更高。 任务通知在FreeRTOS是一个可选的选项,要使用任务通知的话就需要将宏configUSE_T…

kinect在openni下也能玩抠出人物换背景

之前想了个很拉风的名字《用kinect玩穿越》,但是现在功能还不是很完善,细节处理也不是很好,脸皮没有足够的厚,所以呢还是叫换背景吧。 这里面包含两个技术要点: 一、抠出活动人物 在微软的SDK里深度图像的前3位即0-2位…

Emit学习-基础篇-基本概念介绍

之前的Hello World例子应该已经让我们对Emit有了一个模糊的了解,那么Emit到底是什么样一个东西,他又能实现些什么功能呢?昨天查了点资料,大致总结了下,由于才开始学习肯定有不完善的地方,希望大家能够批评指…

The FreeRTOS Distribution(介绍、移植、类型定义)

1 Understand the FreeRTOS Distribution 1.1 Definition :FreeRTOS Port FreeRTOS目前可以在20种不同的编译器构建,并且可以在30多种不同的处理器架构上运行,每个受支持的编译器和处理器组合被认为是一个单独的FreeRTOS Port。 1.2 Build…

Eclipse项目左上角出现大红色感叹号怎么办?

出现大红色感叹号是因为环境不匹配 解决方法: 右击出现大红色感叹号的项目 点击 Libraries,将有叉号的给Remove掉 然后再点击 Add Library —> JRE System Library —> Next 勾选第二个即可 之后,就不会出现大红色感叹号了。

PCB---STM32最小系统制作过程

PCB 制作过程STM32核心模块连接外部电源晶振OSC_IN(8MHz)OSC32_IN(32.768MHz)复位下载口BOOT模式电源模块添加功能UARTWKUPSTM32核心模块 这里我们以STM32F103C8T6为列,先将芯片的原理图放到原理图中 对于STM32,有几个模块是核心&#xff0…

FreeRTOS---堆内存管理(一)

FreeRTOS的堆内存管理简介动态内存分配及其与 FreeRTOS 的相关性动态内存分配选项内存分配方案Heap_1heap_2Heap_3Heap_4设置heap_4的起始地址Heap_5vPortDefineHeapRegions()堆相关的函数xPortGetFreeHeapSizexPortGetMinimumEverFreeHeapSizeMalloc调用失败的Hook函数这篇文章…

FreeRTOS--堆内存管理(二)

堆内存管理代码具体实现heap_1内存申请函数内存释放函数heap_2内存块内存堆初始化函数内存块插入函数内存申请函数判断是不是第一次申请内存开始分配内存内存释放函数heap_3heap_4内存堆初始化函数内存块插入函数heap_5上一篇文章说了FreeRTOS实现堆内存的原理,这一…

css中的node.js_在Node App中使用基本HTML,CSS和JavaScript

css中的node.jsYou may think this is not important, but it is!. As a beginner in node.js, most coding exercises are always server sided. 您可能认为这并不重要,但确实如此! 作为node.js的初学者,大多数编码练习始终都是服务器端的。…

Binary String Matching(C++)

题目描述: Given two strings A and B, whose alphabet consist only ‘0’ and ‘1’. Your task is only to tell how many times does A appear as a substring of B? For example, the text string B is ‘1001110110’ while the pattern string A is ‘11’, you should…

VisualStudio2019配置OpenCV

VisualStudio2019配置OpenCV配置0x01 准备0x02 配置系统环境0x03 复制文件0x04 配置VisualStudio2019测试配置 0x01 准备 下载opencv,官网地址:https://opencv.org/releases/# 下载之后,自行安装 0x02 配置系统环境 找到高级系统设置 …

Visual Studio进行linux远程开发

目录准备工作创建一个项目配置远程项目准备工作 查看linux IP地址 安装了工具 sudo apt-get install openssh-server g gdb make ninja-build rsync zip开启ssh服务: sudo service ssh startVS2019按装了linux功能,如果没有,找到Visual S…

在给定总和K的二叉树中找到级别

Description: 描述: The article describes how to find the level in a binary tree with given sum K? This is an interview coding problem came in Samsung, Microsoft. 本文介绍了如何在给定总和K下在二叉树中找到级别 ? 这是一个面试编码问题&a…

++i与i++的根本性区别(两个代码对比搞定)

首先来看i 代码如下&#xff1a; #include <stdio.h> #include <stdlib.h> int main() {int i0;int ai;printf("%d\n",a);printf("%d\n\n\n",i);return 0; }输出结果如下&#xff1a; 解释&#xff1a;i其实是两行代码的简写形式&#xff0c…

Python | 使用matplotlib.pyplot创建线图

Problem statement: Write a program in python (using matplotlib.pyplot) to create a line plot. 问题陈述&#xff1a;用python编写程序(使用matplotlib.pyplot)以创建线图。 Program: 程序&#xff1a; import matplotlib.pyplot as pltx [1,2,3,4,5,6,7,8,9,10]y [3,…