查看: 2364|回复: 0

STM32F4步步为营三:延时函数

[复制链接]
  • TA的每日心情
    奋斗
    2023-12-3 18:51
  • 签到天数: 772 天

    连续签到: 1 天

    [LV.10]以坛为家III

    发表于 2014-7-15 19:09:54 | 显示全部楼层 |阅读模式
    分享到:
    STM32F429 Discovery开发板,集成了ST_LINK2和2.4寸的TFT  LCD彩屏,可以为学习开发带来不少的方便。此外,还有64Mbits SDRAM,ST MEMS,LED,按键及USB OTG  micro-B接口。本文将介绍这款开发板的延时函数。
            在讨论延时函数之前,先说一下带有CMSIS的程序的流程。
            可以看一下startup_stm32f429_439xx.s文件里启动的代码:
            _Vectors_Size  EQU  __Vectors_End - __VectorsAREA    |.text|, CODE, READONLY; Reset handlerReset_Handler    PROCEXPORT  Reset_Handler             [WEAK]IMPORT  SystemInitIMPORT  __mainLDR     R0, =SystemInitBLX     R0LDR     R0, =__mainBX      R0ENDP; Dummy Exception Handlers (infinite loops which can be modified)        可见,先调用了一个SystemInit的函数,然后才是主函数main.
            这个函数主要完成了系统时钟及各总线时钟的设置。其在system_stm32f4xx.c中定义。
            而其中的一些参数设置,又在其头文件Stm32f4xx.h中定义。
            比如:
    #if !defined  (HSE_VALUE)#define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */#endif /* HSE_VALUE **** @brief In the following line adjust the External High Speed oscillator (HSE) StartupTimeout value*/#if !defined  (HSE_STARTUP_TIMEOUT)#define HSE_STARTUP_TIMEOUT    ((uint16_t)0x05000)   /*!< Time out for HSE start up */#endif /* HSE_STARTUP_TIMEOUT */#if !defined  (HSI_VALUE)#define HSI_VALUE    ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/#endif /* HSI_VALUE */        就定义了各种频率的值。而硬件方面的值又在system_stm32f4xx.c中定义。
    /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */#if defined  (PLL_SOURCE_HSI)#define PLL_M      16#else#define PLL_M      8#endif#define PLL_N      360/* SYSCLK = PLL_VCO / PLL_P */#define PLL_P      2/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */#define PLL_Q      7        总之,到了main函数,系统的各个时钟已经设完。
            书归正转,STM32的延进函数可分为三种:
             
    • 第一种,就是平时51那种自己延时,这种有些不准,有些参数要自己去碰。
            如:
    void MyusDelay(__IO uint32_t nTime){   uint32_t i,j;for(j=0;j<nTime;j++) {for(i=0;i<45;i++) { ; }}}
             
    • 第二种是利用Systick中断去延时程序如下
            娈量声明:static __IO uint32_t TimingDelay;
            初始化:
    if (SysTick_Config(SystemCoreClock / 1000)){while (1);}        以上是延时1ms的值,要延10ms则应写成:
    if (SysTick_Config(SystemCoreClock / 100)){while (1);}        函数原型应写成:
    void Delay(__IO uint32_t nTime){TimingDelay = nTime;while(TimingDelay != 0);}        中断函数为:
    void SysTick_Handler(void){TimingDelay_Decrement();}
             
    • 第三种方法是用Systick的不中断功能。
            我们可以看下参考手册231页的寄存器值的说明如下:
            可见就三个值有用:
            CLKSOURCE:选则SysTick的时钟来源。一般选0
            TICKINT:这个值决定了是否中断。
            ENABLE:这个是使能SysTick.
            明白了上述下面就很简单了:
    void delay_ms(uint32_t nus){uint32_t temp;SysTick ->LOAD = 20*1000*nus;  //test ????SysTick ->VAL = 0x00;SysTick ->CTRL = 0x01;do{temp = SysTick->CTRL;}while((temp&0x01)&&(!(temp&(1<<16))));SysTick ->VAL = 0x00;SysTick ->CTRL = 0x00;}        主程序直接调用它就行了。
            三种方法比较,我认为还是中断最准最简单最实用,要注意的只有一点,定时时间不要小于1ms因为一但程序大了会有很多中断,这样就出现了不稳定因素。强烈建议设为10ms
            以下是中断和不中断的比较:
            这个不是中断的50ms:
           
            下图是用中断的50ms:
           
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-18 11:20 , Processed in 0.117219 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.