本帖最后由 nicholasldf 于 2016-7-7 09:01 编辑
Cortex-M 内核单片机的精确延时方法,ns、us、ms,,不基于任何定时器,,思路来源于uCOS-II官方BSP移植代码。
/*
*********************************************************************************************************
* void Cortex_DWT_Init (void)
* Description : just the same as CPU_TS_TmrInit function, Initialize Cortex-M3 DWT for delay services,
* like delay_ns, delay_us, delay_ms
* Caller(s) : Application.
*********************************************************************************************************
*/
#define CORTEX_REG_DEM_CR (*(uint32_t *)0xE000EDFC)
#define CORTEX_REG_DWT_CR (*(uint32_t *)0xE0001000)
#define CORTEX_REG_DWT_CYCCNT (*(uint32_t *)0xE0001004)
#define CORTEX_REG_DBGMCU_CR (*(uint32_t *)0xE0042004)
#define CORTEX_BIT_DEM_CR_TRCENA (1 << 24)
#define CORTEX_BIT_DWT_CR_CYCCNTENA (1 << 0)
void Cortex_DWT_Init (void)
{
/* Enable Cortex-M3's DWT CYCCNT reg. */
CORTEX_REG_DEM_CR |= (uint32_t)CORTEX_BIT_DEM_CR_TRCENA;
CORTEX_REG_DWT_CYCCNT = (uint32_t)0u;
CORTEX_REG_DWT_CR |= (uint32_t)CORTEX_BIT_DWT_CR_CYCCNTENA;
}
/*
*********************************************************************************************************
* void delay_us (uint32_t number)
* Description : delay service for specified time that often smaller than 1mS
* number : time to delay in uS
*********************************************************************************************************
*/
void delay_us (uint32_t number)
{
uint32_t init_cnts, total, now;
total = BSP_CPU_ClkFreq()/1000000*number;
init_cnts = CORTEX_REG_DWT_CYCCNT;
do{
now = CORTEX_REG_DWT_CYCCNT;
}while( (now - init_cnts) < total);
}
//delay_ns
void delay_ns (uint32_t number)
{
uint32_t init_cnts, total, now;
total = BSP_CPU_ClkFreq()*number/1000000000;
init_cnts = CORTEX_REG_DWT_CYCCNT;
do{
now = CORTEX_REG_DWT_CYCCNT;
}while( (now - init_cnts) < total);
}
//delay_ms
void delay_ms (uint32_t number)
{
while(number--) delay_us(1000);
} |