Systick滴答定时器寄存器、delay()延时函数、SysTick_Config函数

SysTick定时器
SysTick定时器,是一个简单的定时器,对于CM3、CM4内核的芯片都有SysTick定时器。SysTick 是一个 24 位的倒计数定时器,当计数到 0 时,将从RELOAD 寄存器中自动重装载定时初值,开始新一轮计数。只要不把它在 SysTick 控制及状态寄存器中的使能位清除(不把Systick定时器关掉),就永不停息。SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。例如,为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。

作用:

Systick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。比如:UCOS中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick做UCOS的心跳时钟。

Systick寄存器:

  • CLRL寄存器:Systick控制和状态寄存器
  • LOAD寄存器:Systick自动重装载寄存器
  • VAL寄存器:Systick当前值寄存器
  • CALIB寄存器:Systick校准值寄存器

Systick控制和状态寄存器-CTRL
在这里插入图片描述对于STM32,外部时钟源是HCLK(AHB总线时钟的1/8)内核时钟是HCLK时钟。
配置函数:Systick_CLKSourceConfig();

Systick重装载数值寄存器-LOAD(24位)
在这里插入图片描述
Systick当前值定时器-VAL
在这里插入图片描述
Systick校准寄存器-CAL
在这里插入图片描述
固件库中的Systick相关函数:
SysTick_CLCSourConfig()//Systick时钟源选择,在misc.c文件中。
SysTick_config(uint32_t ticks)//初始化systick时钟为HCLK,并开启中断,在core_cm3/core_cm4文件中。

Systick中断服务函数:
void SysTick_Handler(void);

用中断的方式实现delay延时:(比较耗费资源)

static __IO uint32_t TimingDelay;
void Delay(__IO uint32_t nTime)
{ 
   TimingDelay = nTime;
   while(TimingDelay != 0);
}
void SysTick_Handler(void)
{
    if (TimingDelay != 0x00) 
     { 
       TimingDelay--;
     }
}
 int main(void)
 {if (SysTick_Config(SystemCoreClock / 1000)) //systick时钟为HCLK(系统时钟),中断时间间隔1ms,SysTick_Config()这个函数是设置两次中断之间的时间。
     {
     while (1);
     }
    while(1)
     { Delay(200);//200ms}
}

SysTick_Config函数:

SysTick_Config的参数,其实就是一个时钟次数,叫systick重装定时器的值。意思就是我要多少个1/fosc 时间后中断一下。根据学过的物理中的时间与频率的公式:fosc=1/T T=1/fosc ,fosc为Systick的频率。如果STSystick时钟频率为:72MHz,每次的时间为:T=1/72MHz。1秒钟为:1/(每次的时间)=1/(1/72MHz)=72 000 000次。1MHz是:1000 000。反过来讲。SysTick_Config(72000)代表:72000*(1/72MHz)=1/1000=1(ms)。即定时为1ms。如果需要1S则可以通一设置一个全局变量,然后定初值得为1000,这样每个systick中断一次,这个全局变量减1,减到0,即systick中断1000次,时间为:1ms1000=1S。从而实现1S的定时。 因为SysTick定时器是:24位的,最大定时时间为:2的24次方(1/72MHz)的时间,这里Systick频率为:72MHz的情况下。

delay_init()函数:

static u8  fac_us=0;//us延时倍乘数			   
static u16 fac_ms=0;//ms延时倍乘数,在ucos下,代表每个节拍的ms数
void delay_init()
{
#if SYSTEM_SUPPORT_OS  							//如果需要支持OS.
	u32 reload;
#endif
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//选择外部时钟  HCLK/8
	fac_us=SystemCoreClock/8000000;//为系统时钟的1/8  相当于72000000/8000000等于九
									//一次是1/systick的时钟频率就是1/9 us,fac_us相当于1us,这里的将9赋值给他是给寄存器LOAD计数用的,从9到1就是1us
#if SYSTEM_SUPPORT_OS  //如果需要支持OS.
	reload=SystemCoreClock/8000000;//每秒钟的计数次数 单位为M  
	reload*=1000000/delay_ostickspersec;//根据delay_ostickspersec设定溢出时间

	//reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右	
	fac_ms=1000/delay_ostickspersec;//代表OS可以延时的最少单位	   

	SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;//开启SYSTICK中断
	SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次	
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;	//开启SYSTICK    

#else
	fac_ms=(u16)fac_us*1000;//非OS下,代表每个ms需要的systick时钟数   
#endif
}								    

void delay_us()函数:

void delay_us(u32 nus)
{		
	u32 temp;	    	 
	SysTick->LOAD=nus*fac_us; 					//时间加载	  		 
	SysTick->VAL=0x00;        					//清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;	//开始倒数	  
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));		//等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;	//关闭计数器
	SysTick->VAL =0X00;      					 //清空计数器	 
}

void delay_ms()函数:

void delay_ms(u16 nms)
{	 		  	  
	u32 temp;		   
	SysTick->LOAD=(u32)nms*fac_ms;				//时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;							//清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;	//开始倒数  
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));		//等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;	//关闭计数器
	SysTick->VAL =0X00;       					//清空计数器	  	    
} 
  • T=1/1KHZ=1ms=1微秒=1/1000秒
  • T=1/1MHZ=1us=1微秒=1/1000000秒
  • 10MHz=1/10us=0.1us
  • 20MHz=1/20us=0.05us
  • 50MHz=1/50us=0.02us
  • 1GHz=1ns=1纳秒=1/1000000000秒
  • 1MHZ=1000KHZ=1000000HZ
  • 1GHZ=1000MHZ
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值