/**************************************************************************** * SysTick系統滴答定時(shí)學(xué)習筆記 * //深入研究 * * *****************************************************************************/ #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)) //校準值寄存器 肯定會(huì )有個(gè)別人不知道宏定義的意思,這里我先介紹一下宏定義首先肯定是看最里面的括號,也就是(volatile unsigned long *), 這個(gè)用來(lái)修飾地 址:0xE000E010,當然就是把這個(gè)地址強制轉換為unsigned long型的指針. 然后再開(kāi)外部的*,這個(gè)就不難理解了, 指針前面加* 就是取值了。 unsigned long SysTick_Delay;//全局變量 // 所以SYSTICK_CSR 的意思就是存放在0xE000E01C地址的值.大家都 //配置寄存器 //明白了吧,學(xué)C語(yǔ)言的人因該都知道啊,我們開(kāi)始看下面。 void SysTick_InitStructReadCmd(void) { if(SysTick_Config(72)) //SYSTICK_LOAD = SystemCoreClock / 1000000; //重要部分就在這里 系統AHB時(shí)鐘72000000 / 1000000
{
while(1);
} SYSTICK_CSR |= 0x06; //先關(guān)閉SysTick使能用的時(shí)候在打開(kāi) } //SysTick中斷服務(wù)程序 void SysTick_Hangler(void) { SYSTICK_VAL = 0; //當前值寄存器清零 if(SysTick_Delay != 0x00) //判斷延時(shí)SysTick_Delay 是否等于0 { SysTick_Delay--; //減一次 10us } } //延時(shí)函數 void Delay_10us(unsigned long Countlinef) { SYSTICK_CSR |= 0x07; //啟動(dòng)SysTick使能 SysTick_Delay = Countlinef; //把延時(shí)變量賦值SysTick_Delay全局變量 while(SysTick_Delay != 0); //判斷延時(shí)時(shí)間是否到 SYSTICK_CSR |= 0x06; //時(shí)間到關(guān)閉 SysTick使能用的時(shí)候在打開(kāi) } int main(void) { SystemInit(); //注意這么是把系統時(shí)鐘設初始化為 72M主頻,這里是必須的 SysTick_InitStructReadCmd(); while(1) { GPIOD->BSRR = 0x00000100; Delay_10us(100000) ; //實(shí)現1ms延時(shí) GPIOD->BRR = 0x00000100; } } //====================================END=============================================// /* 好了我們開(kāi)始講解程序1us是怎么實(shí)現的,我們使用時(shí)鐘源為AHB時(shí)鐘,AHB系統頻率陪配置為72MHZ SYSTICK_LOAD = SystemCoreClock / 1000000; SysTick重載初值重要的地方就在這里 1:SystemCoreClock 這個(gè)是什么意思,跟蹤庫函數找到如下: #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(); 是系統已經(jīng)把SystemCoreClock配置成72M下面就不難理解了, 先看一下計算公式:T = TICKS * (1/f); T : 為要計時(shí)的總時(shí)間。 TICKS :為SYSTICK_LOAD 的輸入參數。 (1/f)為使用時(shí)鐘源的時(shí)鐘周期,f為時(shí)鐘源的時(shí)鐘頻率 使用時(shí)鐘源為AHB時(shí)鐘, 頻率被配置72M; 把SYSTICK_LOAD重載寄存器賦值為 SystemCoreClock / 100000;大家 發(fā)現了什么,就是72000000 / 1000000 = 72; 大家都應該知道了72個(gè)時(shí)鐘周期 中斷一次,大家接著(zhù)看(1/f)是時(shí)鐘周期的時(shí)間。1/72M = 0.13888888888888888888888888888889; 一個(gè)時(shí)鐘周期時(shí)間*72時(shí)鐘周期中斷一次 1us誕生了,0.13888888888888888888888888888889*72 = 1;1us哈哈哈大家明白了吧。 */ |