网站页面设置,上海微信小程序开发公司,如何选择网站建设案例,WordPress生成海报插件一、软件定时器简介
1 、基本概念 定时器#xff0c;是指从指定的时刻开始#xff0c;经过一个指定时间#xff0c;然后触发一个超时事件#xff0c;用户 可以自定义定时器的周期与频率。类似生活中的闹钟#xff0c;我们可以设置闹钟每天什么时候响#xff0c; 还能设置…一、软件定时器简介
1 、基本概念 定时器是指从指定的时刻开始经过一个指定时间然后触发一个超时事件用户 可以自定义定时器的周期与频率。类似生活中的闹钟我们可以设置闹钟每天什么时候响 还能设置响的次数是响一次还是每天都响。 定时器有硬件定时器和软件定时器之分 硬件定时器是芯片本身提供的定时功能。一般是由外部晶振提供给芯片输入时钟芯 片向软件模块提供一组配置寄存器接受控制输入到达设定时间值后芯片中断控制器产 生时钟中断。硬件定时器的精度一般很高可以达到纳秒级别并且是中断触发方式。 软件定时器是由操作系统提供的一类系统接口它构建在硬件定时器基 础之上使系统能够提供不受硬件定时器资源限制的定时器服务它实现的功能与硬件定 时器也是类似的。 使用硬件定时器时每次在定时时间到达之后就会自动触发一个中断用户在中断中 处理信息而使用软件定时器时需要我们在创建软件定时器时指定时间到达后要调用的 函数也称超时函数/回调函数为了统一下文均用回调函数描述在回调函数中处理 信息。 注意软件定时器回调函数的上下文是任务下文所说的定时器均为软件定时器。 软件定时器在被创建之后当经过设定的时钟计数值后会触发用户定义的回调函数。 定时精度与系统时钟的周期有关。一般系统利用 SysTick 作为软件定时器的基础时钟软件定时器的回调函数类似硬件的中断服务函数所以回调函数也要快进快出而且回调函数中不能有任何阻塞任务运行的情况软件定时器回调函数的上下文环境是任务比如 vTaskDelay() 以及其它能阻塞任务运行的函数两次触发回调函数的时间间隔 xTimerPeriodInTicks 叫定时器的定时周期。 FreeRTOS 提供的软件定时器支持单次模式和周期模式单次模式和周期模式的定时时间到之后都会调用软件定时器的回调函数用户可以在回调函数中加入要执行的工程代码。
单次模式当用户创建了定时器并启动了定时器后定时时间到了只执行一次回调函数之后就将该定时器删除不再重新执行。周期模式这个定时器会按照设置的定时时间循环执行回调函数直到用户将定时器删除。 FreeRTOS 通过一个 prvTimerTask 任务也叫守护任务 Daemon管理软定时器它是在启动调度器时自动创建的为了满足用户定时需求。prvTimerTask 任务会在其执行期间检查用户启动的时间周期溢出的定时器并调用其回调函数。只有设置 FreeRTOSConfig.h 中的宏定义configUSE_TIMERS 设置为 1 将相关代码编译进来才能正常使用软件定时器相关功能。
2 、时间精度 在操作系统中通常软件定时器以系统节拍周期为计时单位。系统节拍是系统的心跳节拍表示系统时钟的频率就类似人的心跳1s 能跳动多少下系统节拍配置为 configTICK_RATE_HZ该宏在 FreeRTOSConfig.h 中有定义默认是 1000。那么系统的时钟节拍周期就为 1ms1s 跳动 1000 下每一下就为 1ms。软件定时器的所定时数值必须是这个节拍周期的整数倍例如节拍周期是 10ms那么上层软件定时器定时数值只能是10ms20ms100ms 等而不能取值为 15ms。由于节拍定义了系统中定时器能够分辨的精确度系统可以根据实际系统 CPU 的处理能力和实时性需求设置合适的数值系统节拍周期的值越小精度越高但是系统开销也将越大因为这代表在 1 秒中系统进入时钟中断的次数也就越多。
3、 注意要点
软件定时器的回调函数中应快进快出绝对不允许使用任何可能引软件定时器起任务挂起或者阻塞的 API 接口在回调函数中也绝对不允许出现死循环。软件定时器使用了系统的一个队列和一个任务资源软件定时器任务的优先级默认为 configTIMER_TASK_PRIORITY为了更好响应该优先级应设置为所有任务中最高的优先级。创建单次软件定时器该定时器超时执行完回调函数后系统会自动删除该软件定时器并回收资源。定时器任务的堆栈大小默认为 configTIMER_TASK_STACK_DEPTH 个字节。
4、软件定时器应用场景 在很多应用中我们需要一些定时器任务硬件定时器受硬件的限制数量上不足以 满足用户的实际需求无法提供更多的定时器那么可以采用软件定时器来完成由软件 定时器代替硬件定时器任务。但需要注意的是软件定时器的精度是无法和硬件定时器相比 的而且在软件定时器的定时过程中是极有可能被其它中断所打断因为软件定时器的执 行上下文环境是任务。所以软件定时器更适用于对时间精度要求不高的任务一些辅助 型的任务。
二、STM32CubeMX设置
1、配置RCC、USART1、时钟72M
2、配置SYS将Timebase Source修改为除滴答定时器外的其他定时器。
3、初始化LED的两个引脚
4、开启FreeRTOSv1与v2版本不同一般选用v1即可
5、创建两个线程任务LED1用作发送LED2用作接收。
以上步骤可参考STM32CubeMX学习笔记22---FreeRTOS任务创建和删除-CSDN博客
6、创建软件定时器Timer
要想使用软件定时器必须在 Config parameters 中把 USE_TIMERS 选择 Enabled 来使能。
在 Timers and Semaphores 中创建两个定时器一个周期定时器一个单次定时器。
Timer Name 定时器名称Callback 回调函数名称Type 定时器类型osTimerPeriodic周期定时器osTimerOnce单次定时器Code Generation Option 代码生成选项Parameter 回调函数形参不用的时候配置为0或NULL即可Allocation 分配方式Dynamic 动态内存创建Conrol Block Name 控制块名称
7、生成代码
三、相关API函数说明
1、创建软件定时器osTimerCreate
创建一个软件定时器并返回一个定时器ID。
例 osTimerId myTimer01Handle;
osTimerId myTimer02Handle;//创建周期定时器osTimerDef(myTimer01, Callback01);myTimer01Handle osTimerCreate(osTimer(myTimer01), osTimerPeriodic, NULL);//创建单次定时器osTimerDef(myTimer02, Callback02);myTimer02Handle osTimerCreate(osTimer(myTimer02), osTimerOnce, NULL); 2、启动定时器osTimerStart可以在中断中使用单位为ms
例
osTimerStart(myTimer01Handle,1000);
3、停止定时器osTimerStop
停止一个软件定时器让其进入休眠态。该函数可以在中断中使用。
函数osStatus osTimerStop (osTimerId timer_id)参数timer_id 定时器ID返回值错误码
例
osTimerStop(myTimer01Handle);
4、删除定时器
用于删除一个已经被创建成功的软件定时器删除之后就无法使用该定时器并且定时器相应的资源也会被系统回收释放。
函数osStatus osTimerDelete (osTimerId timer_id)参数timer_id 定时器ID返回值错误码
例
osTimerDelete(myTimer01Handle)
四、程序编程
在cubemx中设置了两个定时器会自动生成两个定时回调函数定时器需要执行的程序可以在回调函数中编写但在使用定时器之前需要开启一下定时器并设定定时时间。
1、在空闲任务中开启定时器将循环定时器定时1000ms单次定时器定时3000ms
void StartDefaultTask(void const * argument)
{/* USER CODE BEGIN StartDefaultTask *///开始软件定时器osTimerStart(myTimer01Handle, 1000);osTimerStart(myTimer02Handle, 3000);/* Infinite loop */for(;;){osDelay(1);}/* USER CODE END StartDefaultTask */
}
2、在定时器回调函数中编写程序。
void Callback01(void const * argument)
{/* USER CODE BEGIN Callback01 */static uint32_t TmrCb_Count1 0; /* 记录软件定时器 1 回调函数执行次数 */TickType_t tick_num1; TmrCb_Count1; /* 每回调一次加一 */ tick_num1 osKernelSysTick(); /* 获取滴答定时器的计数值 */ HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5); //LED1状态每500s翻转一次printf(定时器1 %dtick_num%d\n, TmrCb_Count1,tick_num1); /* USER CODE END Callback01 */
}/* Callback02 function */void Callback02(void const * argument)
{/* USER CODE BEGIN Callback02 */static uint32_t TmrCb_Count2 0; /* 记录软件定时器 2 回调函数执行次数 */TickType_t tick_num2; TmrCb_Count2; /* 每回调一次加一 */ tick_num2 osKernelSysTick(); /* 获取滴答定时器的计数值 */ HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5); //LED1状态每500s翻转一次printf(定时器2 %d,tick_num%d\n, TmrCb_Count2,tick_num2); /* USER CODE END Callback02 */
}下载验证
程序编译无误后下载到板子上查看串口输出可以看到定时器1每隔1000ms运行一次定时器2定时3000ms运行一次后不再运行了。 五 、参考文献
韦东山freeRTOS系列教程之【第十章】软件定时器(software timer)_xtimerstart-CSDN博客
STM32CubeMX学习笔记33——FreeRTOS实时操作系统使用软件定时器_freertos cubemx 会占用定时器几-CSDN博客
FreeRTOS软件定时器 基于STM32_xtimerstart-CSDN博客