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;//時間超過/等於要延遲的時間,則退出.}  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM