有不少初学者对delay_init()函数犯晕,其实这个函数可以简单到只有两行

2019-07-20 22:29发布

本帖最后由 warship 于 2018-7-29 22:30 编辑

有不少初学者对delay_init()函数犯晕,但每一个程序都绕不开,由于原子的例程里因为想兼容操作系统,搞了很多的宏条件,也难怪初学者难以读懂,
其实不光是初学者,说实在的,我没有用到OS,看着这个函数也头大(其实也是没有完全搞懂)
这两天看了一下,撇开对OS的支持(我想绝大多数的STM32初学者都不会上来就用OS的),
这个函数可以简单到只有两行。如下即可:

void delay_init(void)
{
  SysTick->LOAD=9000-1;    //装载值设定为9*1000-1=8999  即每ms中断一次
  SysTick->CTRL|=3;           //开启SYSTICK并允许中断
}


怎么样,简单吧?
你用它替换掉原子的函数,我保证能用。
楼下我会详细解释一下.

哦,对了,
忘记提示一句: 使用库函数编程的同学,也是一样可用的。
直接替换掉原函数就可以了。
其实使用库函数编程还是有优势的,看到寄存器编的代码可以直接拿来就用,
而使用寄存器编程的同学,临时想调用库函数就真的不是那么容易了,哈哈。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
49条回答
275891381
1楼-- · 2019-07-25 14:10
 精彩回答 2  元偷偷看……
imbest
2楼-- · 2019-07-25 15:01
warship 发表于 2018-12-1 16:27
不知道你为什么要在延时函数这里设断点,
你可以把断点设置在延时函数之后,
如果你怀疑延时不准确,

可以加您QQ或者微信吗?问题比较着急,这样太慢了,您可以私聊发给我号
imbest
3楼-- · 2019-07-25 16:34
275891381 发表于 2018-12-1 16:40
正解,还可以延时前后翻转个io,示波器看一下就可以了,更准
再说这么多人经验的积累,没人怀疑他不准的 ...

我不是怀疑,我现在程序卡在了延时函数里出不来
275891381
4楼-- · 2019-07-25 20:20
本帖最后由 275891381 于 2018-12-1 17:58 编辑
imbest 发表于 2018-12-1 16:44
我不是怀疑,我现在程序卡在了延时函数里出不来

你是不是开滴答定时器中断了,中段函数没有写

static   u8  fac_us=0;                                                             //us延时倍乘数        
//SYSTICK的时钟固定为HCLK时钟的1/8
//中断时间time  =  ( SysTick->LOAD + 1 ) / f                        f = AHB或AHB/8            (9000-1+1)/9M=1ms
void delay_init(void)
{
        //NVIC_SetPriority (SysTick_IRQn, x);默认是NVIC_SetPriority (SysTick_IRQn,15);
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //选择外部时钟  HCLK/8  9M 计数器减1为1/9000000秒
        fac_us=SystemCoreClock/8000000;                                                //9  
        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;                     //开启SYSTICK中断
        SysTick->LOAD=fac_us*1000-1;                                                               //每1/1000s中断一次        
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;                     //开启SYSTICK           
}        

//nus:0~2^32/fac_us=477218588.444us=477s        (fac_us=9)                                                                  
void delay_us(u32 nus)
{               
        u32 ticks;
        u32 told,tnow,tcnt=0;
        u32 reload=SysTick->LOAD;                                                            //LOAD的值                     
        ticks=nus*fac_us;                                                                               //需要的节拍数                           
        tcnt=0;
        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;                                                      //时间超过/等于要延迟的时间,则退出.
                }  
        }        
}
//nms:0---2^32/fac_us/1000ms=477218.588ms=477s
void delay_ms(u32 nms)
{
          delay_us((u32)(nms*1000));//普通方式延时
}



//systick中断服务函数
void SysTick_Handler(void)//内部中断,硬件自动清除标志位
{
                //xitong_haomiao++;
}

warship
5楼-- · 2019-07-25 21:18
imbest 发表于 2018-12-1 16:44
我不是怀疑,我现在程序卡在了延时函数里出不来

很可能是楼上所说的问题,
你先排除一下吧
imbest
6楼-- · 2019-07-25 22:05
 精彩回答 2  元偷偷看……

一周热门 更多>