IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 八、FreeRTOS 软件定时器 -> 正文阅读

[嵌入式]八、FreeRTOS 软件定时器

基本概念

软件定时器类似于单片机的定时中断,但是精度和优先级不如硬件定时器。支持单次模式(只执行一次)和周期模式。精度为x个tick

注意事项

函数接口讲解

xTimerCreate()?软件定时器创建函数

xTimerStart()软件定时器启动函数

软件定时器在创建完成的时候是处于休眠状态的,需要用 FreeRTOS 的相关函数将软件定时器活动起来,而 xTimerStart()函数就是可以让处于休眠的定时器开始工作。

xTimerStop()软件定时器停止函数
xTimerStop() 用于停止一个已经启动的软件定时器, 该函数的实现也是通过“定时器命令队列”发送一个停止命令给软件定时器任务,从而唤醒软件定时器任务去将定时器停止。

xTimerDelete()?软件定时器删除函数

?xTimerDelete()用于删除一个已经被创建成功的软件定时器, 删除之后就无法使用该定
时器, 并且定时器相应的资源也会被系统回收释放。

软件定时器实验

?软件定时器实验:使用软件定时器设置定时任务,当定时器到了事件就执行回调函数,回调函数相当于定时器中断函数(软件定义,事件没有硬件定时器精确),回调函数中的内容要尽可能精简,不能出现阻塞和死循环。
实验现象:每隔一秒循环执行Swtmr1_Callback() 第五秒执行Swtmr2_Callback(),只执行一次;

main.c 如下

#include "stm32f10x.h"


#include "EXC_Gpio.h"
#include "EXC_Usart.h"  
#include "EXC_Led.h"
#include "EXC_Key.h"

/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "event_groups.h"


/**************************** 任务句柄 ********************************/
/* 
 * 任务句柄是一个指针,用于指向一个任务,当任务创建好之后,它就具有了一个任务句柄
 * 以后我们要想操作这个任务都需要通过这个任务句柄,如果是自身的任务操作自己,那么
 * 这个句柄可以为NULL。
 */
 /* 创建任务句柄 */
static TaskHandle_t AppTaskCreate_Handle;

/********************************** 内核对象句柄 *********************************/
/*
 * 信号量,消息队列,事件标志组,软件定时器这些都属于内核的对象,要想使用这些内核
 * 对象,必须先创建,创建成功之后会返回一个相应的句柄。实际上就是一个指针,后续我
 * 们就可以通过这个句柄操作这些内核对象。
 *
 * 内核对象说白了就是一种全局的数据结构,通过这些数据结构我们可以实现任务间的通信,
 * 任务间的事件同步等各种功能。至于这些功能的实现我们是通过调用这些内核对象的函数
 * 来完成的
 * 
 */

static TimerHandle_t Swtmr1_Handle =NULL;/*软件定时器句柄*/
static TimerHandle_t Swtmr2_Handle =NULL;/*软件定时器句柄*/


 /************************** 宏定义 *********************************/
 /*
  * 当我们在写应用程序的时候,可能需要用到一些宏定义。
  */
 
/*
*************************************************************************
*                             函数声明
*************************************************************************
*/
static void AppTaskCreate(void);/* 用于创建任务 */

static void Swtmr1_Callback(void* pvParameters);/*Swtmr1_Task任务实现 */

static void Swtmr2_Callback(void* pvParameters);/* Swtmr1_Task任务实现 */


static void BSP_Init(void);/* 用于初始化板载相关资源 */





/*****************************************************************
  * @brief  主函数
  * @param  无
  * @retval 无
  * @note   第一步:开发板硬件初始化 
            第二步:创建APP应用任务
            第三步:启动FreeRTOS,开始多任务调度
  ****************************************************************/

int main(void)
{
    BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */
	BSP_Init();
   /* 创建 AppTaskCreate 任务 */
	xReturn = xTaskCreate((TaskFunction_t	)AppTaskCreate,		//任务函数
                        (const char* 	)"AppTaskCreate",		//任务名称
                        (uint32_t 		)256,	//任务堆栈大小
                        (void* 		  	)NULL,				//传递给任务函数的参数
                        (UBaseType_t 	)3, 	//任务优先级
                        (TaskHandle_t*   )AppTaskCreate_Handle);	//任务控制块指针
                            //任务控制块
    if(pdPASS == xReturn)/* 创建成功 */
    {
        vTaskStartScheduler();   /* 启动任务,开启调度 */

    }  
    else
    {
        return -1;        
    }
	while(1)
	{


	}
	
	
}

/***********************************************************************
  * @ 函数名  : AppTaskCreate
  * @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
  * @ 参数    : 无  
  * @ 返回值  : 无
  **********************************************************************/
static void AppTaskCreate(void)
{
    taskENTER_CRITICAL();           //进入临界区

   
    Swtmr1_Handle=xTimerCreate((const char* ) "AutoReloadTimer",
                            (TickType_t) 1000,/*定时器周期1000(tick)*/
                            (UBaseType_t)pdTRUE,/*周期模式*/
                            (void*)1,/*为每个计时器分配一个索引的唯一ID */
                            ( TimerCallbackFunction_t)Swtmr1_Callback);
    if(Swtmr1_Handle != NULL)
    {
        /***************************************************************
         *xTicksTowait:如果在调用xTimerstart()时队列已满,则以tick 为单位指定调
          用任务应保持在Blocked(阻塞)状态以等待start命令成功发送到 timer命令队列的时间。
         *如果在启动调度程序之前调用xTimerstart(),则忽略xTicksTowait。在这里设置等待时间为0
         ***************************************************************/

        xTimerStart(Swtmr1_Handle,0); //开启周期定时器
    }

      Swtmr2_Handle=xTimerCreate((const char* ) "AutoReloadTimer",
                            (TickType_t) 5000,/*定时器周期1000(tick)*/
                            (UBaseType_t)pdFALSE,/*单次模式*/
                            (void*)1,/*为每个计时器分配一个索引的唯一ID */
                            ( TimerCallbackFunction_t)Swtmr2_Callback);
    if(Swtmr2_Handle != NULL)
    {
        /***************************************************************
         *xTicksTowait:如果在调用xTimerstart()时队列已满,则以tick 为单位指定调
          用任务应保持在Blocked(阻塞)状态以等待start命令成功发送到 timer命令队列的时间。
         *如果在启动调度程序之前调用xTimerstart(),则忽略xTicksTowait。在这里设置等待时间为0
         ***************************************************************/

        xTimerStart(Swtmr2_Handle,0); //开启周期定时器
    }
  vTaskDelete(AppTaskCreate_Handle); //删除AppTaskCreate任务
  
  taskEXIT_CRITICAL();            //退出临界区
}


/**********************************************************************
  * @ 函数名  : Swtmr1_Callback
  * @ 功能说明: Swtmr1_Callback 任务主体
  * @ 参数    :   
  * @ 返回值  : 无
  * @ Note    :  定时器回调函数因该尽可能短,不能出现阻塞和死循环 
  ********************************************************************/
static void Swtmr1_Callback(void* parameter)
{	
    static int TmrCb_Count1;
    TickType_t tick_num1;
    TmrCb_Count1++; /* 每回调一次加一 */
    tick_num1 = xTaskGetTickCount(); /* 获取滴答定时器的计数值 */
    LED1_TOGGLE;
    printf("Swtmr1_Callback 函数执行 %d 次\r\n", TmrCb_Count1);
    printf("滴答定时器数值=%d\r\n", tick_num1);
}

/**********************************************************************
  * @ 函数名  : Swtmr2_Callback
  * @ 功能说明: Swtmr2_Callback 任务主体
  * @ 参数    :   
  * @ 返回值  : 无
  * @ Note    :  定时器回调函数因该尽可能短,不能出现阻塞和死循环 
  ********************************************************************/
static void Swtmr2_Callback(void* parameter)
{	
    static int TmrCb_Count2;
    TickType_t tick_num1;
    TmrCb_Count2++; /* 每回调一次加一 */
    tick_num1 = xTaskGetTickCount(); /* 获取滴答定时器的计数值 */
    LED3Color_Set(LEDRED);
    printf("Swtmr2_Callback 函数执行 %d 次\r\n", TmrCb_Count2);
    printf("滴答定时器数值=%d\r\n", tick_num1);
}


/***********************************************************************
  * @ 函数名  : BSP_Init
  * @ 功能说明: 板级外设初始化,所有板子上的初始化均可放在这个函数里面
  * @ 参数    :   
  * @ 返回值  : 无
  *********************************************************************/
static void BSP_Init(void)
{
	/*
	 * STM32中断优先级分组为4,即4bit都用来表示抢占优先级,范围为:0~15
	 * 优先级分组只需要分组一次即可,以后如果有其他的任务需要用到中断,
	 * 都统一用这个优先级分组,千万不要再分组,切忌。
	 */

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    USART_init(SYSTEM_UART,115200,1);
    printf("串口初始化成功\r\n");
    /* LED 初始化 */
    LED3Color_Init(LEDBLUE);

    Key_Init(K1);
    Key_Init(K2);
    ILI9341_Init();
    LCD_SetFont(&Font8x16);
    LCD_SetColors(RED,BLACK);
    ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);	/* 清屏,显示全黑 */
    ILI9341_DispString_EN(50,0,"Hello world!");

}
 



/********************************END OF FILE****************************/

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-06-25 18:19:04  更:2022-06-25 18:19:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 0:40:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码