运用Systick编写延时函数以及遇到的问题及其解决方法

运用Systick编写延时函数以及遇到的问题及其解决方法

我对Systick的理解

Systick属于Cotex-M4内核中的外设,是一个24位的向下递减计数器,我们每次所配置是PLL锁相环的时钟,正是Systick的时钟;定时器都有一个自动重装载值寄存器,当自动重装载值递减到0的时,会产生一次中断,而我们可以通过改变这个重装载值,来设定我们要的延时时间,从而起到延时作用。

开发平台

1、运用STM32F429在标准库上开发
2、KEIL 5.25.2.0

初始化Systick

void SYSTICK_INIT(uint16_t fosc)	//F429的时钟频率为180M,所以填入的参数我会填入180
{					//这样我每一次进入中断的时间为1us。(180/180M = 1us)
    if(SysTick_Config(fosc)==1)		//SysTick_Config()已经在cm4.h文件里写好,直接调用
    {
        while(1);
    }
}

编写延时函数思路

编写延时函数的思路是:我定义一个全局变量,当Systick每次进入中断时,中断服务函数让这个全局变量自减1,而我要延时多少秒,就进入这个中断多少次,而当进入延时函数时,我用一个while一直死循环来等待这个全局变量减到0为止,从而起到了精准的延时效果。

定义一个全局变量

__IO uint32_t tim_counter = 0;

延时函数的编写

void DELAY_US(__IO uint32_t US) //传入参数为要延时的时间,单位为us
{
    tim_counter = US;		//把实参传给全局变量,令他进入中断自减
    while(tim_counter != 0);	//死循环等待tim_counter减为0,不为0就一直等待
}
    void DELAY_MS(__IO uint32_t MS)  //传入参数为要延时的时间,单位为us
{ 
 do{
    DELAY_US(1000);		//等待1ms就是等待1000us
   }while(MS--);		
 while(tim_counter!=0);		//死循环等待
}

编写中断服务函数

void SysTick_Handler(void)
{
    TIMEDELAY_HANDLE();
}

void TIMEDELAY_HANDLE(void)
{
    if(tim_counter != 0)
    {
        tim_counter--;  
    }
}

这样Systick中断延时函数就写好了,现在说说我在编写时遇到的问题:

原来是编译器的优化问题!

当我定义的全局变量和形式参数没有加“__IO”的时候:

我第一次写的时候没有加__IO时,发现并没有起到我想要的延时效果,所以我就F12去看一下这个__IO标识符的个什么鬼,同样在cm4.h里面定义好了,代码如下:

#ifdef __cplusplus
  #define   __I     volatile             /*!< Defines 'read only' permissions*/
#else
  #define   __I     volatile const       /*!< Defines 'read only' permissions*/
#endif
#define     __O     volatile             /*!< Defines 'write only' permissions*/
#define     __IO    volatile             /*!< Defines 'read / write' permissions*/

这里发现了volatile关键字,经过百度和CSDN的博客中认识到,在定义变量的时候加入volatile关键字,其实就是在跟编译器说,我定义的这个volatile变量的值是会随时发生改变的,你不要对他进行优化,不然有可能会出错。当我加入关键字后,我定义的全局变量和形式参数就不会被编译器优化,从而实现了我想要的延时功能。

当我未设置编译器的优化等级的时候:

在这里插入图片描述
在新建工程的时候,优化等级我默认选择了Level 1,而这仅仅这个选项,让我定义的全局变量tim_counter和形式参数都被优化了,从而需要用到__IO标识符。但如果把优化等级0,不需要用到__IO标识符也同样可以实现延时功能。

解决方法如下:

在这里插入图片描述

结束语

第一次写博客,可能一些写的不太好,if(有错误){欢迎在评论区里指正} 谢谢。

发布了10 篇原创文章 · 获赞 12 · 访问量 586

猜你喜欢

转载自blog.csdn.net/hjy457459/article/details/100165790