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