STM32 系统定时器(SysTick)
Posted 一只小阿大:)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32 系统定时器(SysTick)相关的知识,希望对你有一定的参考价值。
SysTick定义
SysTick : 24位系统定时器,只能递减,存在于内核嵌套在NVIC中。所有的Cortex-M中都有这个系统定时器。
重装载值reload 递减,当递减到0会触发中断并且会有 置位countflag标志,VAL表示当前值。
然后reload继续从预设值开始递减,周而复始。
还有一个校准数值寄存器,不常用,想知道的可以看下其他文章会讲。
SysTick定时时间的计算
- T : 一个计数循环的时间,跟reload和 CLK有关
- CLK : 72M 或者9 M, 由CTRL寄存器配置
- reload : 24位,用户自己配置
T = reload * (1/ CLK)
CLK= 72M, 1us = (72 )* (1/ 72 000 000)
CLK= 72M, 1ms = (72 000 )* (1/ 72 000 000)
时间单位换算: 1s = 1000ms = 1000 000 us = 1000 000 000 ns
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)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); //判断reload的值是否大于最大值 2^24
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; //配置reload寄存器的初值
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); //配置中断优先级 1<<4 -1 =16-1=15
SysTick->VAL = 0; //配置count的值
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | //配置system时钟为 72M
SysTick_CTRL_TICKINT_Msk | //使能中断
SysTick_CTRL_ENABLE_Msk; //使能systick
return (0);
}
SysTick中断优先级
数字越小中断优先级越高
1.system tick 属于内核的外设,它的中断优先级 与片上外设的中断优先级相比谁高?
依据是什么?
答:systick 中断优先级配置的是scb->shprx寄存器
外设中断优先级配置的是nvic-> iprx寄存器
有优先级分组
3.STM32的外设(内核还是片上)都是使用4个二进制来表示中断优先级
4.中断优先级的分组对内核和外设同样适用,只需要将中断优先级的四个位按外设优先级来分组即可,人为的进行分出抢占优先级和子优先级。例举:
1<<4 -1=16 -1= 15 (1 1 1 1 )
前面两位表示抢占优先级 后面两位表示子优先级
3 3 (抢占优先级3 ,子优先级3)
1<<4 = 1 0000 = 16
编写ms,us延时函数
systick和delay区别
delay一直占用cpu,而systick一般都采用中断方式,(不会有人在程序里一直查询标志位的),不占用cpu。除非任务很简单。否则实际项目不会使用循环的延时。不过因为stm32上面有更强大的外设定时器的。定时的范围也比systick要大。还可以级联,所以一般不用systick,只把systick用于操作系统的时钟节拍。
案例
SysTick.h
#include "stm32f10x.h"
void ms_delay(uint32_t ms);
void us_delay(uint32_t us);
SysTick.c
#include "stm32f10x.h"
#include "SysTick.h"
/*
ϵͳ¶¨Ê±Æ÷Ìص㣺
Ö»Äܵݼõ£¬Èç¹û¶¨ÒåµÄÊÇ72000
ÄǾʹÓ72000¿ªÊ¼µÝ¼õµ½0£¬ÎªÒ»¸öÖÜÆÚ
ËùÒÔÖ»ÐèÒªÅжÏÊÇ·ñ¼õµ½1
ÈçºÎÅжϣ¿
¿´COUNTFLAG¼Ä´æÆ÷£¬Ò²¾ÍÊÇSysTick->CTRL
*/
void ms_delay(uint32_t ms)
{
uint32_t i;
SysTick_Config(72000);//Ñ»·Ò»´Î1ms
for(i=0;i<ms;i++)//Ҫѻ·¶àÉÙms
{
while( !((SysTick->CTRL)&(1<<16)) );//ÅжÏSysTickÊÇ·ñµ½0£¬µ½0¸ÃλΪ1
//!(1&1)Ìø³öÑ»·
//Ϊʲô×óÒÆ16λÄØ£¬ÒòΪCTRLÊÇ16λµÄ?
//¿´¿ØÖƼ°×´Ì¬¼Ä´æÆ÷µÄͼдÁË¡£
}
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
}
void us_delay(uint32_t us)
{
uint32_t i;
SysTick_Config(72);//Ñ»·Ò»´Î1us
for(i=0;i<us;i++)//Ҫѻ·¶àÉÙus
{
while( !((SysTick->CTRL)&(1<<16)) );
}
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
}
led.h
#include "stm32f10x.h"
void Led_init(void);
led.c
#include "stm32f10x.h"
#include "led.h"
void Led_init(void)
{
GPIO_InitTypeDef Led_init;
//1.ʹÄÜAPB2µÄʱÖÓGPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
//2.½á¹¹ÌåÅäÖÃ
Led_init.GPIO_Mode = GPIO_Mode_Out_PP;
Led_init.GPIO_Pin = GPIO_Pin_13;
Led_init.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOC, &Led_init);
}
main.c
#include "stm32f10x.h"
#include "led.h"
#include "relay.h"
#include "shake.h"
#include "exti.h"
#include "usart.h"
#include "stdio.h"
#include "tim.h"
#include "motor.h"
#include "SysTick.h"
void delay(uint16_t time)
{
uint16_t i =0;
while(time--){
i=12000;
while(i--);
}
}
int main()
{
Led_init();
GPIO_SetBits(GPIOA, GPIO_Pin_3);
//ʹÓÃϵͳ¶¨Ê±Æ÷SysTick´úÌædelay;
while(1)
{
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
ms_delay(1000);
GPIO_SetBits(GPIOC, GPIO_Pin_13);
ms_delay(1000);
}
}
以上是关于STM32 系统定时器(SysTick)的主要内容,如果未能解决你的问题,请参考以下文章
STM32 的系统滴答定时器( Systick) 彻底研究解读