STM32CubeMX HAL delay_us() 微秒延时函数

STM32CubeMX HAL delay_us() 微秒延时函数

以 stm32f103 为例:
系统时钟配置为72M。
在这里插入图片描述

delay.c

#include "delay.h"
		   
static uint8_t  fac_us=0;							//us延时倍乘数			   
//static uint8_t  fac_ms=0;							//ms延时倍乘数			   
	
//初始化延迟函数, 在SystemClock_Config()后初始化,否则SystemCoreClock不正确
void delay_init()
{
	HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);	//SysTick频率为HCLK
															// 用SYSTICK_CLKSOURCE_HCLK_DIV8的话会使 HAL_Delay()变慢为8倍 HAL_Delay(1)实际会为8ms
	fac_us=SystemCoreClock/1000000;							//72M/1M=72 数72次为 1us
//	fac_ms=fac_us*1000;
}								    

// 延时nus
// nus为要延时的us数.
// 对 SysTick 寄存器进行了操作,可能会对其他使用了 SysTick 的定时造成影响?如 HAL_Delay() ?
//void delay_us(uint32_t nus)
//{		
//	uint32_t temp;	    	 
//	SysTick->LOAD=nus*fac_us; 					//时间加载	  		 
//	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;      					 //清空计数器	 
//}

// 延时nus
// nus为要延时的us数
// 没有对 SysTick 进行改动,相对安全。但精准度可能会轻微降低??
void delay_us(uint32_t nus)
{		
	uint32_t ticks;
	uint32_t told,tnow,tcnt=0;
	uint32_t 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;			//时间超过/等于要延迟的时间,则退出.
		}  
	};
}

//延时nms
//nms:要延时的ms数
void delay_ms(uint16_t nms)
{
	uint32_t i;
	for(i=0;i<nms;i++) delay_us(1000);
}

delay.h

#ifndef __DELAY_H_
#define __DELAY_H_ 			   
#include "main.h"  
	 
void delay_init(void);
void delay_us(uint32_t nus);
void delay_ms(uint16_t nms);

#endif
STM32中,使用delay.h函数可以方便地实现延时操作。以下是一个控制蓝牙的delay.h函数的示例代码: ```c #ifndef __DELAY_H #define __DELAY_H #include "stm32f10x.h" void Delay_Init(void); void Delay_us(uint32_t n); void Delay_ms(uint32_t n); #endif ``` ```c #include "delay.h" static uint32_t fac_us = 0; // us延时倍乘数 static uint32_t fac_ms = 0; // ms延时倍乘数 /* * 延时初始化函数 */ void Delay_Init(void) { SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8 fac_us = SystemCoreClock / 8000000; //系统时钟频率 72Mhz fac_ms = fac_us * 1000; } /* * 微秒延时函数 */ void Delay_us(uint32_t n) { uint32_t temp; SysTick->LOAD = n * fac_us; //时间加载 SysTick->VAL = 0x00; //清空计数器 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //开始倒数 do { temp = SysTick->CTRL; } while ((temp & 0x01) && !(temp & SysTick_CTRL_COUNTFLAG_Msk)); //等待时间到达 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //关闭计数器 SysTick->VAL = 0X00; //清空计数器 } /* * 毫秒级延时函数 */ void Delay_ms(uint32_t n) { uint32_t temp; SysTick->LOAD = n * fac_ms; //时间加载(SysTick->LOAD为24bit) SysTick->VAL = 0x00; //清空计数器 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //开始倒数 do { temp = SysTick->CTRL; } while ((temp & 0x01) && !(temp & SysTick_CTRL_COUNTFLAG_Msk)); //等待时间到达 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //关闭计数器 SysTick->VAL = 0X00; //清空计数器 } ``` 使用该函数时,需要在main函数或其他需要使用延时功能的函数中调用Delay_Init()函数进行初始化。例如: ```c #include "delay.h" int main(void) { Delay_Init(); // ...其他代码 while (1) { Delay_ms(1000); // 延时一秒钟 // ...其他代码 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值