赞
踩
延时是一个很重要的概念,尤其是在利用单片机做项目的时候,比如利用IIC协议驱动EEPROM时,需要用到精准延时,延时时间太短或者延时时间太长都会影响到数据的写入和读出。因此正确写好延时对我们在学习单片机和利用单片机做项目时会有事半功倍的效果。
本文中实现延时用的是stm32f407系列单片机的定时器3,但不仅仅是定时器3,Systick定时器同样也可以实现延时,但考虑到有的小伙伴可能会移植FreeRtos、UCOSIII等等实时操作系统,所以到那个时候,Systick将作为整个操作系统的时基单元,选择基本定时器更能方便了解定时器原理。
打开STM32CUBEIDE先配置定时器3,配置到如下图所示即可。
通过了解STM32参考手册可以知道定时器3挂载在APB1总线上,时钟选用外部高速时钟25M晶振再倍频得到系统时钟频率最高可以跑180M。而APB1总线上的定时器时钟频率为90M,如下图。
为什么要选用90分频呢?因为TIM3总时钟频率为90M也就是说1s可以跑90M次,为了实现微妙延时,则需要把定时器配置成us级别,1s = 1000ms = 1000us,也就是说需要把90M/90 = 1M,这个时候,TIM3的时钟频率为1us 可以计数1次,我们把重装载值设置为65535(因为定时器为16位,最大值就是65535),则这个定时器最大可以计时65535us = 655.35ms。
定时器是一直重复计时的,我们设置TIM3的计数方式为向上计数,也就是从0开始一直计数到重装载值寄存器中设定的那个值,然后再重复计数,除非手动关闭定时器。具体配置代码如下。
通过配置好以上步骤,便可以实现如下代码,TIM3不需要进入中断,一定程度上减少了中断嵌套带来的缺点。
- //微秒延时
- void HAL_usDelay(uint16_t us)
- {
- if((us > 65535) || (us < 0))//判断参数是否正确
- {
- us = 65535;
- }
- uint16_t Count = 0;
- __HAL_TIM_SET_AUTORELOAD(&htim3,us);//设置重装载值,也就是计数目标值
- __HAL_TIM_SET_COUNTER(&htim3,Count);//把定时器计数值归零
- HAL_TIM_Base_Start(&htim3);//开启定时器之后,定时器就会开始计数,从0到us
-
- //不断获取定时器的计数值,当计数值数到us时,再关闭定时器
- while(Count != us){Count = __HAL_TIM_GET_COUNTER(&htim3);}
- HAL_TIM_Base_Stop(&htim3);//关闭定时器
- }
-
- //毫秒延时
- void HAL_msDelay(uint16_t ms)
- {
-
- for(uint32_t i=0; i<ms; i++)
- {
- HAL_usDelay(1000);//因为1ms = 1000 us
- }
-
- }

最后通过示波器验证了100us延时的精准度,如下图,一个格子是50us,两个格子就是100us。
以上就是简单的定时器实现延时函数,本人是新手小白,内容有不正确之处欢迎高手指正.....
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。