/**************************************************************************** * 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哈哈哈大家明白了吧。 */ |