STM32的SysTick定时器与Delay延时函数

版权声明:本文为小生原创,转载请注明出处,好吗好的,善哉善哉!!! https://blog.csdn.net/u010650845/article/details/82188315

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));              
}

猜你喜欢

转载自blog.csdn.net/u010650845/article/details/82188315