本文将花费你3分钟时间,如果你懒,请直接拉到代码处拷贝关键代码。
定时器配置cubeMX
定时器输入时钟
TIM14时钟挂载于AHB1,其实不用看那么多,直接看cube 软件timer clock ,84Mhz
定时器计数配置
定时器微秒实现原理
84Mhz时钟输入定时器,分频后1Mhz = 1us,也就是count CNT每加一次就是1us。
代码实现
__weak void HAL_Delay_us(uint32_t Delay_us)
{
uint16_t wait = Delay_us;
if (wait < UINT16_MAX) //设定定时器计数器阈值,也可注释掉
wait++;
__HAL_TIM_SET_COUNTER(&htim14,0); //将CNT值设置为0
HAL_TIM_Base_Start(&htim14); //启动定时器
while(__HAL_TIM_GET_COUNTER(&htim14) < wait) //查询计数器的计数值判断
{
}
HAL_TIM_Base_Stop(&htim14);//频繁开启时,可以注释掉这句
}
微秒实验结果
1us
2us
50us
100us
注意
- 计数模式选择向上模式,其他模式实现步骤和上文类似
- 自动重载值建议调到最大
- 更正计数值建议从1开始
DWT 实现方法
野火有对此方法的具体解释,如果不是M0的话可以使用。
#ifndef __DWT_H_
#define __DWT_H_
#include "stm32f4xx.h"
#define DWT_CR *(volatile uint32_t *)0xE0001000
#define DWT_CYCCNT *(volatile uint32_t *)0xE0001004
#define DEM_CR *(volatile uint32_t *)0xE000EDFC
#define DEM_CR_TRCENA (1 << 24)
#define DWT_CR_CYCCNTENA (1 << 0)
#define delayms(msec) delayus(msec*1000)
void dwt_delay_init(uint32_t clk);
void delay_us(uint32_t usec);
void delay_ms(__IO uint32_t nTime);
#endif
#include "dwt.h"
static uint32_t cpuclkfeq;
void dwt_delay_init(uint32_t clk)
{
cpuclkfeq = clk;
DEM_CR |= DEM_CR_TRCENA;
DWT_CYCCNT = 0u;
DWT_CR |= DWT_CR_CYCCNTENA;
}
void delay_us(uint32_t usec)
{
uint32_t startts, endts, ts;
startts = DWT_CYCCNT;
ts = usec * (cpuclkfeq / (1000 * 1000));
endts = startts + ts;
if(endts > startts)
{
while(DWT_CYCCNT < endts);
}
else
{
while(DWT_CYCCNT > endts);
while(DWT_CYCCNT < endts);
}
}
void delay_ms(__IO uint32_t nTime)
{
delay_us(1000 * nTime);
}
重在直接用