Systick系统滴答定时器

一个24 位的倒计数定时器,计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。

四个寄存器:

CTRL            SysTick 控制和状态寄存器 

LOAD           SysTick 自动重装载除值寄存器 

VAL              SysTick 当前值寄存器 

CALIB            SysTick 校准值寄存器

CTRL中的时钟源选择:

void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)

参数可以填:SYSTICK_CLKSOURCE_HCLK 和 SYSTICK_CLKSOURCE_HCLK_DIV8  不分贫或者八分频

经过ticks个周期 发生一次中断,(开启中断 设置时钟源 使能SYSTICK 设置了装载值)

__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
  {
    return (1UL);                                                   /* Reload value impossible */
  }

  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
  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;                         /* Enable SysTick IRQ and SysTick Timer */
  return (0UL);                                                     /* Function successful */
}
//用来存放系统时钟频率
static u32 fac_us=0;                            //us延时倍乘数



//初始化延迟函数
//当使用ucos的时候,此函数会初始化ucos的时钟节拍
//SYSTICK的时钟固定为AHB时钟的1/8
//SYSCLK:系统时钟频率
void delay_init(u8 SYSCLK)
{
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//SysTick频率为HCLK
    fac_us=SYSCLK;                            //不论是否使用OS,fac_us都需要使用
}    


//延时nus
//nus为要延时的us数.    
//注意:nus的值不要大于1000us
void delay_us(u32 nus)
{        
    u32 ticks;
    u32 told,tnow,tcnt=0;            //tcnt用来存放当前周期数 最后拿来和ticks对比
    u32 reload=SysTick->LOAD;                //LOAD的值    重载值 达到这个数之后将会重置   	          
    ticks=nus*fac_us;                         //需要的节拍数 
    told=SysTick->VAL;                        //刚进入时的计数器值VAL 存进told里
    while(1)
    {
        tnow=SysTick->VAL;    
        if(tnow!=told)            //还没有被重载的情况
        {        
            if(tnow<told)tcnt+=told-tnow;    //这里注意一下SYSTICK是一个递减的计数器就可以了.
            else tcnt+=reload-tnow+told;        //told < tnow 重载后的情况
            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);
}

if(tnow!=told){    if(tnow<told)//还没有被重载的情况{tcnt+=told-tnow;//这里注意一下SYSTICK是一个递减的计数器就可以了.}else //told < tnow 重载后的情况{tcnt+=reload-tnow+told;    }told=tnow;if(tcnt>=ticks)break;//时间超过/等于要延迟的时间,则退出.}  

猜你喜欢

转载自www.cnblogs.com/qifeng1024/p/12052284.html