1. 程式人生 > 實用技巧 >5-stm32 滴答定時器(delay中斷延時)

5-stm32 滴答定時器(delay中斷延時)

ARM Cortex-M3核心中有一個Systick定時器,它是一個24位(0~(2^24-1))的倒計數定時器,當計數到0時,它就會從Load暫存器中自動重灌定時初值,只要不把CTRL暫存器中的ENABLE清0,它就永不停。

systick定時器暫存器:

時鐘源可以是內部時鐘FCLK或外部時鐘STCLK

配置系統定時器步驟:

①選擇時鐘源②設定過載數(reload)③開啟中斷④啟動滴答定時器

在core_cm3.h中有關於系統定時器的配置:

static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return
(1); /* Reload value impossible 判斷是否大於 2^24*/ SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts 異常號2^4-1 =15
*/ SysTick->VAL = 0; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | //選擇內部時鐘FCLK SysTick_CTRL_TICKINT_Msk | //中斷使能 SysTick_CTRL_ENABLE_Msk; //定時器使能 /* Enable SysTick IRQ and SysTick Timer
*/ return (0); /* Function successful */ }

實驗一:

通過systick中斷方式進行定時

實驗程式碼:

(1)定時函式

//時基:1/72M
//SystemCoreClock /X裝值
//SystemCoreClock /1000000    --1us
//SystemCoreClock /1000       --1ms
//SystemCoreClock /100000     --10us

u32  TimingDelay=0;
void Systick_Config(void)
{
     //判斷是否超出範圍
   if(SysTick_Config(SystemCoreClock/1000000)) return; //1us
    
     SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;//失能定時器
}

//time us
void  Delay_us(__IO u32 time) //--微秒級延時
{
   TimingDelay =time;
    
    SysTick->CTRL |=SysTick_CTRL_ENABLE_Msk;//使能定時器
     while(TimingDelay !=0);
    
    SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;//失能定時器
    
}

//time ms
void Delay_ms(__IO u32 time) //--毫秒級延時
{
   TimingDelay =time*1000;
     
    SysTick->CTRL |=SysTick_CTRL_ENABLE_Msk;//使能定時器
     while(TimingDelay !=0);
    
    SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;//失能定時器
}



 //*************滴答定時器中斷****************//
//中斷服務函式
void SysTick_Handler(void)
{
    if(TimingDelay !=0)
  
     TimingDelay --;
}

(2)main函式

 1 int main(void)
 2 {
 3 
 4    LED_INIT();
 5      Systick_Config();
 6 
 7      GPIOA->BRR |=1<<8; //點亮led  //寫1 reset
 8      GPIOA->BSRR |=1<<8;//關閉led //寫1,set
 9     
10      GPIOD->BRR |=1<<2; //點亮led  //寫1 reset
11      GPIOD->BSRR |=1<<2;//關閉led //寫1,set
12      
13    GPIOA->ODR &=~(1<<8);    //點亮led
14    GPIOA->ODR |= (1<<8);   //關閉led
15     
16     while(1)
17     {
18         GPIOA->ODR ^= GPIO_Pin_8;        //LED_Toggle
19         GPIOD->ODR ^= GPIO_Pin_2;
20         Delay_ms(1000);
21     }
22 
23 }

實驗現象:

https://www.bilibili.com/video/BV1uA411j7W6/