SysTick 是属于 CM3 内核的外设,有关寄存器的定义和部分库函数都在 core_CM3.h 这个头文件中实现。
SysTick简介
SysTick—系统定时器是属于 CM3 内核中的一个外设,内嵌在 NVIC 中。系统定时器是一个 24bit的向下递减的计数器,计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟 SYSCLK等于 72M。当重装载数值寄存器的值递减到 0 的时候,系统定时器就产生一次中断,以此循环往复。
系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。
SysTick寄存器简介
有 4 个寄存器。在使用 SysTick 产生定时的时候,只需要配置前三个寄存器,最后一个校准寄存器不需要使用。
SysTick 控制及状态寄存器
SysTick 重装载数值寄存器
SysTick 当前数值寄存器
SysTick 校准数值寄存器(暂时先不考虑)
SysTick定时实验(产生1s的时基,控制led灯1s闪烁)
bsp_SysTick.c 和 bsp_ SysTick.h 文件用来存放 SysTick驱动程序及相关宏定义,中断服务函数放在 stm32f1xx_it.c 文件中。
编程要点
1、设置重装载寄存器的值
2、清除当前数值寄存器的值
3、配置控制与状态寄存器
代码 SysTick 配置库函数
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
//判断 tick 的值是否大于2^24,如果大于,则不符合规则
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);
//初始化reload寄存器的值
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
//配置中断优先级,配置15,默认为最低的优先级
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);
}
用固件库编程的时候我们只需要调用库函数 SysTick_Config() 即可,形参ticks 用来设置重装载寄存器的值,最大不能超过重装载寄存器的值 2^24,当重装载寄存器的值递减到 0 的时候产生中断,然后重装载寄存器的值又重新装载往下递减计数,以此循环往复。紧随其后设置好中断优先级,最后配置系统定时器的时钟等于 AHBCLK=72M,使能定时器和定时器中断,这样系统定时器就配置好了,一个库函数搞定。
bsp_SysTick.c
#include "bsp_systick.h"
void SysTick_Delay_us(uint32_t us)
{
uint32_t i;
SysTick_Config(72); //初始化并启动SysTick计数器及其中断。定义为72M,转变为1us
for(i=0;i<us;i++)
{
while(!((SysTick->CTRL) & (1<<16))); //在次内部循环,看计次是否到0,循环1us 。 SysTick 已经计到了 0,则该位为 1。
}
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //CTRL清零,重新进行1us倒数计次
}
void SysTick_Delay_ms(uint32_t ms)
{
uint32_t i;
SysTick_Config(72000); //初始化并启动SysTick计数器及其中断。定义为72000M,转变为1ms
for(i=0;i<ms;i++)
{
while(!((SysTick->CTRL) & (1<<16))); //在次内部循环,看计次是否到0,循环1ms 。 SysTick 已经计到了 0,则该位为 1。
}
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //CTRL清零,重新进行1ms倒数计次
}
bsp_ SysTick.h
#ifndef __BSP_SYSTICK_H_
#define __BSP_SYSTICK_H_
#include "stm32f10x.h"
#include "core_cm3.h" //SysTick_Config(72);来源于core_cm3.h中,所以添加此头文件
void SysTick_Delay_us(uint32_t us);
void SysTick_Delay_ms(uint32_t ms);
#endif
main.c
#include "stm32f10x.h" //相当于51单片中的#include <reg51.h>
#include "bsp_led.h"
#include "bsp_systick.h"
void delay(unsigned int i) //软件延时函数
{
while(i--);
}
int main(void)
{
//来到这里的时候,系统时钟已经被配置好72M.
LED_GPIO_Config();
while(1)
{
//GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
LED_G(OFF);
//delay(0xFFFFF);
SysTick_Delay_ms(1000); //1s=1000ms=10000000us
//GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
LED_G(ON);
SysTick_Delay_ms(1000);
//delay(0xFFFFF);
}
}