delay_init() delay_ms() 非os环境下的代码理解

void delay_init(u8 SYSCLK)
{
#if SYSTEM_SUPPORT_OS                         //如果需要支持OS.
    u32 reload;
#endif
     SysTick->CTRL&=~(1<<2);                    //SYSTICK使用外部时钟源     
    fac_us=SYSCLK/8;                        //不论是否使用OS,fac_us都需要使用

#if SYSTEM_SUPPORT_OS                         //如果需要支持OS.
    reload=SYSCLK/8;                        //每秒钟的计数次数 单位为K       
    reload*=1000000/delay_ostickspersec;    //根据delay_ostickspersec设定溢出时间
                                            //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右    
    fac_ms=1000/delay_ostickspersec;        //代表OS可以延时的最少单位       
    SysTick->CTRL|=1<<1;                       //开启SYSTICK中断
    SysTick->LOAD=reload;                     //每1/delay_ostickspersec秒中断一次    
    SysTick->CTRL|=1<<0;                       //开启SYSTICK    
#else
    fac_ms=(u16)fac_us*1000;                //非OS下,代表每个ms需要的systick时钟数   
#endif

}                

系统嘀嗒校准值固定为 9000 ,当系统嘀嗒时钟设定为 9MHz(HCLK/8 的最大值 ) ,产生 1ms 时间
基准。      这段解释是在《stm32中文参考手册》中找到的

疑问点1

上面这段话说是产生1ms 值所需要的设置,是不是和上面的代码有冲突,fac_us =SYSCLK/8

 

/延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK                               1MHZ = 1000000HZ
//SYSCLK单位为Hz,nms单位为ms                            1S = 1000 ms
//对72M条件下,nms<=1864 
void delay_ms(u16 nms)
{                     
    u32 temp;                                                                       
    SysTick->LOAD=(u32)nms*fac_ms;            //时间加载(SysTick->LOAD为24bit)
    SysTick->VAL =0x00;                       //清空计数器
    SysTick->CTRL=0x01 ;                      //开始倒数  
    do
    {
        temp=SysTick->CTRL;
    }while((temp&0x01)&&!(temp&(1<<16)));    //等待时间到达   
    SysTick->CTRL=0x00;                       //关闭计数器
    SysTick->VAL =0X00;                       //清空计数器              

疑问点2

SysTick->LOAD=(u32)nms*fac_ms;      这个语句显示的是频率,加载到load这个寄存器不会有什么错误吧!

什么都应该基于实践得来的! 想来想去,不如多实践实践。

 SysTick->LOAD=(u32)nms*fac_ms;            //时间加载(SysTick->LOAD为24bit)

比如·我现在要设置4ms的延时时间!

把上面的公式展开得到  4*sysclk/8*1000  ,这个数字装入LOAD寄存器中去!

void delay_init(u8 SYSCLK)
{
#if SYSTEM_SUPPORT_OS                         //如果需要支持OS.
    u32 reload;
#endif
     SysTick->CTRL&=~(1<<2);                    //SYSTICK使用外部时钟源     
    fac_us=SYSCLK/8;                        //不论是否使用OS,fac_us都需要使用

因为这里我们使用的是72mz的频率(SYSCLK为72MHZ) 所以8分频后为9Mhz  ,周期为0.9us

接近1us.    即load中的次数每改变一次, 时间改变为0.9us    

把上面4ms 需要的次数,乘以周期  8/sysclk  ,即得到所需要的时间!

总结: 上面的延时是不准确的,而且还是基于频率 为9MHZ,不具有灵活性!

               可用于对时间精度不高的场合!

            systick中的细节还是要参考《cm3 权威指南》 中的内容!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值