FreeRTOS学习(2)延时函数的封装

 以下是封装的延时函数:


/*-----------------------------------------------------*/
/*                                                     */
/*         		  	  延时函数                         */
/*                                                     */
/*-----------------------------------------------------*/


/*
 *	delay_us()是us级延时函数,delay_ms和delay_xms()都是ms级的延时函数,delay_us()和
 *	delay_xms()不会导致任务切换。delay_ms()其实就是对 FreeRTOS中的延时函数vTaskDelay()的
 *	简单封装,所以在使用delay_ms()的时候就会导致任务切换。 
 */

#include "delay.h"

static u8  fac_us = 0;					//us延时倍乘数			   
static u16 how_ms_per_rate = 0;			//ms延时倍乘数

/*-------------------------------------------------*/
/*函数名:延时初始化                    	       */
/*参  数:无                                       */
/*返回值:无                                       */
/*-------------------------------------------------*/
void delay_init()
{
	u32 reload;
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//选择外部时钟  HCLK
	fac_us = SystemCoreClock/1000000;				//不论是否使用OS,fac_us都需要使用 
	reload = SystemCoreClock/configTICK_RATE_HZ;	//根据configTICK_RATE_HZ设定溢出时间
													//reload为24位寄存器,最大值:16777216,在72M下,约合0.233s左右	
	how_ms_per_rate = 1000/configTICK_RATE_HZ;		//代表OS可以延时的最少单位	   

	SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;   	//开启SYSTICK中断
	SysTick->LOAD = reload; 						//每1/configTICK_RATE_HZ秒中断一次	
	SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;   	//开启SYSTICK 					
}	 

/*-------------------------------------------------*/
/*函数名:us延时                    			    */
/*参  数  us                                       */
/*返回值:无                                        */
/*-------------------------------------------------*/
void delay_us(u32 nus)
{		
	u32 ticks;
	u32 told,tnow,tcnt = 0;
	u32 reload = SysTick->LOAD;					//LOAD的值	    	 
	ticks = nus * fac_us; 						//需要的节拍数 
	told = SysTick->VAL;        				//刚进入时的计数器值
	while(1)
	{
		tnow = SysTick->VAL;	
		if(tnow != told)
		{	    
			if(tnow < told)tcnt += told - tnow;	//这里注意一下SYSTICK是一个递减的计数器就可以了.
			else tcnt += reload - tnow + told;	    
			told = tnow;
			if(tcnt >= ticks)break;				//时间超过/等于要延迟的时间,则退出.
		}  
	};										    
} 

/*-------------------------------------------------*/
/*函数名:ms延时 (FreeRTOS vTaskDelay()封装)        */
/*参  数  ms                                       */
/*返回值:无                                        */
/*-------------------------------------------------*/
void delay_ms(u32 nms)
{	 		  	  
	if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
	{
		if (nms >= how_ms_per_rate) 
		{
			vTaskDelay(nms/how_ms_per_rate);
		}
		nms %= how_ms_per_rate;				//OS已经无法提供这么小的延时了,采用普通方式延时  		
	}
	delay_us((u32)(nms * 1000));		    //普通方式延时
} 


//延时nms,不会引起任务调度
//nms:要延时的ms数
void delay_xms(u32 nms)
{
	u32 i;
	for(i = 0; i < nms; i++) delay_us(1000);
}

 当我们移植FreeRTOS时,会出现了freertos.axf: Error: L6218E: Undefined symbol xTaskGetSchedulerState (referred from delay.o).

解决方法:

使用如下代码,首先要在FreeRTOS.h文件中加入以下宏定义,并设置为1

#ifndef INCLUDE_xTaskGetSchedulerState
	#define INCLUDE_xTaskGetSchedulerState 1
#endif

并且,然后在FreeRTOSconfig.h文件中配置这个宏为1

#define INCLUDE_xTaskGetSchedulerState          1 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值