/* ********************************************************************************************************* * * 模块名称 : 数据观察点与跟踪(DWT)模块 * 文件名称 : bsp_dwt.c * 版 本 : V1.0 * 说 明 : 在CM3,CM4中可以有3种跟踪源:ETM, ITM 和DWT,本驱动主要实现 * DWT中的时钟周期(CYCCNT)计数功能,此功能非常重要,可以很方便的 * 计算程序执行的时钟周期个数。 * 修改记录 : * 版本号 日期 作者 说明 * V1.0 2015-08-18 Eric2013 正式发布 * * Copyright (C), 2015-2020, 安富莱电子 www.armfly.com * ********************************************************************************************************* */ #include "global.h" /* ********************************************************************************************************* * 寄存器 ********************************************************************************************************* */ #define DWT_CYCCNT *(volatile unsigned int *)0xE0001004 #define DWT_CR *(volatile unsigned int *)0xE0001000 #define DEM_CR *(volatile unsigned int *)0xE000EDFC #define DBGMCU_CR *(volatile unsigned int *)0xE0042004 #define DEM_CR_TRCENA (1 << 24) #define DWT_CR_CYCCNTENA (1 << 0) /* ********************************************************************************************************* * 函 数 名: bsp_InitDWT * 功能说明: 初始化DWT. 该函数被 bsp_Init() 调用。 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void dwt_init(void) { DEM_CR |= (unsigned int)DEM_CR_TRCENA; /* Enable Cortex-M4's DWT CYCCNT reg. */ DWT_CYCCNT = (unsigned int)0u; DWT_CR |= (unsigned int)DWT_CR_CYCCNTENA; } /* ********************************************************************************************************* * 函 数 名: bsp_DelayUS * 功能说明: 这里的延时采用CPU的内部计数实现,32位计数器 * OSSchedLock(&err); * bsp_DelayUS(5); * OSSchedUnlock(&err); 根据实际情况看看是否需要加调度锁或选择关中断 * 形 参: us_time 延迟长度,单位1 us * 返 回 值: 无 * 说 明: 1. 主频168MHz的情况下,32位计数器计满是2^32/168000000 = 25.565秒 * 建议使用本函数做延迟的话,延迟在1秒以下。 * 2. 实际通过示波器测试,微妙延迟函数比实际设置实际多运行0.25us左右的时间。 * 下面数据测试条件: * (1). MDK5.15,优化等级0, 不同的MDK优化等级对其没有影响。 * (2). STM32F407IGT6 * (3). 测试方法: * GPIOI->BSRRL = GPIO_Pin_8; * bsp_DelayUS(10); * GPIOI->BSRRH = GPIO_Pin_8; * ------------------------------------------- * 测试 实际执行 * bsp_DelayUS(1) 1.2360us * bsp_DelayUS(2) 2.256us * bsp_DelayUS(3) 3.256us * bsp_DelayUS(4) 4.256us * bsp_DelayUS(5) 5.276us * bsp_DelayUS(6) 6.276us * bsp_DelayUS(7) 7.276us * bsp_DelayUS(8) 8.276us * bsp_DelayUS(9) 9.276us * bsp_DelayUS(10) 10.28us * 3. 两个32位无符号数相减,获取的结果再赋值给32位无符号数依然可以正确的获取差值。 * 假如A,B,C都是32位无符号数。 * 如果A > B 那么A - B = C,这个很好理解,完全没有问题 * 如果A < B 那么A - B = C, C的数值就是0xFFFFFFFF - B + A + 1。这一点要特别注意,正好用于本函数。 ********************************************************************************************************* */ void delay_us(uint32_t us_time) { uint32_t tCnt, tDelayCnt; uint32_t tStart; tStart = DWT_CYCCNT; /* 刚进入时的计数器值 */ tCnt = 0; tDelayCnt = us_time * (SystemCoreClock / 1000000); /* 需要的节拍数 */ while (tCnt < tDelayCnt) { tCnt = DWT_CYCCNT - tStart; /* 求减过程中,如果发生第一次32位计数器重新计数,依然可以正确计算 */ } } void delay_ms(uint32_t us_time) { delay_us(1000 * us_time); }