/* ********************************************************************************************************* * * 模块名称 : 数据观察点与跟踪(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 "bsp.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) /* ********************************************************************************************************* * 函 数 名: dwt_init * 功能说明: 初始化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); 根据实际情况看看是否需要加调度锁或选择关中断 * 形 参: 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 us_delay(uint32_t time) { uint32_t count, tcnt; uint32_t tstart; tstart = DWT_CYCCNT; /* 刚进入时的计数器值 */ count = 0; tcnt = time * (SystemCoreClock / 1000000); /* 需要的节拍数 */ while (count < tcnt) { count = DWT_CYCCNT - tstart; /* 求减过程中,如果发生第一次32位计数器重新计数,依然可以正确计算 */ } } /* ********************************************************************************************************* * 函 数 名: bsp_DelayMS * 功能说明: 为了让底层驱动在带RTOS和裸机情况下有更好的兼容性 * 专门制作一个阻塞式的延迟函数,在底层驱动中ms毫秒延迟主要用于初始化,并不会影响实时性。 * 形 参: n 延迟长度,单位1 ms * 返 回 值: 无 ********************************************************************************************************* */ void ms_delay(uint32_t time) { us_delay(1000 * time); } /***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/