STM32 可重入 delay_us

delay 函数是最常用的工具函数之一,如果它不可靠了,结果会比较令人头疼。

  • STM32 中基于 SysTick 实现的 delay_ms/delay_us 是不可重入的,不可重入的原因很简单,因为在 delay 函数中对 SysTick 的寄存器进行了“写操作”:
	SysTick->LOAD = DELAY_Nus * DELAY_FAC_US; 	//时间加载	  		 
	SysTick->VAL = 0x00;        				//清空计数器
	SysTick->CTRL = 0x01 ;
  • 同时,SysTick->CTRL 的状态标志位即使只是读取也会改变状态
    SysTick 控制与状态寄存器
  • 因此,想靠 SysTick 实现可重入的 delay 是不可能的,只能使用笨方法。靠 uint32_t i = N; while(i--);根据单片机的执行频率以及测试调优,找到一个相对准确的经验值 N。72MHz的 STM32F103的1um 的 N 值测试:
    1. 10000000 次的执行最快时间为 833333 um
    2. N 的值为: 12
/* 测试 while 空循环 10M 次需要的时间,以此为依据写可重入的 delay 用于中断内部 */
void TEST_DelayReen(void)
{		
	char numstr[11] = {'\0'};	 
	uint32_t temp = 10000000, tmp2;	
	SysTick->LOAD = 0xFFFFFF;   	//最大值 16777215 , SysTIck工作频率9MHz
	SysTick->VAL = 0x00;        	//清空计数器
	SysTick->CTRL = 0x01 ;      	//开始倒数 	
	while(temp--);
	/* 关闭所有中断测试多次,收到的稳定值是 9277215 */
	Dec2Str(SysTick->VAL, numstr);	
	USART1_SendData(numstr, 11);
	SysTick->CTRL=0x00;       //关闭计数器
	SysTick->VAL =0X00;       //清空计数器	 
}
  • 最后(很重要),因为如果这个函数被中断,那么这次 delay 的时间就是设置的时间 N 加上中断的执行时间。所以在主流程中最好还是使用 SysTick 实现的 delay,而可重入的 delay 只在中断中用就行
发布了18 篇原创文章 · 获赞 1 · 访问量 966

猜你喜欢

转载自blog.csdn.net/ManWZD/article/details/100562971