uCOSIII实时操作系统 八 软件定时器

目录

软件定时器概述

使用步骤:

创建软件定时器:

启动软件定时器:

停止软件定时器:

删除软件定时器:

单次定时器:

​编辑周期定时器:

无初始化延时:

有初始化延时:

软件定时器实验:


软件定时器概述

在学习单片机的的时候,会使用定时器来做很多事情,这个定时器时单片机自带的也就是硬件定时器,而UCOSIII内核提供了一个模拟定时器的机制类似于任务,但是占用资源少,只能做一些简单的定时控制,如可以定时器喂狗控灯。在软件定时器中绝对不能添加事件管理函数,阻塞等待函数。

使用步骤:

创建软件定时器:

利用OSTmrCreate()函数,函数原型如下:

参数:

 p_tmr,                软件定时器对象

p_name,              软件定时器的名字

dly,                      启动定时器后,延迟多长时间执行,默认隐含dly10ms

period,                 定时周期,默认隐含period10ms

opt:                      模式

OS_OPT_TMR_ONE_SHOT,软件定时器执行一遍

OS_OPT_TMR_PERIODIC,软件定时器周期性执行

p_callback,          软件定时器执行的回调函数 void MyCallback (OS_TMR *p_tmr, void *p_arg);

p_callback_arg,   传递参数给软件定时器的回调函数

p_err,                   返回错误码,没有错误的就返回OS_ERR_NONE

启动软件定时器:

函数原型如下:

参数:

p_tmr :软件定时器对象

p_err  :返回错误码,没有错误就返回OS_ERR_NONE

返回值:

 DEF_TRUE is the timer was started

DEF_FALSE if not or upon an error

停止软件定时器:

函数原型如下:

参数:

p_tmr 软件定时器对象

os_opt 默认参数,OS_OPT_TMR_NONE

p_callback_arg 填写OSTmrCreate创建时传递给软件定时器arg的参数

p_err 返回错误码,没有错误就返回OS_ERR_NONE

删除软件定时器:

函数原型:

参数:

 p_tmr,软件定时器对象

 p_err,返回错误码,没有错误的就返回OS_ERR_NONE

单次定时器:

使用OSTmrCreate()函数创建定时器参数时候把参数opt设置为OS_OPT_TMR_ONE_SHOT,就是创建的单次定时器。创建一个单次定时器以后,我们一旦调用OSTmrStart()函数定时器就会是从创建定义的dly开始倒计时直到减为0调用回调函数。

上图展示了单次定时器的运行,dly减到0的时候调用回调函数,到这里定时器就停止运行了不再做任何事,我们可以调用OSTmrStop()函数来删除这个运行完成的定时器,也可以重新调用OSTmrStart()函数来重新开启,如下图

周期定时器:

无初始化延时:

使用OSTmrCreate()函数创建定时器时把参数opt设置为OS_OPT_TMR_PERIODIC ,就是创建周期定时器。当计时器倒计数完成之后,定时器就会调用周期函数,并重置计数器开始下一轮定时,这样一直循环下去。如果使用OSTmrCreate函数创建定时器的时候,参数dly为0的话,那么定时器在每个周期开始时计数器的初始值就是period,如下图

有初始化延时:

在创建任务的时候可以创建带有初始化延时,初始化初始化延时就是使用OSTmrCreate()函数中的参数dly就是初始化延时,定时器的第一个周期是dly。当第一个周期完成后就用参数period作为周期值,主要流程如下图:

软件定时器实验:

任务要求:先两个任务,任务A和任务B,任务A用于创建两个定时器:是定时器1和定时器2,任务A还创建了另一个任务B。其中定时器 1 为周期定时器,初始延时为 200ms,以后的定时器周期为 1000ms,定时器 2 为单次定时器,延时为2000ms。

任务 B 作为按键检测任务,当 KEY_UP 键按下的时候,打开定时器 1;当 KEY0 按下的时候打开定时器 2;当 KEY1 按下的时候,同时关闭定时器 1 和 2;任务 B 还用来控制 LED0,使其闪烁,提示系统正在运行。

定时器 1 定时完成以后调用回调函数串口输出定时器1进入一次。定时器 2 是单次定时器,我们通过串口打印来观察单次定时器的运行情况。

实验效果:

代码历程:

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "includes.h"
#include "os_app_hooks.h"
#include "key.h"
//UCOSIII中以下优先级用户程序不能使用,ALIENTEK
//将这些优先级分配给了UCOSIII的5个系统内部任务
//优先级0:中断服务服务管理任务 OS_IntQTask()
//优先级1:时钟节拍任务 OS_TickTask()
//优先级2:定时任务 OS_TmrTask()
//优先级OS_CFG_PRIO_MAX-2:统计任务 OS_StatTask()
//优先级OS_CFG_PRIO_MAX-1:空闲任务 OS_IdleTask()

//创建任务A
//定义任务优先级
#define TASK_A_PRIO 3
//定义任务控制块
OS_TCB TASK_A_TCB;
//定义任务堆栈大小
#define TASK_A_STK_SIZE 128
//定义任务堆栈
CPU_STK TASK_A_STK[TASK_A_STK_SIZE];
//定义任务函数
void TASK_A(void *arg);

//创建任务B
//定义任务优先级
#define TASK_B_PRIO 4
//定义任务控制块
OS_TCB TASK_B_TCB;
//定义任务堆栈大小
#define TASK_B_STK_SIZE 128
//定义任务堆栈
CPU_STK TASK_B_STK[TASK_B_STK_SIZE];
//定义任务函数
void TASK_B(void *arg);

/
OS_TMR tmr1;//定时器1
OS_TMR tmr2;//定时器1
void tmr1_callback(void *p_tmr, void *p_arg); //定时器1回调函数
void tmr2_callback(void *p_tmr, void *p_arg); //定时器1回调函数



int main(void)
{
	OS_ERR err1;//错误码变量
	CPU_SR_ALLOC();//定义临界区需要的变量
	
	//硬件初始化
	delay_init();       //延时初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置
	uart_init(115200);    //串口波特率设置
	LED_Init();
	KEY_Init();
	
	OSInit(&err1);//初始化UCOSIII
	OS_CRITICAL_ENTER();//进入临界区代码
	
	//创建定时器1
	
	//创建开始任务1
	OSTaskCreate((OS_TCB 	* )&TASK_A_TCB,		//任务控制块
				 (CPU_CHAR	* )"main TASKA", 		//任务名字
                 (OS_TASK_PTR )TASK_A, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )TASK_A_PRIO,     //任务优先级
                 (CPU_STK   * )&TASK_A_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)TASK_A_STK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)TASK_A_STK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR 	* )&err1);				//存放该函数错误时的返回值
	
	OS_CRITICAL_EXIT();//退出临界区代码
	OSStart(&err1);//开启UCOSIII

	while(1);
}

//开始任务函数
void TASK_A(void *arg)
{
	OS_ERR err2_3;//错误码变量
	CPU_SR_ALLOC();//定义临界区需要的变量
	arg = arg;
	
	CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0u
   OSStatTaskCPUUsageInit(&err2_3);  	//统计任务                
#endif

#ifdef CPU_CFG_INT_DIS_MEAS_EN		//如果使能了测量中断关闭时间
    CPU_IntDisMeasMaxCurReset();	
#endif
	
#if	OS_CFG_SCHED_ROUND_ROBIN_EN  //当使用时间片轮转的时候
	 //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms
	OSSchedRoundRobinCfg(DEF_ENABLED,1,&err2_3);  
#endif	
	
//#if OS_CFG_APP_HOOKS_EN				//使用钩子函数
//	App_OS_SetAllHooks();			
//#endif
	
#if OS_CFG_SCHED_ROUND_ROBIN_EN
	//使用时间片轮转调度功能,时间片长度为一个时钟节拍即1*5=5ms
	OSSchedRoundRobinCfg(DEF_ENABLED,1,&err2_3);
#endif
	
	//创建定时器1 
	OSTmrCreate((OS_TMR		*)&tmr1,		//定时器1
                (CPU_CHAR	*)"tmr1",		//定时器名字
                (OS_TICK	 )20,			//20*10=200ms
                (OS_TICK	 )100,          //100*10=1000ms
                (OS_OPT		 )OS_OPT_TMR_PERIODIC, //周期模式
                (OS_TMR_CALLBACK_PTR)tmr1_callback,//定时器1回调函数
                (void	    *)0,			//参数为0
                (OS_ERR	    *)&err2_3);		//返回的错误
	//创建定时器2
	OSTmrCreate((OS_TMR		*)&tmr2,		//定时器1
                (CPU_CHAR	*)"tmr2",		//定时器名字
                (OS_TICK	 )200,			//200*10=2000ms
                (OS_TICK	 )0,          //
                (OS_OPT		 )OS_OPT_TMR_ONE_SHOT, //单次延时
                (OS_TMR_CALLBACK_PTR)tmr2_callback,//定时器2回调函数
                (void	    *)0,			//参数为0
                (OS_ERR	    *)&err2_3);		//返回的错误码
				

	OS_CRITICAL_ENTER();//进入临界区代码
	//创建开始任务B
	OSTaskCreate((OS_TCB 	* )&TASK_B_TCB,		//任务控制块
				 (CPU_CHAR	* )"main TASKB", 		//任务名字
                 (OS_TASK_PTR )TASK_B, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )TASK_B_PRIO,     //任务优先级
                 (CPU_STK   * )&TASK_B_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)TASK_B_STK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)TASK_B_STK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR 	* )&err2_3);				//存放该函数错误时的返回值
			 
								 
	OS_CRITICAL_EXIT();//退出临界区代码
	
	//任务一执行完函数之后删掉自身
	OSTaskDel((OS_TCB *)0,&err2_3);			 
}



void TASK_B(void *arg)
{
	u8 key,num;
	OS_ERR err_B;
	while(1)
	{
		key = KEY_Scan(0);
		switch(key)
		{
			case WKUP_PRES: //当key_up按下的话打开定时器1
					OSTmrStart(&tmr1,&err_B); //开启定时器1
					printf("开启定时器1\r\n");
			break ;
			
			case KEY0_PRES://当key0按下的话打开定时器2
					OSTmrStart(&tmr2,&err_B); //开启定时器2
					printf("开启定时器2\r\n");
			break ;
			
			case KEY1_PRES:
					OSTmrStop(&tmr1,OS_OPT_TMR_NONE,0,&err_B); //关闭定时器1
					OSTmrStop(&tmr2,OS_OPT_TMR_NONE,0,&err_B); //关闭定时器2
					printf("关闭定时器1和2\r\n");
			break ;	
		}
		num++;
		if(num==50)//每500msled闪烁一次
		{
			num=0;
			LED0 = ~LED0;
		}
		OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err_B);//延时10ms
	}
	
}


//定时器1回调函数
void tmr1_callback(void *p_tmr, void *p_arg)
{
	static u8 tmr1_num=0;
	tmr1_num++; //定时器1执行次数加1
	printf("定时器1进入一次\r\n");
}


//定时器2回调函数
void tmr2_callback(void *p_tmr, void *p_arg)
{
	static u8 tmr2_num = 0;
	tmr2_num++; //定时器2执行次数加1
	LED1 = ~LED1;
	printf("定时器2运行结束\r\n");
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 嵌入式实时操作系统μC/OS是一款由美国UCOS-II开发的实时操作系统。该操作系统主要用于嵌入式系统中,具有可裁剪、高性能和可移植性的特点。 μC/OS是基于优先级调度算法的实时操作系统,支持多任务并发执行。它提供了丰富的任务管理功能,包括任务创建、任务删除、任务切换等。系统中的任务可以根据优先级进行调度,优先级高的任务可以抢占优先级低的任务,从而确保高优先级任务的及时响应。 μC/OS还提供了丰富的同步和通信机制,包括信号量、消息队列、事件标志等。这些机制使得多个任务之间可以进行有效的协作,实现任务间的同步和通信。 此外,μC/OS还支持硬实时任务和软实时任务的混合调度。硬实时任务具有严格的时限要求,需要在特定的时刻完成,而软实时任务则没有时限要求。μC/OS可以根据任务的时间要求进行动态调度,保证硬实时任务的及时响应,同时尽可能充分利用系统资源执行软实时任务。 μC/OS具有良好的可移植性,可以在不同的硬件平台上运行。同时,它也支持多种编译器,如C语言和汇编语言等。 总的来说,μC/OS是一款功能强大的嵌入式实时操作系统,能够满足嵌入式系统对实时性和可靠性的要求,同时也具有灵活的任务管理和通信机制,方便开发人员进行系统设计和应用开发。 ### 回答2: 嵌入式实时操作系统ucos是一种小型、高效、可靠的实时操作系统,在嵌入式系统开发中得到广泛应用。它由美国嵌入式专家Jean J. Labrosse开发并于1992年发布。 ucos具有可移植性强、可裁剪性高的特点。它支持多种处理器架构,如ARM、MIPS、PowerPC等,适用于不同的嵌入式系统。同时,ucos的内核占用资源较小,可以根据应用需求进行裁剪和定制,满足各种嵌入式系统对资源的限制。 ucos提供了一套完整的实时操作系统功能,包括任务管理、时间管理、内存管理和通信管理等。任务管理模块可以管理多个任务,通过优先级和时间片轮转的调度算法,实现多任务并发运行。时间管理模块提供了精确的时钟服务,可以进行实时时钟、定时器和延时等操作。内存管理模块提供了动态内存分配和释放功能,通过内存池管理方式避免了碎片问题。通信管理模块支持任务间的消息传递和同步操作,保证数据的可靠传输和任务之间的协同工作。 由于ucos的可靠性和实时性,它广泛应用于各种嵌入式系统,如工业控制、汽车电子、医疗设备等领域。它在实时性能和资源利用上具有优势,为开发人员提供了一个强大而灵活的开发平台。同时,ucos在应用层编程接口上也提供了丰富的功能库和协议栈,为系统开发提供了更多的支持。 总而言之,嵌入式实时操作系统ucos是一款高效、可靠、可移植的实时操作系统,具有广泛的应用领域和良好的生态系统。它为嵌入式系统开发者提供了一个稳定的开发平台,可以根据实际需求进行裁剪和定制,满足不同应用场景的需求。 ### 回答3: 嵌入式实时操作系统μC/OS是一种创建和管理实时任务的操作系统。它由美国工程师Jean Labrosse开发,并由其公司Micrium Inc.发布。μC/OS提供了许多功能和特性,使其成为嵌入式系统的理想选择。 μC/OS是一个可裁剪的操作系统,可以根据应用程序的需求选择性地启用或禁用功能。它具有小内核和低的内存占用,适用于资源有限的嵌入式系统。此外,μC/OS提供了一套全面的API,包括任务管理、时间管理、内存管理、信号量、消息队列和事件标志等,为开发人员提供了丰富的功能来实现复杂的嵌入式应用程序。 μC/OS具有轻量级实时调度算法,可以实现任务的优先级和时间片调度。它通过任务优先级来处理紧急的任务,确保系统能够及时响应重要事件。此外,μC/OS还提供了高精度的时钟管理功能,可以实现微秒级的时间精度。 μC/OS还具有可靠的内存管理功能,包括静态和动态内存分配。开发人员可以灵活地管理内存,并通过内存池和内存分区机制来提高系统的效率和可靠性。 总而言之,嵌入式实时操作系统μC/OS是一款强大而灵活的操作系统,适用于各种嵌入式系统的开发。它提供了丰富的功能和特性,满足了实时任务管理、时间管理和内存管理等要求。使用μC/OS可以提高系统的效率和可靠性,加快开发周期,使嵌入式系统更加稳定和可靠。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值