STM32F4X UCOSIII软件定时器
定时器概念
定时器在MCU中是一个很常用的外设,其作用是可以在某个事件点触发MCU中断,告知MCU处理事情。定时器跟生活中的闹钟很类似,可以设置闹钟每天什么时候响,还能设置响的次数,是响一次还是每天都响。定时器也有硬件定时器和软件定时器之分。
硬件定时器
硬件定时器通常是MCU的内部资源,当用户需要使用硬件定时器时,需要配置硬件定时器的分频系数,重装载数,使其满足用户的需要。硬件定时器的精度一般都很高,可以达到纳秒级别,而且硬件定时器通常跟中断一起配合使用。缺点就是硬件定时器资源有限,配置也比较复杂。
软件定时器
软件定时器是由操作系统提供的一类系统接口,软件定时器是基于硬件定时器之上,使系统可以不受硬件定时器的资源限制,理论上只要系统的存储空间充足,用户就可以创建很多的软件定时器。软件定时器通常会绑定一个回调函数,当定时时间到的时候,就调用回调函数,相当于硬件定时器的中断。
UCOSIII软件定时器
UCOSIII支持软件定时器,在MCU资源允许的情况下,用户可以创建多个软件定时器,UCOSIII的软件定时器有以下特点。
UCOSIII软件定时器运行模式
UCOSIII软件定时器的运行模式有两种,分别是单次模式和周期模式,两种模式的区别如下
- 单次模式:软件定时器的定时时间到了之后,只会执行一次回调函数,然后就不会继续执行,用户可以再次调用OSTmrStart函数继续执行
- 周期模式:软件定时器开始工作后,会按照设定的定时时间循环运行。
上图设置两个定时器,其中定时器1定时时间是200个tick,周期运行。定时器2定时时间是100个tick,单次运行。定时器开始运行后,当定时2达到定时时间时,会调用一次回调函数然后就停止,定时器1则会循环执行。
UCOSIII软件定时器周期模式
UCOSIII中软件定时器的周期模式也有两种,一种是初始化延时,一种是无初始化延时
- 初始化延时:在软件定时器创建的时候,其第一个定时周期是由定时器中的 dly 参数决定,然后在运行完第一个周期后,其以后的定时周期均由period 参数决定。
- 无初始化延时:定时器一直按周期运行
上图设置两个定时器,其中定时器1定时时间是100个tick,周期运行。定时器2定时的初始化周期是150tick,周期是100tick。定时器开始运行后,当定时2达到初始化周期时会调用一次回调函数,之后定时器2就会按照100tick的定时周期循环运行。而定时器1则会按照100tick定时周期循环执行。
UCOSIII软件定时器API
软件定时器创建函数
/*
* p_tmr:定时器对象
* p_name:定时器名字
* dly:定时器初始值
* period:定时器周期
* opt:用户选项
* p_callback:回调函数
* p_callback_arg:回调函数参数
* p_err:错误代码
*/
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)
其中opt可以选择OS_OPT_TMR_ONE_SHOT和OS_OPT_TMR_PERIODIC
- OS_OPT_TMR_ONE_SHOT:单次模式
- OS_OPT_TMR_PERIODIC:周期模式
软件定时器启动函数
/*
* p_tmr:定时器对象
* p_err:错误代码
返回值 : DEF_TRUE:定时器开始运行
DEF_FALSE:没有定时器
*/
CPU_BOOLEAN OSTmrStart (OS_TMR *p_tmr,
OS_ERR *p_err)
定时器停止函数
/*
* p_tmr:定时器对象
* opt:用户选项
* p_callback_arg:用户新设置的回电函数参数
* p_err:错误代码
返回值 : DEF_TRUE:定时器停止成功
DEF_FALSE:定时器失败
*/
CPU_BOOLEAN OSTmrStop (OS_TMR *p_tmr,
OS_OPT opt,
void *p_callback_arg,
OS_ERR *p_err)
opt参数可以选择OS_OPT_TMR_NONE、OS_OPT_TMR_CALLBACK和OS_OPT_TMR_CALLBACK_ARG
- OS_OPT_TMR_NONE:直接停止定时器,不做任何操作
- OS_OPT_TMR_CALLBACK:在停止定时器前再执行一次回调函数
- OS_OPT_TMR_CALLBACK_ARG:在停止定时器前再执行一次回调函数,并且可以设置新参数
定时器删除函数
/*
* p_tmr:定时器对象
* p_err:错误代码
返回值 : DEF_TRUE:定时器已经删除
DEF_FALSE:没有定时器
*/
CPU_BOOLEAN OSTmrDel (OS_TMR *p_tmr,
OS_ERR *p_err)
UCOSIII软件定时器例程
/*
*********************************************************************************************************
* EXAMPLE CODE
*
* (c) Copyright 2013; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
* Knowledge of the source code may not be used to write a similar
* product. This file may only be used in accordance with a license
* and should not be redistributed in any way.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* EXAMPLE CODE
*
* IAR Development Kits
* on the
*
* STM32F429II-SK KICKSTART KIT
*
* Filename : app.c
* Version : V1.00
* Programmer(s) : YS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#include <includes.h>
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
/* ----------------- APPLICATION GLOBALS -------------- */
static OS_TCB AppTaskStartTCB;
static CPU_STK AppTaskStartStk[APP_CFG_TASK_START_STK_SIZE];
static OS_TMR timr1;
static void timr1_callback_func(void *p_tmr, void *p_arg);
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
static void AppTaskStart (void *p_arg);
/*
*********************************************************************************************************
* main()
*
* Description : This is the standard entry point for C code. It is assumed that your code will call
* main() once you have performed all necessary initialization.
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
int main(void)
{
OS_ERR err;
OSInit(&err); /* Init uC/OS-III. */
OSTaskCreate((OS_TCB *)&AppTaskStartTCB, /* Create the start task */
(CPU_CHAR *)"App Task Start",
(OS_TASK_PTR )AppTaskStart,
(void *)0u,
(OS_PRIO )APP_CFG_TASK_START_PRIO,
(CPU_STK *)&AppTaskStartStk[0u],
(CPU_STK_SIZE )AppTaskStartStk[APP_CFG_TASK_START_STK_SIZE / 10u],
(CPU_STK_SIZE )APP_CFG_TASK_START_STK_SIZE,
(OS_MSG_QTY )0u,
(OS_TICK )0u,
(void *)0u,
(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
(OS_ERR *)&err);
OSStart(&err); /* Start multitasking (i.e. give control to uC/OS-III). */
}
/*
*********************************************************************************************************
* STARTUP TASK
*
* Description : This is an example of a startup task. As mentioned in the book's text, you MUST
* initialize the ticker only once multitasking has started.
*
* Arguments : p_arg is the argument passed to 'AppTaskStart()' by 'OSTaskCreate()'.
*
* Returns : none
*
* Notes : 1) The first line of code is used to prevent a compiler warning because 'p_arg' is not
* used. The compiler should not generate any code for this statement.
*********************************************************************************************************
*/
static void AppTaskStart (void *p_arg)
{
CPU_INT32U cpu_clk_freq;
CPU_INT32U cnts;
OS_ERR err;
(void)p_arg;
BSP_Init();
CPU_Init(); /* Initialize the uC/CPU services */
cpu_clk_freq = BSP_CPU_ClkFreq(); /* Determine SysTick reference freq. */
cnts = cpu_clk_freq /* Determine nbr SysTick increments */
/ (CPU_INT32U)OSCfg_TickRate_Hz;
OS_CPU_SysTickInit(cnts); /* Init uC/OS periodic time src (SysTick). */
Mem_Init(); /* Initialize memory managment module */
Math_Init(); /* Initialize mathematical module */
#if OS_CFG_STAT_TASK_EN > 0u
OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
CPU_IntDisMeasMaxCurReset();
#endif
#if (APP_CFG_SERIAL_EN == DEF_ENABLED)
App_SerialInit(); /* Initialize Serial communication for application ... */
#endif
OSTmrCreate(&timr1,
(CPU_CHAR*)"timr1",
(OS_TICK)100,
(OS_TICK)100,
(OS_OPT)OS_OPT_TMR_PERIODIC, // 周期定时
(OS_TMR_CALLBACK_PTR)timr1_callback_func, // 定时器回调函数
"timer callback", // 定时器回调函数参数
&err);
if(err == OS_ERR_NONE)
{
printf("timr1 Create Success\r\n");
OSTmrStart(&timr1,&err); // 定时器开始工作
}
else
printf("timr1 Create Fail\r\n");
OSTaskDel ( & AppTaskStartTCB, & err );
}
static void timr1_callback_func(void *p_tmr, void *p_arg)
{
printf("%s\r\n",p_arg);
}