#include "GD32Sys.h" #include "hardware_delay.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) static volatile int system_core_clock = 400; //系统时钟 /** * 初始化软件延时 * * @author lxz * * @param clk 设备硬件时钟 */ void hw_delay_init(int clk) { system_core_clock = clk * 1000000; 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; SysTick->CTRL |= 1 << 2; //SYSTICK 时钟跟系统同步 SysTick->CTRL |= 1 << 1; //中断使能 SysTick->LOAD = (system_core_clock / 1000) - 1; //1ms中断 SysTick->CTRL |= 1 << 0; //使能systick } /** * 微妙级延时 * * @author LXZ (2018/8/16) * * @param usec */ void hw_delay_us(int usec) { uint32_t tCnt, tDelayCnt; uint32_t tStart; tStart = DWT_CYCCNT; /* 刚进入时的计数器值 */ tCnt = 0; tDelayCnt = usec * (system_core_clock / 1000000); /* 需要的节拍数 */ while (tCnt < tDelayCnt) { tCnt = DWT_CYCCNT - tStart; /* 求减过程中,如果发生第一次32位计数器重新计数,依然可以正确计算 */ } } /** * 获取当前的微秒值,该值只是近似值,偏差一个us * * @author lxz (2019/5/30/周四) * * @param void * * @return int */ int hw_read_us(void) { uint32_t usec = system_core_clock / 1000000; return (DWT_CYCCNT + (usec >> 1)) / usec; }