stm32cubemx hal学习记录:FreeRTOS软件定时器

一、配置过程

1、配置RCC、USART1、时钟84M

2、配置SYS,将Timebase Source修改为除滴答定时器外的其他定时器。

3、初始化LED的两个引脚、两个按键引脚

4、开启FreeRTOS,v1与v2版本不同,一般选用v1即可

5、打开定时器选项

 6、创建两个定时器,一个周期定时器,一个单次定时器

 Timer Name: 定时器名称
Callback: 回调函数名称
Type: 定时器类型,osTimerPeriodic周期定时器,osTimerOnce单次定时器
Code Generation Option: 代码生成选项
Parameter: 回调函数形参,不用的时候配置为0或NULL即可
Allocation: 分配方式:Dynamic 动态内存创建
Conrol Block Name: 控制块名称

7、生成代码

二、API

1、创建软件定时器:osTimerCreate

osTimerId timer01_stackHandle;

osTimerDef(timer01_stack, timer01_thread_entry);
timer01_stackHandle = osTimerCreate(osTimer(timer01_stack), osTimerPeriodic, NULL);

2、启动定时器:osTimerStart,可以在中断中使用,单位为ms

osTimerStart(timer01_stackHandle,1000);

3、停止定时器:osTimerStop,可以在中断中使用

osTimerStop(timer01_stackHandle);

4、删除定时器

osTimerDelete(timer01_stackHandle)

三、代码使用

1、在函数void StartDefaultTask(void const * argument)中开启定时器

void StartDefaultTask(void const * argument)
{
  osTimerStart(timer01_stackHandle,1000);
  osTimerStart(timer02_stackHandle,2000);
	
  for(;;)
  {
    osDelay(1);
  }

}

2、在定时器1和定时器2中添加代码来验证定时器是否工作,定时器1设置的为循环定时器,定时器2设置的为单次定时器

TickType_t tick_num;
uint32_t a;
void timer01_thread_entry(void const * argument)
{
	tick_num=osKernelSysTick();
	a++;
}

TickType_t tick_num1;
uint32_t a1;
void timer02_thread_entry(void const * argument)
{
	tick_num1=osKernelSysTick();
	a1++;
}

进行debug后发现,开始执行后a的数值每秒增加1,tick_num每秒增加1000。a1在开始执行两秒后+1,tick_num=2000,且之后不再进行工作,因为timer2设置的为单次定时器。

### nRF52840 上使用 FreeRTOS定时器 当在 nRF52840 设备上配置并使用 FreeRTOS 时,了解如何正确设置和管理定时器至关重要。这不仅涉及到硬件资源的有效利用,还关系到系统的稳定性和性能优化。 #### 配置 FreeRTOS 的基础架构 为了使 FreeRTOS 能够高效运作于 nRF52840 平台上,需先掌握其核心组件——任务(Task)、信号量(Semaphore)、互斥锁(Mutex)、事件标志组(Event Flags),以及队列(Queue)[^2]。这些机制共同作用以支持多线程编程环境下的进程间通信与同步操作。 #### 设置 HAL 基础时钟 尽管上述信息主要针对 STM32 系列微控制器,但在其他平台如 nRF52840 中也有相似考量。对于基于 ARM Cortex-M 架构的设备而言,推荐采用独立于 SysTick 外设的时间基准源来驱动操作系统调度程序;这样做可以避免因中断优先级冲突而导致潜在问题的发生[^1]。 #### 实现 APP 定时器模块初始化 下面展示了一段简单的 C++ 代码片段,用于演示如何初始化应用程序级别的计时服务: ```cpp // 初始化APP定时器模块 static void timers_init(void){ // 初始化APP定时器模块 ret_code_t err_code = app_timer_init(); // 检查返回值 APP_ERROR_CHECK(err_code); } ``` 此函数通过调用 `app_timer_init()` 来启动 SDK 提供的标准时间管理功能,并借助宏定义 `APP_ERROR_CHECK` 对可能产生的错误情况进行处理[^3]。 #### 创建自定义周期性回调任务 接下来是一个更具体的例子,它展示了怎样建立一个每秒触发一次的任务实例: ```c #include "nrf.h" #include "app_error.h" #include "app_timer.h" #define ONE_SECOND_IN_MS (uint32_t)(1000) void my_periodic_task(void * p_context) { // 用户定义的具体逻辑放在这里... } int main() { uint32_t err_code; // 初始化定时器子系统 timers_init(); // 注册新的定时器句柄 static app_timer_id_t periodic_timer_id; // 创建具有固定间隔重复执行特性的软件定时器 err_code = app_timer_create(&periodic_timer_id, APP_TIMER_MODE_REPEATED, my_periodic_task); APP_ERROR_CHECK(err_code); // 启动该定时器,设定初始延迟时间为零毫秒 err_code = app_timer_start(periodic_timer_id, APP_TIMER_TICKS(ONE_SECOND_IN_MS), NULL); APP_ERROR_CHECK(err_code); while(true) { __WFE(); // 进入等待状态直到被唤醒 } } ``` 这段代码实现了如下目标: - **timers_init()**: 如前所述完成必要的准备工作; - **my_periodic_task()**: 自定义的工作负载函数体; - **main()**: 主循环里包含了创建及激活指定频率(即一秒)下自动重启型软定时器的过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值