利用滴答定时器(SysTick)实现简单的延时函数

预备知识:

对标准库来说,如果定义了时钟频率,则系统会默认初始化该时钟频率。

SysTick是CM4的内核外设,是一个24位的向下递减计数器,每次计数时间是1/SYSCLK,即1/168000000。
SysTick计数时间的计算:t=重装载值*1/AHB时钟频率。1/AHB时钟频率即是计数一次的时间。一般把重装载值定为128000000/100000=1280,则10us中断一次;一般不设置为1us中断一次,这样中断频率太高,偏移了程序重心。

 

正文:

程序源码:

在main.c中

 

#include "sys.h"
#include "led.h"

// "__IO"在Core_cm4.h中被重定义,原型是"volatile" ①
__IO uint32_t TimingDelay;      

// 延时函数
void Delay(__IO uint32_t nTime)    
{
    TimingDelay = nTime;
    while(TimingDelay != 0);
}

// 主函数
int main(void)
{ 
    // 初始化LED端口
    LED_Init();
    // 初始化SysTick ②
    if(SysTick_Config(SystemCoreClock/1000))  
    {
        // Capture error
        while(1);
    }
    // LED闪烁
    while(1)                                   
    {
        Delay(250);   GPIO_SetBits(GPIOF,GPIO_Pin_9);
        Delay(250); GPIO_ResetBits(GPIOF,GPIO_Pin_9);
    }
}


/*------------------------------------------------------------------------------------
注释:
    ①:volatile 的作用就是指示编译器不要因优化而省略此指令,必须每次都直接读写其值。
       写一段测试代码如下:
         u8  test;
         test = 1;
         test = 2;
         test = 3;

       设置优化级别中级
       运行后test会被直接取值为3 只有最后一个语句被编译
       
       如用volatile:
         volatile u8 test;
         test = 1;
         test = 2;
         test = 3;
       则所有语句都会被编译。test先后被设置成1、2、3
       由此可以看出这个作用在IO操作,寄存器操作,特殊变量,多线程变量读写都是很重要。
    ②:SysTick_Config的参数,是一个时钟次数,叫systick重装定时器的值。意思就是多少个
       1/fosc 时间后中断一下。
       这里 SystemCoreClock/1000 为没过1ms中断一次,SystemCoreClock为系统时钟频率。
       计算方法为:
       SystemCoreClock ÷ timer = 1ms
       假设SystemCoreClock为128M,单位为Hz。则:
       1ms = 1128MHz ÷ timer
           = 128M/s ÷ timer
             
                128M
               ------
       timer =   1s
               ------
               0.001s
                                        
                128M
       timer = ------
                1000
              
------------------------------------------------------------------------------------*/

 

在stm32f4xx_it.c中

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_it.h"
 
/* 变量定义 ------------------------------------------------------------------*/
// 利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数
extern __IO uint32_t TimingDelay;

/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
    
    if(TimingDelay != 0x00)
    {
        TimingDelay--;
    }
}

注意:

1.在stm32中,中断函数在stm32f4xx_it.c中,不能像51那样写在main.c文件下。

2.关键字extern拓展变量作用范围的用法。

3.__IO == volatile

参考资料:

https://blog.csdn.net/u010834669/article/details/80204195

 

posted @ 2018-12-01 20:16  路合华  阅读(2220)  评论(0编辑  收藏  举报