在做项目的时候,驱动有时会用到us级别的延时比如软件模拟i2c、DS18B20驱动等 ,使用定时器可以实现,但是需要频繁进入中断,在RTOS环境下会影响实时性。ARM M3内核及更高级内核都会自带一个DWT模块,具体有作用可自行问度娘!
话多不表,开整!!!
a.先使能DWT外设,由内核调试寄存器DEM_CR的位24控制,写1使能。
b.使能CYCCNT寄存器之前,先清0。
c.使能CYCCNT寄存器,由DWT_CTRL的位0控制,写1使能。
对于STM32F767还有一点不一样,这一点也折腾我好久!在网上找到有人提到这个问题,缺少解锁 dbg regs(DWT->LAR = 0xC5ACCE55)(https://www.soinside.com/question/pNGYbX5uj8xjLsuAbgN2iR),试一下果然解决了;
献上代码:
#define DEM_CR_TRCENA (1 << 24)
#define DWT_CR_CYCCNTENA (1 << 0)
void bsp_DWT_Init(void)
{
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->LAR = 0xC5ACCE55;
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
//下面代码参考 安富莱
void bsp_DelayUS(uint32_t _ulDelayTime)
{
uint32_t tCnt, tDelayCnt;
uint32_t tStart;
tStart = DWT->CYCCNT; /* 刚进入时的计数器值 */
tCnt = 0;
tDelayCnt = _ulDelayTime * (SystemCoreClock / 1000000); /* 需要的节拍数 */
while(tCnt < tDelayCnt)
{
tCnt = DWT->CYCCNT - tStart; /* 求减过程中,如果发生第一次32位计数器重新计数,依然可以正确计算 */
}
}