使用DWT实现us级延时

/*
Cortex-M3,M4,M7内核有一个外设叫DWT(Data Watchpoint and Trace),用于系统调试及跟踪。
它有一个32位的寄存器叫CYCCNT,它是一个向上的计数器,记录的是内核时钟运行的个数,内核时钟跳动一次,该计数器就加1,精度非常高。
当CYCCNT溢出之后,会清0重新开始向上计数。
1、使能DWT外设,由内核调试寄存器DEMCR的位24控制,写1使能。DEMCR的地址是0xE000 EDFC
2、使能DWT的CYCCNT计数器,由DWT->CTRL的bit0控制
3、获取计数值DWT_CYCCNT
*/

#define DWT_BASE            (0xE0001000UL)                            /*!< DWT Base Address */
#define CoreDebug_BASE      (0xE000EDF0UL)                            /*!< Core Debug Base Address */

/* Debug Exception and Monitor Control Register Definitions */
#define CoreDebug_DEMCR_TRCENA_Pos         24U                                            /*!< CoreDebug DEMCR: TRCENA Position */
#define CoreDebug_DEMCR_TRCENA_Msk         (1UL << CoreDebug_DEMCR_TRCENA_Pos)            /*!< CoreDebug DEMCR: TRCENA Mask */

#define DWT_CTRL_CYCCNTENA_Pos              0U                                         /*!< DWT CTRL: CYCCNTENA Position */
#define DWT_CTRL_CYCCNTENA_Msk             (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/)       /*!< DWT CTRL: CYCCNTENA Mask */

#define DEMCR		*(__IO uint32_t *)(CoreDebug_BASE + 0x0C)
#define DWT_CTRL	*(__IO uint32_t *)(DWT_BASE)
#define DWT_CYCCNT	*(__IO uint32_t *)(DWT_BASE + 0x04)

/* CPU core clock frequency. */
#define CPU_CORE_CLOCK CLOCK_GetFreq(kCLOCK_CpuClk)

void enableCpuCycleCounter(void)
{
    /* Make sure the DWT trace fucntion is enabled. */
    if (CoreDebug_DEMCR_TRCENA_Msk != (CoreDebug_DEMCR_TRCENA_Msk & DEMCR))
    {
        DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    }

    /* CYCCNT not supported on this device. */
    //assert(DWT_CTRL_NOCYCCNT_Msk != (DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk));

    /* Read CYCCNT directly if CYCCENT has already been enabled, otherwise enable CYCCENT first. */
    if (DWT_CTRL_CYCCNTENA_Msk != (DWT_CTRL_CYCCNTENA_Msk & DWT_CTRL))
    {
        DWT_CTRL |= DWT_CTRL_CYCCNTENA_Msk;
    }
}

uint32_t getCpuCycleCount(void)
{
    return DWT_CYCCNT;
}

/* 
core clock frequency. 
内核时钟600Mhz,周期是1/600us,跳动一次时间是1/600us
假设现在要延时1us,则需要跳动1/(1/600)=600次,即CYCCNT累加了600
*/
#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)(((uint64_t)(us) * (clockFreqInHz)) / 1000000U)

uint32_t get_distance_32(uint32_t ori,uint32_t cur )
{
	return (uint32_t)(( ( ori ) > ( cur ) ) ? ( 0xFFFFFFFF - ( ori ) + ( cur  ) + 1) : ( ( cur ) - ( ori ) ));
}

void delay_us(uint32_t delayTime_us, uint32_t coreClock_Hz)
{
	uint32_t startTime,curTime,count;

    if (delayTime_us > 0U)
    {
        count = USEC_TO_COUNT(delayTime_us, coreClock_Hz);

		startTime = getCpuCycleCount();
		
        while(1)
        {
			curTime = getCpuCycleCount();
			if(get_distance_32(startTime,curTime)>count)
				break;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值