当前位置: 代码迷 >> 综合 >> SysTick
  详细解决方案

SysTick

热度:76   发布时间:2023-12-23 15:09:36.0

概述

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;i<ms;i++){while(!((SysTick->CTRL)&(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  0111NVIC_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)	
{//这里可以加中断触发条件,因为说实话一般不会用到systicki++;	}
#ifndef _MYDELAY_H_
#define _MYDELAY_H_#include"stm32f10x.h"void  my_delay_init(void);
void SysTick_Delay_Ms(u32 ms);#endif