深入了解Systick系统滴答定时学习笔记

2012年11月16日 12:26    发布者:爱好单片机

/*****************************************************************************                 SysTick系统滴答定时学习笔记*          //深入研究**            *****************************************************************************/#ifndef                 _SYSTICK_H#define                 _SYSTICK_H#include "SysTick.h"                        #define    SYSTICK_CSR   (*((volatile unsigned long *) 0xE000E010)) //控制寄存器#define    SYSTICK_LOAD  (*((volatile unsigned long *) 0xE000E014)) //重载寄存器#define    SYSTICK_VAL   (*((volatile unsigned long *) 0xE000E018)) //当前值寄存器#define    SYSTICK_CALRB (*((volatile unsigned long *) 0xE000E01C)) //校准值寄存器肯定会有个别人不知道宏定义的意思,这里我先介绍一下宏定义首先肯定是看最里面的括号,也就是(volatile unsigned long *),这个用来修饰地  址:0xE000E010,当然就是把这个地址强制转换为unsigned long型的指针. 然后再开外部的*,这个就不难理解了,指针前面加* 就是取值了。                           unsigned long SysTick_Delay;//全局变量       // 所以SYSTICK_CSR 的意思就是存放在0xE000E01C地址的值.大家都 //配置寄存器                                 //明白了吧,学C语言的人因该都知道啊,我们开始看下面。void SysTick_InitStructReadCmd(void){    if(SysTick_Config(72)) //SYSTICK_LOAD = SystemCoreClock / 1000000;    //重要部分就在这里  系统AHB时钟72000000 / 1000000
   {
      while(1);
    }      SYSTICK_CSR |= 0x06;                   //先关闭SysTick使能用的时候在打开}//SysTick中断服务程序void SysTick_Hangler(void){    SYSTICK_VAL = 0;                     //当前值寄存器清零    if(SysTick_Delay != 0x00)          //判断延时SysTick_Delay 是否等于0    {        SysTick_Delay--;                //减一次 10us    }               } //延时函数void Delay_10us(unsigned long Countlinef){                                           SYSTICK_CSR |= 0x07;                         //启动SysTick使能    SysTick_Delay = Countlinef;                  //把延时变量赋值SysTick_Delay全局变量    while(SysTick_Delay != 0);                   //判断延时时间是否到    SYSTICK_CSR |= 0x06;                         //时间到关闭 SysTick使能用的时候在打开}int main(void){    SystemInit();   //注意这么是把系统时钟设初始化为 72M主频,这里是必须的    SysTick_InitStructReadCmd();    while(1)    {        GPIOD->BSRR = 0x00000100;        Delay_10us(100000)  ; //实现1ms延时        GPIOD->BRR  = 0x00000100;    }}//====================================END=============================================///*   好了我们开始讲解程序1us是怎么实现的,我们使用时钟源为AHB时钟,AHB系统频率陪配置为72MHZ     SYSTICK_LOAD = SystemCoreClock / 1000000; SysTick重载初值重要的地方就在这里     1:SystemCoreClock 这个是什么意思,跟踪库函数找到如下:        #ifdef SYSCLK_FREQ_HSE        uint32_t SystemCoreClock         = SYSCLK_FREQ_HSE;               #elif defined SYSCLK_FREQ_24MHz        uint32_t SystemCoreClock         = SYSCLK_FREQ_24MHz;             #elif defined SYSCLK_FREQ_36MHz        uint32_t SystemCoreClock         = SYSCLK_FREQ_36MHz;               #elif defined SYSCLK_FREQ_48MHz        uint32_t SystemCoreClock         = SYSCLK_FREQ_48MHz;               #elif defined SYSCLK_FREQ_56MHz        uint32_t SystemCoreClock         = SYSCLK_FREQ_56MHz;                #elif defined SYSCLK_FREQ_72MHz        uint32_t SystemCoreClock         = SYSCLK_FREQ_72MHz;                #else /*!< HSI Selected as System Clock source *///     uint32_t SystemCoreClock         = HSI_VALUE;     /*这里不难看出,我们初始化SystemInit(); 是系统已经把SystemCoreClock配置成72M下面就不难理解了,               先看一下计算公式:T = TICKS * (1/f);                 T : 为要计时的总时间。               TICKS :为SYSTICK_LOAD 的输入参数。               (1/f)为使用时钟源的时钟周期,f为时钟源的时钟频率               使用时钟源为AHB时钟, 频率被配置72M;               把SYSTICK_LOAD重载寄存器赋值为 SystemCoreClock / 100000;大家               发现了什么,就是72000000 / 1000000 = 72; 大家都应该知道了72个时钟周期               中断一次,大家接着看(1/f)是时钟周期的时间。1/72M = 0.13888888888888888888888888888889;              一个时钟周期时间*72时钟周期中断一次               1us诞生了,0.13888888888888888888888888888889*72 = 1;1us哈哈哈大家明白了吧。          */                               

#endif

网友评论

爱好单片机 2012年11月16日
这个程序是我用做项目的时候写的,红外解码上面用到的1us很精准,大家可以放心使用
z81032643 2012年11月16日
学习了
爱好单片机 2012年11月16日
void SysTick_Hangler(void)

{

  //  SYSTICK_VAL = 0;                     //当前值寄存器清零

    if(SysTick_Delay != 0x00)          //判断延时SysTick_Delay 是否等于0

    {

        SysTick_Delay--;                //减一次 10us

    }               

}
不好意思这个程序,以前被我给过,把当前值寄存器清零去掉


zhangaiminab 2012年11月29日
mark