SysTick寄存器介绍
SysTick寄存器总汇
寄存器名称 | 寄存器描述 |
---|---|
CTRL | SysTick控制及状态寄存器 |
LOAD | SysTick重装载数值寄存器 |
VAL | SysTick当前数值寄存器 |
CALIB | SysTick校准数值寄存器 |
①SysTick控制及状态寄存器
位段 | 名称 | 类型 | 复位值 | 描述 |
---|---|---|---|---|
16 | COUNTFLAG | R/W | 0 | 如果在上次读取本寄存器后,SysTick已经计到了0,则该位为1 |
2 | CLKSOURCE | R/W | 0 | 时钟源选择位,0=AHB/8,1=处理器时钟AHB |
1 | TICKINT | R/W | 0 | 1:SysTick倒数计数到0时产生SysTick异常请求,0:计数到0时无动作 |
0 | ENABLE | R/W | 0 | SysTick定时器的使能位 |
②SystTick重装载数值寄存器
位段 | 名称 | 类型 | 复位值 | 描述 |
---|---|---|---|---|
23:0 | RELOAD | R/W | 0 | 当倒数计数至0时,将被重装载的值 |
③SysTick当前数值寄存器
位段 | 名称 | 类型 | 复位值 | 描述 |
---|---|---|---|---|
23:0 | CURRENT | R/W | 0 | 读取时返回当前倒数计数的值,写它则使之清零,同时还会清除在SysTick控制及状态寄存器中的COUNTFLAG标志 |
SysTick定时实验
编程要点
1)设置重装载寄存器的值。
2)清除当前数值寄存器的值。
3)配置控制与状态寄存器。
bsp_led.c文件
#include "./led/bsp_led.h"
void LED_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( LED1_GPIO_CLK | LED2_GPIO_CLK | LED3_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LED2_GPIO_PIN;
GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LED3_GPIO_PIN;
GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStructure);
GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PIN);
GPIO_SetBits(LED3_GPIO_PORT, LED3_GPIO_PIN);
}
bsp_led.h文件
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"
#define LED1_GPIO_PORT GPIOB
#define LED1_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED1_GPIO_PIN GPIO_Pin_5
#define LED2_GPIO_PORT GPIOB
#define LED2_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED2_GPIO_PIN GPIO_Pin_0
#define LED3_GPIO_PORT GPIOB
#define LED3_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED3_GPIO_PIN GPIO_Pin_1
#define ON 0
#define OFF 1
#define LED1(a) if (a) \
GPIO_SetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);\
else \
GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN)
#define LED2(a) if (a) \
GPIO_SetBits(LED2_GPIO_PORT,LED2_GPIO_PIN);\
else \
GPIO_ResetBits(LED2_GPIO_PORT,LED2_GPIO_PIN)
#define LED3(a) if (a) \
GPIO_SetBits(LED3_GPIO_PORT,LED3_GPIO_PIN);\
else \
GPIO_ResetBits(LED3_GPIO_PORT,LED3_GPIO_PIN)
#define digitalHi(p,i) {p->BSRR=i;}
#define digitalLo(p,i) {p->BRR=i;}
#define LED1_TOGGLE digitalToggle(LED1_GPIO_PORT,LED1_GPIO_PIN)
#define LED1_OFF digitalHi(LED1_GPIO_PORT,LED1_GPIO_PIN)
#define LED1_ON digitalLo(LED1_GPIO_PORT,LED1_GPIO_PIN)
#define LED2_TOGGLE digitalToggle(LED2_GPIO_PORT,LED2_GPIO_PIN)
#define LED2_OFF digitalHi(LED2_GPIO_PORT,LED2_GPIO_PIN)
#define LED2_ON digitalLo(LED2_GPIO_PORT,LED2_GPIO_PIN)
#define LED3_TOGGLE digitalToggle(LED3_GPIO_PORT,LED3_GPIO_PIN)
#define LED3_OFF digitalHi(LED3_GPIO_PORT,LED3_GPIO_PIN)
#define LED3_ON digitalLo(LED3_GPIO_PORT,LED3_GPIO_PIN)
void LED_GPIO_Config(void);
#endif /* __LED_H */
bsp_SysTick.h文件
#ifndef __SYSTICK_H
#define __SYSTICK_H
#include "stm32f10x.h"
void SysTick_Init(void);
void Delay_us(__IO u32 nTime);
#define Delay_ms(x) Delay_us(100*x) //单位ms
void SysTick_Delay_Us( __IO uint32_t us);
void SysTick_Delay_Ms( __IO uint32_t ms);
#endif /* __SYSTICK_H */
bsp_SysTick.c文件
#include "bsp_SysTick.h"
#include "core_cm3.h"
#include "misc.h"
static __IO u32 TimingDelay;
/*
启动系统嘀嗒定时器
*/
void SysTick_Init(void)
{
/* SystemCoreClock / 1000 1ms中断一次
* SystemCoreClock / 100000 10us中断一次
* SystemCoreClock / 1000000 1us中断一次
*/
if (SysTick_Config(SystemCoreClock / 100000))
{
/* Capture error */
while (1);
}
}
/*
Delay_us(1):实现1x10us = 10us延时
*/
void Delay_us(__IO u32 nTime)
{
TimingDelay = nTime;
//使能嘀嗒定时器
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
while(TimingDelay != 0);
}
//获取节拍程序,在SysTick中断函数SysTick_Handler()中调用
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
#if 0
// 这个固件库函数在core_cm3.h中
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
// reload 寄存器为24bit,最大值为2^24
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);
// 配置reload初始值
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
//配置中断优先级为:1<<4-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);
}
#endif
// couter减一的时间等于1/systick_clk
//当counter 从reload 的值减小到0的时候,为一个循环,如果开启了中断则执行中断服务程序。
//同时CTRL的countflag位会置1
//这一个循环的时间为:reload * (1/systick_clk)
void SysTick_Delay_Us( __IO uint32_t us)//SysTick微妙级延时
{
uint32_t i;
SysTick_Config(SystemCoreClock/1000000);
for(i=0;i<us;i++)
{
//当计数器的值减到0的时候,CRTL寄存器的位16会置1
while( !((SysTick->CTRL)&(1<<16)) );
}
//关闭SysTick定时器
SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
}
void SysTick_Delay_Ms( __IO uint32_t ms)//SysTick毫秒级延时
{
uint32_t i;
SysTick_Config(SystemCoreClock/1000);
for(i=0;i<ms;i++)
{
//当计数器的值减少到0的时候,CRTL寄存器的位16会置1
//当置1时,读取该位会清0
while( !((SysTick->CTRL)&(1<<16)) );
}
//关闭SysTick定时器
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
}
main.c文件
#include "stm32f10x.h"
#include "bsp_SysTick.h"
#include "bsp_led.h"
int main(void)
{
/* LED端口初始化 */
LED_GPIO_Config();
/* 配置SysTick 为10us中断一次*/
SysTick_Init();
#if 0
for(;;)
{
LED1( ON );
Delay_us(100000); // 100000 * 10us = 1000ms
//Delay_ms(100);
LED1( OFF );
LED2( ON );
Delay_us(100000); // 100000 * 10us = 1000ms
//Delay_ms(100);
LED2( OFF );
LED3( ON );
Delay_us(100000); // 100000 * 10us = 1000ms
//Delay_ms(100);
LED3( OFF );
}
#else
for(;;)
{
LED1( ON );
SysTick_Delay_Ms( 1000 );
LED1( OFF );
LED2( ON );
SysTick_Delay_Ms( 1000 );
LED2( OFF );
LED3( ON );
SysTick_Delay_Ms( 1000 );
LED3( OFF );
}
#endif
}