SysTick---系统(嘀嗒)定时器,内核外设,是一个24位的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK。
当重装载数值寄存器的值递减到 0 的时候,系统定时器就产生一次中断,以此循环往复。
系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。
校准寄存器一般不用。?
编程步骤:
?
systick.c
#include "systick.h"
#if 0
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的值为0
SysTick->VAL = 0;
// 配置 systick 的时钟为 72M
// 使能中断
// 使能systick
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return (0);
}
#endif
void SysTick_Delay_us(uint32_t us)
{
uint32_t i;
SysTick_Config(72);
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(uint32_t ms)
{
uint32_t i;
SysTick_Config(72000);
for(i=0; i<ms; i++)
{
// 当计数器的值减小到 0 的时候,CRTL 寄存器的位 16 会置 1
// 当置 1 时,读取该位会清 0
while( !((SysTick->CTRL) & (1<<16)) );
}
// 关闭 SysTick 定时器
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}
SysTick 中断时间的计算:SysTick_Config(SystemCoreClock / 100000)
systick.h
#ifndef _SYSTICK_H
#define _SYSTICK_H
#include "stm32f10x.h"
#include "core_cm3.h"
void SysTick_Delay_us(uint32_t us);
void SysTick_Delay_ms(uint32_t ms);
#endif
led.c
#include "led.h"
void led_gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(LED0_GPIO_CLK,ENABLE);//注意需要用到的总线
GPIO_InitStruct.GPIO_Pin = LED0_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED0_GPIO_PORT,&GPIO_InitStruct);
GPIO_ResetBits(LED0_GPIO_PORT,LED0_GPIO_PIN);
}
led.h
#ifndef _LED_H
#define _LED_H
#include "stm32f10x.h"
#define LED0_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED0_GPIO_PORT GPIOB
#define LED0_GPIO_PIN GPIO_Pin_5
/******************************************************************************************/
/* LED端口定义 */
#define LED0(x) do{ x ? \
GPIO_SetBits(LED0_GPIO_PORT, LED0_GPIO_PIN) : \
GPIO_ResetBits(LED0_GPIO_PORT, LED0_GPIO_PIN); \
}while(0) /* LED0翻转 */
#define digitalToggle(p,i) {p->ODR ^=i;} //输出反转状态
#define LED0_Toggle digitalToggle(LED0_GPIO_PORT,LED0_GPIO_PIN)
void led_gpio_init(void);
#endif
main.c
#include "stm32f10x.h"
#include "led.h"
#include "systick.h"
int main()
{
// 来到这里的时候,系统的时钟已经被配置成72M。
led_gpio_init();
while(1)
{
LED0(1);
SysTick_Delay_ms(500);
LED0(0);
SysTick_Delay_ms(500);
}
}