SysTick: 24位,只能递减,存在于内核,嵌套在NVIC中,所有Cortex-M内核的单片机都具有这个定时器
系统滴答校准值固定为9000,当系统滴答时钟设定位9MHz(HCK/8的最大值),产生1ms时间的基准.
4个systick寄存器:
CTRL 控制和状态寄存器
LOAD:自动重装载初值寄存器
VAL:当前值寄存器
CALIB:校准值寄存器
Sys Tick定时时间计算:
t=reload*(1/CLk) CLK位系统时钟
CLK=72M时,t=(72)*(1/72M)=1us
CKL=72M时t=(72000)*(1/72M)=1ms
在core_cm3.h中
typedef struct
{
__IO uint32_t CTRL; //控制状态寄存器
__IO uint32_t LOAD; //重装载寄存器
__IO uint32_t VAL; //当前值寄存器
__I uint32_t CALIB; //校准寄存器
} SysTick_Type;
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);
}
固件库中systick相关函数:
SysTick_CLKSourceConfig()//systick时钟源选择.在misc.c文件中
SYSTick_Config(uint32_t ticks)//初始化Systick时钟为HCLK,并开启中断,在core_cm3.h或core_CM4.h中
中断服务函数:
Void SysTick_Handler(void)
用中断的方式实现delay 函数:
我们只需要设置好LOAD的值,VAL清零,CTRL配置好就能使用了,将systick用来定时也是可以的,但是一般将其用在实时系统中.
寄存器非中断写法:
/*看看就好,别太当真,因为这个东西一般用来做rtos,而且这样写其实是有问题的,这种做法对一个工程来说不能保证工程的实时性*/
#include"mydelay.h"
void SysTick_Delay_Ms(u32 ms)
{
u32 i;
SysTick->LOAD=72000-1;//重装载值
SysTick->VAL = 0; /*初始化val值,val将会取load的值71999数到0将会计数72000次.我们使用的
时72M时钟,频率是1/72000000,那么计数72000次则等于1/1000s=1ms*/
SysTick->CTRL =0x05; /*使能SysTick,不开启中断 0000 0000 0000 0000 0000 0000 0000
0101*/
for(i=0;iCTRL)&(1<<16)));/*当第一次进入时,SysTick还没有计算满,所以该位为0,
直到Systick计算满了,第16位为0,跳出while循环,并自动置0*/
}
SysTick->CTRL &=~SysTick_CTRL_CLKSOURCE_Msk;//清除一处标志位
}
#ifndef _MYDELAY_H_
#define _MYDELAY_H_
#include"stm32f10x.h"
void SysTick_Delay_Ms(u32 ms);
#endif
中断写法:
#include"mydelay.h"
u32 i;
void my_delay_init(void)
{
SysTick->LOAD=72000-1;//重装载值
SysTick->VAL = 0; //初始化val值,val将会取load的值71999数到0将会计数72000次.我们使用
的时72M时钟,频率是1/72000000,那么计数72000次则等于1/1000s=1ms,
SysTick->CTRL =0x07; //使能SysTick,开启中断 //0 0000 0000 0000 0111
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//设置中断优先级分组
NVIC_SetPriority(SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);//设置中断优先
级,1<<__NVIC_PRIO_BITS) - 1这句的意思时1左移4位为10000,然后减一就是1111,那么这里就是设置
了一位抢占(抢占优先级为1),三位响应(响应优先级为7).
}
void SysTick_Delay_Ms(u32 ms)
{
while(ms!=i)
;
i=0;
}
void SysTick_Handler(void)
{
//这里可以加中断触发条件,因为说实话一般不会用到systick
i++;
}
#ifndef _MYDELAY_H_
#define _MYDELAY_H_
#include"stm32f10x.h"
void my_delay_init(void);
void SysTick_Delay_Ms(u32 ms);
#endif