5.STM32SysTick定时器

1.Systick知识

1.Systick是什么
是一个简单的定时器(系统滴答定时器),通常用于延时函数,可以节省CPU资源
24位的倒计速定时器,从RELOAD寄存器中自动装载定时器初值
还被绑定在NVIC中,会产生Systick异常(15)
Systick的中断优先级也可以设置

2.Systick寄存器

1.Systick寄存器
CTRL(控制和状态寄存器)
LOAD(自动重装载除值寄存器)
VAL(当前指寄存器)
CALIB(校准寄存器)
2.Systick寄存器详解
1.CTRL(控制和状态寄存器)
请添加图片描述
位0,使能位
位1,计数到0是否产生中断请求
位2,时钟源选择,外部时钟是HCLI(AHB总线时钟)的8分频,内部时钟是HCLK
位16,标志位,是否到0
配置函数
HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource) //选择外部或内部时钟
uint32_t SysTick_Config(uint32_t ticks) //配置经过多少ticks发生中断

__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
  {
    return (1UL);                                                   /* Reload value impossible 不能超过24位*/
  }

  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register load装入值*/
  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* 优先级set Priority for Systick Interrupt */
  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                         /* 设置内核时钟源,开启中断,使能SysTick,Enable SysTick IRQ and SysTick Timer */
  return (0UL);                                                     /* Function successful */
}

2.LOAD(自动重装载除值寄存器)
请添加图片描述
每次计数到0,会把load的值放到但前值寄存器
3.VAL(当前指寄存器)
请添加图片描述
读取倒计数器当前的值当前的值
4.CALIB(校准寄存器)

3.Systick延时函数

1.使用中断的方法实现
请添加图片描述
1000个systick周期发生中断,中断服务函数不断递减,一直减到0,时间就到了
2.使用查询的方法实现

static u32 fac_us=0;							//us延时倍乘数
void delay_init(u8 SYSCLK)
{
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//SysTick频率为HCLK(180MHZ)
	fac_us=SYSCLK;						//不论是否使用OS,fac_us都需要使用,1us需要180个SYSTICK周期
}			
void delay_us(u32 nus)
{		
	u32 ticks;
	u32 told,tnow,tcnt=0;
	u32 reload=SysTick->LOAD;				//LOAD的值	    	 
	ticks=nus*fac_us; 						//需要的节拍数 
	told=SysTick->VAL;        				//刚进入时的计数器值
	while(1)
	{
		tnow=SysTick->VAL;	
		if(tnow!=told)
		{	    
			if(tnow<told)tcnt+=told-tnow;	//这里注意一下SYSTICK是一个递减的计数器就可以了.
			else tcnt+=reload-tnow+told;	    
			told=tnow;
			if(tcnt>=ticks)break;			//时间超过/等于要延迟的时间,则退出.
		}  
	};
}
//延时nms
//nms:要延时的ms数
void delay_ms(u16 nms)
{
	u32 i;
	for(i=0;i<nms;i++) delay_us(1000);
}

delay_us(u32 nus)函数
就是先输入nus(us),1us需要180个SysTick周期,故需要180nus个SysTick周期
然后先记下LOAD,就是每次溢出到0恢复的值
在设立两个值,一个用于存当前val的值tnow,一个用于存上次val的值told(val是SysTick定时器的不断减1时候所处的位置)
如果当前的小于上次的,代表一直在减少,没有溢出,那么经过的SysTick周期周期数为told-tnow
当前的大于上次的,那么代表溢出了(因为到0,会重新装上load的值,是比当前的大的),那么经过的SysTick周期周期数为load-tnow+told
不断改变当前val的数值,再加上经过的SysTick周期的总和,如果超过180
nus,则代表延时结束

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值