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/

原文地址:https://www.cnblogs.com/darren-pty/p/13910820.html