论坛元老
![Rank: 8]() ![Rank: 8]()
- 积分
- 3300
- 金钱
- 3300
- 注册时间
- 2018-5-11
- 在线时间
- 586 小时
|
推荐
![]() 楼主 | 发表于 2018-7-29 21:46:47 | 只看该作者
本帖最后由 warship 于 2018-9-21 10:47 编辑
好了,本该就此打住的,但既然说到延时了,就不得不吐槽一下原子的延时函数, 那个delay_ms(u16 nms)只能是16位的参数不说,还进一步限制最大只能延时1864ms, 如果初学者一不小心,想延时2秒,嘿嘿,不好意思,越界了!!! 所以建议索性把这个延时程序也换了,保证你可以一次延时5分钟以上,足够你闭目养神的了。
而且重要的是:延时函数仅反复读取SYSTICK的当前值,直到给定的延时时间到达, 不影响SYSTICK的自动重装,也不影响其中断
//微秒延时函数: //nus:0~2^32/fac_us=4294967296/9=477,218,588 高达4.7亿微秒 void delay_us(u32 nus) { u32 ticks; u32 told,tnow,tcnt=0; u32 reload=SysTick->LOAD; //reload中保存原1ms装载的值 ticks=nus*9; //需要延时的节拍数 tcnt=0; told=SysTick->VAL; //刚进入时的计数器值 while(1) { tnow=SysTick->VAL; //当前计数值 if(tnow!=told) //如果计数值有变化, 则(这里注意一下SYSTICK是一个递减的计数器就可以了): { if(tnow<told) //一般情况, 计数器递减了, 则累计经历的节拍数 tcnt+=told-tnow; else //有溢出的情况, 计数值变大了, 则累计时要增加满载值 tcnt+=reload-tnow+told; told=tnow; //每次累计后, 将当前值变成基础旧值 if(tcnt>=ticks)break; //累计节拍数大于/等于需要延迟的节拍数,即延时时间到达, 则退出本函数. } } }
//毫秒延时函数: //将给定的延时毫秒数乘以1000后直接调用微秒延时函数 //nms:0---2^32/1000/fac_us=47万毫秒 void delay_ms(u32 nms) { delay_us((u32)(nms*1000)); //直接调用delay_us函数进行延时 }
后注:最新修改的delay函数可以确保SYSTICK中断不会影响延时精度,延时函数的具体实现过程已经考虑到延时过程中进入中断的情况了。最新的delay请关注https://github.com/ShuifaHe/STM32/blob/delay/delay.c,如果觉得对你有用的话,请帮忙在GITHUB下载后点个赞哦。
|
|