• 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;//时间超过/等于要延迟的时间,则退出.}  

  • 相关阅读:
    排序算法之冒泡排序
    排序算法之快速排序
    排序算法之插入排序
    Java集合之LinkedList源码分析
    排序算法之选择排序
    Java集合之Vector源码分析
    Python 装饰器
    一致性哈希
    剑指Offer-数组中重复的数字
    剑指Offer-把字符串转换成整数
  • 原文地址:https://www.cnblogs.com/qifeng1024/p/12052284.html
Copyright © 2020-2023  润新知