SysTick簡介
SysTick:系統定時器,24位,只能遞減,存在於內核,嵌套在NVIC中,所有的Cortex-M內核的單片機都具有這個定時器。
SysTick功能框圖
counter在時鐘的驅動下,從reload初值開始往下遞減計數到0,產生中斷和置位COUNTFLAG標誌。然後又從reload值開始重新遞減計數,如此循環。
SysTick寄存器
SysTick定時時間計算
t:一個計數循環的時間,跟reload和CLK有關 t = reload * ( 1/clk )
CLK:72M或者9M,由CTRL寄存器配置
RELOAD:24位,用戶自己配置
SysTick寄存器結構體
typedef struct
{
__IO uint32_t CTRL; /*控制及狀態寄存器*/
__IO uint32_t LOAD; /*重裝載數值寄存器 */
__IO uint32_t VAL; /*當前數值寄存器*/
__I uint32_t CALIB; /*校準寄存器 */
} SysTick_Type;
SysTick配置庫函數
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
//reload寄存器爲24bits,最大值2^24
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);
//配置reload寄存器初始值
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
//配置中斷優先級爲(1<<4)-1,優先級爲最低
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
//配置counter計數器的值
SysTick->VAL = 0;
//配置SysTick的時鐘爲72M
//使能中斷
//使能SysTick
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return (0);
}
1-STM32裏面無論是內核還是外設都是使用4個二進制位來表示中斷優先級。
2-中斷優先級的分組對內核和外設同樣適用。當比較的時候,只需要把內核外設的中斷優先級的四個位按照外設的中斷優先級來分組來解析即可,即人爲的分出搶佔優先級和子優先級。
3-systick中斷優先級配置的是scb->shprx寄存器;而外設的中斷優先級配置的是nvic->iprx,有優先級分組,有搶佔優先級和子優先級的說法。
延時函數編寫
main.c
#include "stm32f10x.h"
#include "bsp_led.h"
#include"bsp_systick.h"
int main(void)
{
LED_GPIO_Config();
while(1)
{
LED_G(OFF);
SysTick_Delay_ms(500);
LED_G(ON);
SysTick_Delay_ms(500);
}
}
bsp_led.c
#include "bsp_led.h"
void LED_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK, ENABLE);
GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);
}
bsp_led.h
#ifndef __BSP_LED_H
#define __BSP_LED_H
#include "stm32f10x.h"
#define LED_G_GPIO_PIN GPIO_Pin_0
#define LED_G_GPIO_PORT GPIOB
#define LED_G_GPIO_CLK RCC_APB2Periph_GPIOB
#define ON 1
#define OFF 0
// \
#define LED_G(a) if(a) \
GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN); \
else GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
void LED_GPIO_Config(void);
#endif /* __BSP_LED_H */
bsp_systick.c
#include "bsp_systick.h"
void SysTick_Delay_us(uint32_t us)
{
uint32_t i;
SysTick_Config(72);
for(i=0; i<us; i++)
{
while( !((SysTick->CTRL) & (1<<16)) );
}
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}
void SysTick_Delay_ms(uint32_t ms)
{
uint32_t i;
SysTick_Config(72000);
for(i=0; i<ms; i++)
{
while( !((SysTick->CTRL) & (1<<16)) );
}
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}
bsp_systick.h
#ifndef __BSP_SYSTICK_H
#define __BSP_SYSTICK_H
#include "stm32f10x.h"
#include "core_cm3.h"
void SysTick_Delay_us(uint32_t us);
void SysTick_Delay_ms(uint32_t ms);
#endif /* __BSP_SYSTICK_H */