STM32F1与STM32CubeIDE编程实例-CMSIS-RTOS V2-定时器管理

定时器管理

CMSIS-RTOS v2 (CMSIS-RTOS2) 为基于 Arm® Cortex® 处理器的设备提供通用 RTOS 接口。 它为需要 RTOS 功能的软件组件提供标准化 API,从而为用户和软件行业带来巨大的好处。

本文将详细介绍,在CMSIS-RTOS V2中如何使用定时器。

1、CMSIS-RTOS V2定时器介绍

除了通用延时函数之外,CMSIS-RTOS 还支持虚拟定时器对象。 这些定时器对象可以触发函数(不是线程)的执行。 当定时器到期时,将执行回调函数以运行与定时器相关的代码。 每个定时器都可以配置为一次性或周期性定时器。 周期性定时器重复其操作,直到它被删除或停止。 所有定时器都可以启动、重新启动或停止。

1
2
3
4
注意:
1)、RTX 在线程 osRtxTimerThread 中处理定时器。 回调函数在此线程的控制下运行,并且可能使用其他 CMSIS-RTOS API 调用。 osRtxTimerThread 在 Timer Configuration 中配置。
2)、定时器管理函数不能从中断服务程序中调用。

下图显示了周期性定时器的行为。 对于一次性定时器,定时器在回调函数执行后停止。

在这里插入图片描述

CMSIS-RTOS V2对定时器管理提供了如下函数:

  • osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr):

函数 osTimerNew 创建一次性或周期性定时器,并将其与带有参数的回调函数相关联。 定时器在使用 osTimerStart 启动之前处于停止状态。 该函数可以在 RTOS 启动之前安全调用(调用 osKernelStart),但不能在初始化之前调用(调用 osKernelInitialize)。

函数 osTimerNew 返回指向定时器对象标识符的指针,如果发生错误,则返回 NULL。

其参数说明如下:

+ func: 函数指向回调函数的指针。
+ osTimerOnce: 用于一次性或 osTimerPeriodic 用于周期性行为。
+ argument:定时器回调函数的参数。
+ attr: 定时器属性; NULL:默认值。`注意:不能从中断服务程序调用此函数`

简单示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "cmsis\_os2.h"

void Timer1\_Callback (void \*arg); // prototypes for timer callback function
void Timer2\_Callback (void \*arg); // prototypes for timer callback function

uint32\_t exec1; // argument for the timer call back function
uint32\_t exec2; // argument for the timer call back function

void TimerCreate\_example (void) {
osTimerId\_t id1; // timer id
osTimerId\_t id2; // timer id

// Create one-shoot timer
exec1 = 1U;
id1 = osTimerNew(Timer1_Callback, osTimerOnce, &exec1, NULL);
if (id1 != NULL) {
// One-shoot timer created
}

// Create periodic timer
exec2 = 2U;
id2 = osTimerNew(Timer2_Callback, osTimerPeriodic, &exec2, NULL);
if (id2 != NULL) {
// Periodic timer created
}
:
}

  • **const char * osTimerGetName (osTimerId_t timer_id)**:返回定时器名称

  • **osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks)**:启动或重新启动由参数 timer_id 指定的计时器。 参数 ticks 以时间刻度指定计时器的值。可能的 osStatus_t 返回值:

    • osOK:指定的定时器已经启动或重启。
    • osErrorISR:无法从中断服务例程调用 osTimerStart。
    • osErrorParameter:参数 timer_id 为 NULL 或无效或刻度不正确。
    • osErrorResource:定时器处于无效状态。

​ 简单示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "cmsis\_os2.h"

void Timer\_Callback (void \*arg) { // timer callback function
// arg contains &exec
// called every second after osTimerStart
}

uint32\_t exec; // argument for the timer call back function

void TimerStart\_example (void) {
osTimerId\_t id; // timer id
uint32\_t timerDelay; // timer value
osStatus\_t status; // function return status

// Create periodic timer
exec = 1U;
id = osTimerNew(Timer_Callback, osTimerPeriodic, &exec, NULL);
if (id != NULL) {
timerDelay = 1000U;
status = osTimerStart(id, timerDelay); // start timer
if (status != osOK) {
// Timer could not be started
}
}
;
}

  • **osStatus_t osTimerStop (osTimerId_t timer_id)**:停止定时器,可能的 osStatus_t 返回值:

    • osOK:指定的定时器已经停止。
    • osErrorISR:无法从中断服务例程调用 osTimerStop。
    • osErrorParameter:参数 timer_id 为 NULL 或无效。
    • osErrorResource:定时器没有运行(只能停止一个正在运行的定时器)。

简单示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "cmsis\_os2.h"

void Timer\_Callback (void \*arg); // prototype for timer callback function

uint32\_t exec; // argument for the timer call back function

void TimerStop\_example (void) {
osTimerId\_t id; // timer id
osStatus\_t status; // function return status

// Create periodic timer
exec = 1U;
id = osTimerNew(Timer_Callback, osTimerPeriodic, &exec, NULL);
osTimerStart(id, 1000U); // start timer
:
status = osTimerStop(id); // stop timer
if (status != osOK) {
// Timer could not be stopped
}
;
osTimerStart(id, 1000U); // start timer again
;
}

  • **uint32_t osTimerIsRunning (osTimerId_t timer_id)**:检查参数 timer_id 指定的定时器是否正在运行。 如果计时器正在运行,则返回 1,如果计时器停止或发生错误,则返回 0。

  • **osStatus_t osTimerDelete (osTimerId_t timer_id)**:删除由参数 timer_id 指定的定时器。可能的 osStatus_t 返回值:

    • osOK:指定的定时器已被删除。
    • osErrorISR:无法从中断服务例程调用 osTimerDelete。
    • osErrorParameter:参数 timer_id 为 NULL 或无效。
    • osErrorResource:定时器处于无效状态。注意:不能从中断服务程序调用此函数

简单示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "cmsis\_os2.h"

void Timer\_Callback (void \*arg); // prototype for timer callback function

uint32\_t exec; // argument for the timer call back function

void TimerDelete\_example (void) {
osTimerId\_t id; // timer id
osStatus\_t status; // function return status

// Create periodic timer
exec = 1U;
id = osTimerNew(Timer_Callback, osTimerPeriodic, &exec, NULL);
osTimerStart(id, 1000U); // start timer
;
status = osTimerDelete(id); // stop and delete timer
if (status != osOK) {
// Timer could not be deleted
}
;
}

2、在STM32CubeIDE中配置定时器

第一步: 新建工程

新建工程,请参考前面文章:

串口配置,请参考前面文章:

第二步: 配置时钟

配置时钟,请参考前面文章:

第三步:配置FreeRTOS

配置FreeRTOS,及FreeRTOS的堆栈,请参考:

第四步:添加定时器

在这里插入图片描述

在这里插入图片描述

可根据需求填写Timer NameCallback等。

在这里插入图片描述

定义了两个定时器,一个是osTimerPeriodic,一处是osTimerOnce

第五步:保存生成代码

3、定时器回调代码实现

main.c文件的main函数中,RTOS启动调用如下:

1
2
3
4
5
6
7
/\* Init scheduler \*/
osKernelInitialize(); /\* Call init function for freertos objects (in freertos.c) \*/
MX\_FREERTOS\_Init();

/\* Start scheduler \*/
osKernelStart();

freertos.c文件中,生成定义的定时器如下:

1
2
3
4
5
6
7
8
9
10
11
/\* Definitions for ledBlink \*/
osTimerId\_t ledBlinkHandle;
const osTimerAttr\_t ledBlink_attributes = {
.name = "ledBlink"
};
/\* Definitions for ledOn \*/
osTimerId\_t ledOnHandle;
const osTimerAttr\_t ledOn_attributes = {
.name = "ledOn"
};

freertos.c文件中,生成定义的定时器回调函数如下:

1
2
3
void ledBlinkTask(void \*argument);
void ledOnCallback(void \*argument);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/\* ledBlinkTask function \*/
void ledBlinkTask(void \*argument)
{
/\* USER CODE BEGIN ledBlinkTask \*/

/\* USER CODE END ledBlinkTask \*/
}

/\* ledOnCallback function \*/
void ledOnCallback(void \*argument)
{
/\* USER CODE BEGIN ledOnCallback \*/

/\* USER CODE END ledOnCallback \*/
}

MX_FREERTOS_Init函数中启动定时器:

1
2
3
4
5
6
7
/\* Create the timer(s) \*/
/\* creation of ledBlink \*/
ledBlinkHandle = osTimerNew(ledBlinkTask, osTimerPeriodic, NULL, &ledBlink_attributes);

/\* creation of ledOn \*/
ledOnHandle = osTimerNew(ledOnCallback, osTimerOnce, NULL, &ledOn_attributes);

STM32CubeIDE帮助我们生成了整个与定时器管理相关的脚手加代码,接下来,只需要在定时器回调函数中实现需要的功能即可。

比如,定义的定时器回调函数中,实现的功能如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/\* ledBlinkTask function \*/
void ledBlinkTask(void \*argument) {
/\* USER CODE BEGIN ledBlinkTask \*/
printf("led blink\r\n");
HAL\_GPIO\_TogglePin(LED2_GPIO_Port, LED2_Pin);
/\* USER CODE END ledBlinkTask \*/
}

/\* ledOnCallback function \*/
void ledOnCallback(void \*argument) {
/\* USER CODE BEGIN ledOnCallback \*/
printf("-------------led on-----------\r\n");
HAL\_GPIO\_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
/\* USER CODE END ledOnCallback \*/
}

ledBlinkTaskledOnCallback函数中,分别对LED进行点亮、关闭操作和点亮操作。关于GPIO的设置,请参考:

最后编译生成固件并下载到开发板中。

4、STM32F1与STM32CubeIDE快速入门系列文章

序号 内容
1 STM32F1与STM32CubeIDE快速入门-开发环境搭建
2 STM32F1与STM32CubeIDE快速入门-STM32F1微控制器概述
3 STM32F1与STM32CubeIDE快速入门-GPIO概述与点亮LED
4 STM32F1与STM32CubeIDE快速入门-按键与LED控制
5 STM32F1与STM32CubeIDE快速入门-中断、NVIC与EXTI概述
6 STM32F1与STM32CubeIDE快速入门-外部中断配置与功能实现
7 STM32F1与STM32CubeIDE快速入门-USART/UART串口通信
8 STM32F1与STM32CubeIDE快速入门-定时器(Timer)概述
9 STM32F1与STM32CubeIDE快速入门-定时器定时模式
10 STM32F1与STM32CubeIDE快速入门-定时器计数模式
11 STM32F1与STM32CubeIDE快速入门-定时器PWM模式
12 STM32F1与STM32CubeIDE快速入门-定时器编码(Encoder)模式
13 STM32F1与STM32CubeIDE快速入门-定时器输入捕获模式(Input Capture Mode)实现频率计数
14 STM32F1与STM32CubeIDE快速入门-DMA概述
15 STM32F1与STM32CubeIDE快速入门-USART通过DMA进行数据接收与发送
16 STM32F1与STM32CubeIDE快速入门-ADC概述
17 STM32F1与STM32CubeIDE快速入门-ADC轮询方式实现PWM调光器
18 STM32F1与STM32CubeIDE快速入门-ADC中断方式实现PWM调光器
19 STM32F1与STM32CubeIDE快速入门-ADC通过DMA方式与PWM实现调光器
20 STM32F1与STM32CubeIDE快速入门-DAC概述
21 STM32F1与STM32CubeIDE快速入门-SPI概述
22 STM32F1与STM32CubeIDE快速入门-M25P16串行闪存驱动
23 STM32F1与STM32CubeIDE快速入门-I2C概述
24 STM32F1与STM32CubeIDE快速入门-I2C驱动LCD1602显示屏(基于PCF8574)
25 STM32F1与STM32CubeIDE快速入门-独立看门狗(IWDG)
26 STM32F1与STM32CubeIDE快速入门-OLED-SSD1306-I2C驱动
27 STM32F1与STM32CubeIDE编程实例-CMSIS-RTOS V2配置(基于FreeRTOS)
28 STM32F1与STM32CubeIDE编程实例-CMSIS-RTOS V2-线程管理
29 STM32F1与STM32CubeIDE编程实例-CMSIS-RTOS v2-延时

文章来源: https://iotsmart.blog.csdn.net/article/details/124645963