单片机延时的几种方式

分为使用操作系统和不使用操作系统
一、不使用操作系统
1.执行指令耗时间,不能实现可打断,浪费MCU资源,如下面的延时函数 delay_ms

void delay_ms(u16 nms)
{	 	 
	while(repeat)
	{
		repeat--;//重复执行自减指令
	}
} 

2.使用定时器进行计时,可以实现延时过程可打断,不浪费MCU资源
定时器初始化,根据时钟去设置一次定时的时间

void Timer1_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能时钟

    TIM_TimeBaseStructure.TIM_Period = arr;                    //设置自动重装周期
    TIM_TimeBaseStructure.TIM_Prescaler =(psc-1);              //预分频值
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;               //时钟分割
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;           //重复计数设置
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);            //参数初始化
    TIM_ClearFlag(TIM1, TIM_FLAG_Update);                      //清中断标志 

    TIM_ITConfig(                                              //使能定时器
    TIM1,                                                      //TIM1
    TIM_IT_Update  |                                           //TIM 更新源
    TIM_IT_Trigger,                                            //TIM 触发中断源
    ENABLE                                                     //使能
    );

    //设置优先级
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //主优先级0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        //从优先级0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure); 

    TIM_Cmd(TIM1, ENABLE);  //使能TIM外设
}

中断服务函数设置一个全局变量去用于计数

void TIM1_UP_IRQHandler(void)
{
     clrCnt=clrCnt ++;//计数
    TIM_ClearFlag(TIM1, TIM_FLAG_Update);//清除标志位
}

3.使用STM32的系统滴答时钟,即可实现定时器的功能,又不用使用定时器的功能。

void delay_xms(u16 nms)
{	 		  	  
	u32 temp;		   
	SysTick->LOAD=(u32)nms*fac_ms;			//时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;           			//清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //开始倒数 
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));	//等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //关闭计数器
	SysTick->VAL =0X00;     		  		//清空计数器	  	    
} 

二、使用操作系统
1.uC/OS提供两种不同的延时方式,缺点是不能少于一个时钟节拍的时间,其他操作系统也类似。
OSTimeDly()延时函数,延时多少个时钟节拍;
OSTimeDlyHMSM()延时可以是时、分、秒、毫秒的组合延时;

你可能感兴趣的:(STM32)