一、Systick簡介
二、Systick timer
三、相關寄存器介紹
除了上面說的STK_VAL,下面帶大家了解相關的寄存器和寄存器位。
1. SysTick_CSR 控制狀態寄存器
Bit1: TICKINT
Bit2: CLKSOURCE
Bit16:COUNTFLAG
2. SysTick_LOAD
0-23 24位的重裝值,這也是為什么只能計數到2^24
3. SysTick_VAL 當前值寄存器
4. SysTick_CALRB 校準寄存器
由于我們要寫精確延時的LED流水燈,所以我們需要使用Systick進行精確延時,理論上它的最小計時單位為AHB的時鐘周期,1/72000000秒,72分之一微秒。
我們在昨天流水燈的基礎上,新建兩個文件,SysTick.c和SysTick.h
具體代碼如下
SysTick.h
#ifndef __SYSTICK_H__
#define __SYSTICK_H__
#include "stm32f10x.h"
#define __SYSTICK_H__
#include "stm32f10x.h"
void SysTick_Init(void);
void Delay_us(__IO u32 nTime);
#endif
SysTick.c
#include "SysTick.h"
#include "stm32f10x.h"
#include "stm32f10x.h"
static __IO u32 TimingDelay;
void SysTick_Init(void)
{
if(SysTick_Config(SystemCoreClock/100000))
{
while(1);
}
//關閉滴答定時器
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
{
}
void TimingDelay_Decrement(void)
{
if(TimingDelay != 0x00)
{
TimingDelay--;
}
}
{
}
void Delay_us(__IO u32 nTime)
{
TimingDelay = nTime;
//使能滴答定時器
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
while(TimingDelay != 0);
}
{
}
中斷函數,在stm32f10xit.c
void SysTick_Handler(void)
{
TimingDelay_Decrement();
}
{
}
修改main.c如下
#include "stm32f10x.h"
#include "led.h"
#include "SysTick.h"
#include "led.h"
#include "SysTick.h"
int main(void)
{
}
這里面只有兩個函數,SysTick_Init()和Delay_us(),一個是配置SysTick定時器,一個是進行精確延時
中斷函數也只是運行了一個自定義函數,看看不難理解
SysTick_Config(SystemCoreClock/100000);
SystemCoreClock是系統時鐘的宏,SystemCoreClock = 72000000
我們的計時總時間 T = tick * (1/f),tick為SysTick_Config()的輸入參數
1/f為SysTick timer使用的時鐘源的時鐘周期,f為該時鐘源的時鐘頻率。
上面的語句中:tick = SystemCoreClock/100000=720,表示720個時鐘周期中斷一次,1/f是時鐘周期的時間,1/f = 1/72us,所以T = 720*(1/72) = 10us
SysTick_CTRL_ENABLE_Msk,這是一個宏,用來指示寄存器的特定位置或進行位屏蔽用的,那么他是如何定義的呢?

其中的寄存器位指示宏:SysTick_xxx_Pos,
寄存器的位屏蔽宏:SysTick_xxx_Msk,宏展開是xxx的位全部置1后,左移SysTick_xxx_Pos位,1ul使之無符號長整型,上圖中SysTick_CTRL_CLKSOURCE_Msk,宏展開為1ul<<SysTick_CTRL_CLKSOURCE_Pos,即1左移2位,得到的只有Bit2:CLKSOURCE位被置1,而其它位為0,這樣搭配& | 能夠很方便的修改寄存器的某些位,這樣就程序就不難理解了.就說這么多吧,已經講得很多了,不懂得自己想想,琢磨一下就通了。