1. 程式人生 > >STM32的SysTick定時器與Delay延時函式

STM32的SysTick定時器與Delay延時函式

1.BB一下

原子哥的Delay延時函式,在沒有使用OS的情況下,沒有使用SysTick中斷,而筆者希望通過該中斷記錄系統時間

  • 不使用OS,使用SysTick中斷
  • 不使用OS,不使用SysTick中斷
  • 使用OS,使用SysTick中斷

2.BB完了,上程式碼

2.1.不使用OS,使用SysTick中斷

#define SYSTICK_INT_MS 500 /* 定義 SysTick 定時器 1/SYSTICK_INT_MS秒中斷一次 */

static u8  fac_us=0;
static u16 fac_ms=0;

static u32 _tickMs = 0;
void SysTick_Handler(void)
{   
    _tickMs+=2;/*1/SYSTICK_INT_MS=2ms */
} /* 獲取系統時間 */ u32 get_systemMs(void){ return _tickMs; } /* ************************************************** ** desc : 延時函式初始化 ** sysClk : 系統時鐘頻率 ** note : SysTick的時鐘頻率是系統時鐘頻率的1/8 ************************************************** */ void delay_init(u8 sysClk ){ u32 reload; SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);/* 選擇外部時鐘 */
fac_us=sysClk/8; /* fac_us個時鐘數1us */ reload=sysClk/8; reload*=1000000/SYSTICK_INT_MS; /* 根據delay_ostickspersec設定溢位時間 */ /* reload為24位暫存器,最大值:16777216,在168M下,約合0.7989s左右 */ fac_ms=1000/SYSTICK_INT_MS; /* 最小延時單位 */
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;/* 開啟SysTick中斷 */ SysTick->LOAD=reload; /* 每1/delay_ostickspersec秒中斷一次 */ SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; /* 開啟SYSTICK */ } /* *********************************************** ** desc : us 延時函式 ** nus : 0~204522252(最大值即2^32/fac_us) *********************************************** */ void delay_us(u32 nus){ u32 ticks; u32 told,tnow,tcnt=0; u32 reload=SysTick->LOAD; ticks=nus*fac_us; /* 需要的節拍數 */ told=SysTick->VAL; /* 當前 SysTick 計數值 */ while(1){ tnow=SysTick->VAL; if(tnow!=told){ if(tnow<told) tcnt+=told-tnow; else tcnt+=reload-tnow+told; told=tnow; if(tcnt>=ticks) /* 時間超過/等於要延遲的時間,則退出.*/ break; } }; } /* *********************************************** ** desc : ms 延時函式 ** nus : 0~204522(最大值即2^32/fac_us/1000) *********************************************** */ void delay_ms(u32 nms){ delay_us( nms*1000 ); #if 0 u32 time = get_systemMs(); while(1){ if( get_systemMs()-time>nms ) break; } #endif }

2.2.不使用OS,不使用SysTick中斷

static u8  fac_us=0;
static u16 fac_ms=0;

void delay_init(u8 sysClk){

    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); 
    fac_us=sysClk/8;                        
    fac_ms=(u16)fac_us*1000;
}
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_xms(u16 nms){                  
    u32 temp;          
    SysTick->LOAD=(u32)nms*fac_ms;          
    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(u32 nms){

    u8 repeat=nms/540;                      

    u16 remain=nms%540;
    while(repeat)
    {
        delay_xms(540);
        repeat--;
    }
    if(remain)delay_xms(remain);
}

2.3.使用OS,使用SysTick中斷

static u8  fac_us=0;
static u16 fac_ms=0;

static u32 _tickMs = 0;
void SysTick_Handler(void){

    if( OSRunning==TRUE){
        OSIntEnter();       
        OSTimeTick();                    
        OSIntExit();        
    }

    _tickMs+=2;//OS_TICKS_PER_SEC=500

}
u32 get_systemMs(void){
    return _tickMs;
}

void delay_init(u8 sysClk){

    u32 reload;
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); 
    fac_us=sysClk/8;                        

    reload=sysClk/8;                           
    reload*=1000000/OS_TICKS_PER_SEC;   

    fac_ms=1000/OS_TICKS_PER_SEC;              
    SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;   
    SysTick->LOAD=reload;                   
    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;      
}   
void delay_us(u32 nus)
{       
    u32 ticks;
    u32 told,tnow,tcnt=0;
    u32 reload=SysTick->LOAD;                    
    ticks=nus*fac_us;                       
    OSSchedLock();                  
    told=SysTick->VAL;                      
    while(1)
    {
        tnow=SysTick->VAL;  
        if(tnow!=told)
        {       
            if(tnow<told)tcnt+=told-tnow;   
            else tcnt+=reload-tnow+told;        
            told=tnow;
            if(tcnt>=ticks)break;           
        }  
    };
    OSSchedUnlock();                                                                
}  
void delay_ms(u16 nms)
{   
    if(OSRunning==TRUE) 
    {        
        if(nms>=fac_ms)                     
        { 
            OSTimeDly(nms/fac_ms);
        }
        nms%=fac_ms;                           
    }
    delay_us((u32)(nms*1000));              
}