SysTick 简介
SysTick—系统定时器是属于CM3内核中的一个外设,内嵌在NVIC中。系统定时器是一个24bit 的向下递减的计数器,计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK 等于72M。当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往 复。 因为SysTick是属于CM3内核的外设,所以所有基于CM3内核的单片机都具有这个系统定时器, 使得软件在CM3单片机中可以很容易的移植。系统定时器一般用于操作系统,用于产生时基,维 持操作系统的心跳。
SysTick 寄存器介绍
SysTick—系统定时器有4个寄存器,简要介绍如下。在使用SysTick产生定时的时候,只需要配 置前三个寄存器,最后一个校准寄存器不需要使用。
SysTick 定时实验
利用SysTick 产生1s的时基,LED以1s的频率闪烁。
编程要点
1、设置重装载寄存器的值
2、清除当前数值寄存器的值
3、配置控制与状态寄存器
代码分析
SysTick 属于内核的外设,有关的寄存器定义和库函数都在内核相关的库文件core_cm3.h中。
SysTick 配置库函数
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
// 不可能的重装载值,超出范围
if ((ticks- 1UL) > SysTick_LOAD_RELOAD_Msk) {
return (1UL);
}
// 设置重装载寄存器
SysTick->LOAD = (uint32_t)(ticks- 1UL);
// 设置中断优先级
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS)- 1UL);
//设置当前数值寄存器
SysTick->VAL = 0UL;
//设置系统定时器的时钟源为AHBCLK=72M
//使能系统定时器中断
//使能定时器
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return(0UL);
}
用固件库编程的时候我们只需要调用库函数SysTick_Config()即可,形参ticks用来设置重装载寄 存器的值,最大不能超过重装载寄存器的值224,当重装载寄存器的值递减到0的时候产生中断, 然后重装载寄存器的值又重新装载往下递减计数,以此循环往复。紧随其后设置好中断优先级, 最后配置系统定时器的时钟等于AHBCLK=72M,使能定时器和定时器中断,这样系统定时器就 配置好了,一个库函数搞定。 SysTick_Config()库函数主要配置了SysTick中的三个寄存器:LOAD、VAL和CTRL,有关具体 的部分看代码注释即可。
Systick.c
#include "Systick.h"
void SysTick_Delay_us(uint32_t us)
{
uint32_t i = 0;
SysTick_Config(72);
for(i=0;i<us;i++)
{
while(!((SysTick->CTRL) & (1<<16)));
}
//关闭定时器使能
SysTick ->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //清0
}
void SysTick_Delay_ms(uint32_t ms)
{
uint32_t i = 0;
SysTick_Config(72000);
for(i=0;i<ms;i++)
{
while(!((SysTick->CTRL) & (1<<16)));
}
//关闭定时器使能
SysTick ->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //清0
}
Systick.h
#ifndef __SYSTICK_H
#define __SYSTICK_H
#include "stm32f10x.h" // Device header
#include "core_cm3.h"
void SysTick_Delay_ms(uint32_t ms);
void SysTick_Delay_us(uint32_t us);
#endif
main函数
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "Systick.h"
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 ;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE,&GPIO_InitStruct);
while(1)
{
GPIO_ResetBits(GPIOE,GPIO_Pin_5);
//Delay_ms(500); //延时500毫秒
SysTick_Delay_ms(500);
GPIO_SetBits(GPIOE,GPIO_Pin_5);
//Delay_ms(500);
SysTick_Delay_ms(500);
}
}