【FreeRtos教程九】STM32 CubeMx——Timers(定时器)

目录

1 软件定时器

2 示例程序

2.1 例程功能 

2.2 步骤

2.3 实验结果

2.4 函数讲解

2.5 程序源码


1 软件定时器

定时器是MCU常用的外设,我们在学习各种单片机时必然会学习它的硬件定时器。但是,MCU自带的硬件定时器资源是有限的,而且一般会用在实时性要求很强的地方。 在freeRTOS中提供了软件定时器的功能,来实现更多的定时器资源。
1. 软件定时器的特性
使用定时器跟使用手机闹钟是类似的:

  • 指定时间:启动定时器和运行回调函数,两者的间隔被称为定时器的周期(period)。
  • 指定类型,定时器有两种类型:
    • 一次性(One-shot timers): 这类定时器启动后,它的回调函数只会被调用一次; 可以手工再次启动它,但是不会自动启动它。
    • 自动加载定时器(Auto-reload timers ): 这类定时器启动后,时间到之后它会自动启动它; 这使得回调函数被周期性地调用。
  • 指定要做什么事,就是指定回调函数

实际的闹钟分为:有效、无效两类。软件定时器也是类似的,它由两种状态:

  • 运行(Running、Active):运行态的定时器,当指定时间到达之后,它的回调函数会被调用
  • 冬眠(Dormant):冬眠态的定时器还可以通过句柄来访问它,但是它不再运行,它的回调函数不会 被调用

2.回调函数
定时器的回调函数的原型如下:

void ATimerCallback( TimerHandle_t xTimer );

定时器的回调函数是在守护任务中被调用的,守护任务不是专为某个定时器服务的,它还要处理其他定时器。 所以,定时器的回调函数不要影响其他人:

  • 回调函数要尽快实行,不能进入阻塞状态
  • 不要调用会导致阻塞的API函数,比如 vTaskDelay()
  • 可以调用 xQueueReceive() 之类的函数,但是超时时间要设为0:即刻返回,不可阻塞

2 示例程序

2.1 例程功能 

创建周期定时器,在定时器回调函数中添加串口打印的程序,定时器计数时间到了就打印当前计数值。

2.2 步骤

 默认任务保持不变

在Config parameters中使能定时器,定时器的优先级、队列长度和栈的深度按默认的来,注意定时器的优先级要比默认仍无的优先级高

 添加一个周期定时器

在FREERTOS初始化函数中开启定时器,定时时间设置为1s

void MX_FREERTOS_Init(void) {
    
//..........
    
  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
    osTimerStart(myTimer01Handle,1000);
  /* USER CODE END RTOS_TIMERS */    
//..........

}

在定时器回调中打印当前定时器的计数值

/* Callback01 function */
void Callback01(void const * argument)
{
  /* USER CODE BEGIN Callback01 */
  printf("\n定时器%d\n",osKernelSysTick());
  /* USER CODE END Callback01 */
}

2.3 实验结果

 可见回调函数每隔1000ms执行一次

2.4 函数讲解

osStatus osTimerStart (osTimerId timer_id, uint32_t millisec)

/**
@brief  Start or restart a timer.
@param  timer_id      timer ID obtained by \ref osTimerCreate.
@param  millisec      time delay value of the timer.
@retval  status code that indicates the execution status of the function
@note   MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
*/
osStatus osTimerStart (osTimerId timer_id, uint32_t millisec)
  • 函数功能:开始或重启定时器
  • 传入参数:1、timer_id(要开启定时器的句柄)2、millisec(定时器记时时间)

uint32_t osKernelSysTick(void) 

/**
@brief  Get the value of the Kernel SysTick timer
@param  None
@retval None
@note   MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
*/
uint32_t osKernelSysTick(void)
  • 函数功能:获取内核SysTick定时器的值

自我感悟

typedef enum  {
  osPriorityIdle          = -3,          ///< priority: idle (lowest)
  osPriorityLow           = -2,          ///< priority: low
  osPriorityBelowNormal   = -1,          ///< priority: below normal
  osPriorityNormal        =  0,          ///< priority: normal (default)
  osPriorityAboveNormal   = +1,          ///< priority: above normal
  osPriorityHigh          = +2,          ///< priority: high
  osPriorityRealtime      = +3,          ///< priority: realtime (highest)
  osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal                                                  ///<priority
} osPriority;

defaultTask的优先级为,即为0,myTimer01的优先级为2,满使用FreeRtos的定时器的编程规范

2.5 程序源码

github链接:HaoJosephWen/FreeRtos_personal (github.com)

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值