查看: 4935|回复: 4

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

[复制链接]
发表于 2012-11-16 12:26:45 | 显示全部楼层 |阅读模式
/****************************************************************************
*                 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 12:32:43 | 显示全部楼层
这个程序是我用做项目的时候写的,红外解码上面用到的1us很精准,大家可以放心使用
发表于 2012-11-16 14:03:10 | 显示全部楼层
学习了
 楼主| 发表于 2012-11-16 16:38:12 | 显示全部楼层
void SysTick_Hangler(void)

{

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

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

    {

        SysTick_Delay--;                //减一次 10us

    }               

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


发表于 2012-11-29 10:01:58 | 显示全部楼层
mark
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表