/************************************* time: auther: change: *************************************/ #include "delay.h" #include "sys.h" #include "main.h" static uint32_t fac_us = 0; //us延时倍乘数 //hal库提供了ms延时 __weak void HAL_Delay(uint32_t Delay),但是没有us延时,所以delay_us为us延时函数 /** * @brief 初始化延迟函数,SYSTICK的时钟固定为AHB时钟 * * @param SYSCLK 系统时钟频率 1us计数fac_us脉冲 * * @return void */ void delay_init(uint8_t SYSCLK) { //HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//SysTick频率为HCLK fac_us = SYSCLK; //不论是否使用OS,fac_us都需要使用 } /** * @brief 延时微秒(us)函数 * * @remark nus:0~190887435(最大值即2^32/fac_us@fac_us=22.5) * * @param nus 需要延时多少微秒 * * @return void */ void delay_us(uint32_t nus) { uint32_t ticks; uint32_t told, tnow, tcnt = 0; uint32_t reload = SysTick->LOAD; //LOAD的值 ticks = nus * fac_us; //需要的节拍数 told = SysTick->VAL; //刚进入时的计数器值 while(1) { tnow = SysTick->VAL; if(tnow != told) { if(tnow < told) tcnt += told - tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了. else tcnt += reload - tnow + told; told = tnow; if(tcnt >= ticks)break; //时间超过/等于要延迟的时间,则退出. } } } /** * @brief 延时毫秒(ms)函数 * * @param nms 需要延时多少毫秒 * * @return void */ void delay_ms(uint16_t nms) { uint32_t i; for(i = 0; i < nms; i++) delay_us(1000); } //RCC_ClocksTypeDef RCC_Clockss; //void delay_us(uint32_t time) //{ // uint16_t i; // for (i = 2; i <( time*0.07); i++); // // for (i = 2; i <( time*0.082); i++); //} //void delay_ms(uint32_t time) //{ // uint32_t i,j; // for(i = time;i>0;i--) // for(j = 1220;j>0;j--); //} // ////初始化延时系统,参数为CPU频率 //void DelayInit() //{ // RCC_GetClocksFreq(&RCC_Clockss); ////打开CYCCNT功能,并把计数器清零,最后打开计数器对cpu时钟进行向上计数 // DEM_CR |= DEM_CR_TRCENA; //// DWT_CYCCNT = 0u; //根据需要如果调试,或其他程序要使用CYCCNT时注释掉,否则可直接清零 // DWT_CR |= DWT_CR_CYCCNTENA; //} // // //延时函数,参数为需要延时的微秒数 //void Delayus(u32 usec) //{ // u32 startts,endts,ts; // //保存进入函数时的计数器值 // startts = DWT_CYCCNT; // ts = (usec-5) * (RCC_Clockss.SYSCLK_Frequency /(1000*1000) ); //计算达到所需延时值的cpu时钟数,^-^如果想要更精确此处可以减去运行前面代码所需的时钟数。 // endts = startts + ts; //计算达到所需延时时间的DWT_CYCCNT计数值,超过32bit所能表达的最大值2的32次方-1是自动绕回丢弃进位 // if(endts > startts) //判断是否跨越最大值边界 // { // while(DWT_CYCCNT < endts); //等到计数到所需延时值的cpu时钟数值 // } // else // { // while(DWT_CYCCNT > endts); //等待跨域32bit的最大值,2的32次方-1 // while(DWT_CYCCNT < endts); //等到计数到所需延时值的cpu时钟数值 // } //}