本文纯属记录自己学习历程,如有不妥之处,欢迎指正。
使用TIM定时器方式延时
使用STM32CubeMX配制TIM1定时,如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020102611010227.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L29YYWRtaW4=,size_16,color_FFFFFF,t_70#pic_center)
自动重装载值为1,向上计数模式,预分频系数为168-1,也就是167(这里我用的是F407的板子做的示例,F407芯片主频为168Mhz,设置这个分频系数,TIM1 的时钟频率为1Mhz,也就是说每1s计数1000000次,换算过来也就是说,1us计数一次)。另外,如果使用的是TIM2-7,这几路定时器时钟频率最高84Mhz,分频系数要做修改。
下面是延时函数
void delay_us(uint16_t us)
{
uint16_t delay=0xffff-us-5; //65535-5-us,计数初值,由这个数
//计数到65535刚好计数us次,也就实
//现了nus延时
HAL_TIM_Base_Start(&htim1); //开启定时器
__HAL_TIM_SetCounter(&htim1,delay); //设置计数值
while(delay<0xffff-5)
{
delay=__HAL_TIM_GetCounter(&htim1); //获取当前计数值
}
HAL_TIM_Base_Stop(&htim1);
}
延时函数测试代码如下
void LedTask_Function(void const * argument)
{
portTickType tick = xTaskGetTickCount();
while(1)
{
HAL_GPIO_WritePin(LED_2_GPIO_Port,LED_2_Pin,GPIO_PIN_SET);
delay_us(10);
HAL_GPIO_WritePin(LED_2_GPIO_Port,LED_2_Pin,GPIO_PIN_RESET);
delay_us(10);
}
}
延时效果如图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201026115021109.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L29YYWRtaW4=,size_16,color_FFFFFF,t_70#pic_center)
由图像可以看出,引脚输出的高低电平时间为10.4us,延时效果较为理想
还有其他定时器计数方式,只要了解原理,可以灵活的实现精确延时,另外不建议在较为复杂的系统中使用TIM中断延时,容易出现问题。
使用空代码方式延时
空代码演延时方式精确度略低于定时器延时,但是对于一些us延时精度不是很高的场景已经足够使用。
F103系列
F103系列芯片主频72MHz
/**
* @funNm : delay_sys_us
* @brief : 延时nus
* @param : nus:要延时的us数. 0~204522252(最大值即2^32/fac_us@fac_us=168)
* @retval: void
*/
void delay_sys_us(uint32_t Delay)//1个delay,大概1.5us
{
uint32_t cnt = Delay * 8;
uint32_t i = 0;
for(i = 0; i < cnt; i++)__NOP();
}
F429系列
F429芯片主频180MHz,执行一条指令时间相较于F103系列芯片会短很多,F429系列us延时函数如下
void delay_sys_us(uint32_t Delay)
{
uint32_t cnt = Delay*35;
uint32_t i = 0;
for(i=0;i<cnt;i++)__NOP();
} ;
延时效果如图
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201026115955598.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L29YYWRtaW4=,size_16,color_FFFFFF,t_70#pic_center)
由波形图可以看出,使用这种延时方式,也可以做到us级延时,但是仔细看会发现,这种波形的延时周期并不稳定,所以较高要求的延时还是尽量使用TIM定时器延时