stm32延时us寄存器_STM32单片机systick使用注意事项

前言

CM4内核的处理和CM3一样,内部都包含了一个SysTick定时器,SysTick 是一个24 位的倒计数定时器,当计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。这样可以用systick来实现延时定时功能,不用再占用系统定时器。systick也多用做系统的时钟节拍,如freeRTOS等OS,再启动调度器的时候,就会将systick配置成其系统时钟,给系统提供心跳。

systick中有4个寄存器

  • CTRL
  • LOAD
  • VAL
  • CALIB

dc90ca17acfea7ca3ea7983c09a98d8e.png

systick配置注意事项

使用CubeMX配置生成的代码中,会自动生成一个 SystemClock_Config() 的函数,用于配置单片机时钟,其中就会配置systick

void SystemClock_Config(){    ...........    LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);    LL_SetSystemCoreClock(32000000);#ifndef SYSTICK_IRQ    LL_Init1msTick(32000000); //使能systick但是不开启systick中断#else    SysTick_Config(SystemCoreClock / 1000);//使能systick同时开启systick中断#endif}
但是这里 需要注意的是,是不是需要开启 systick 中断!!!! 1、如果只是想用systick来作为延时用,程序不想被中断打断,就只需要使能systick而不用开启systick中断,调用 LL_Init1msTick 即可
void LL_Init1msTick(uint32_t HCLKFrequency)    ---> LL_InitTick(HCLKFrequency, 1000U);        ---> __STATIC_INLINE void LL_InitTick(uint32_t HCLKFrequency, uint32_t Ticks)            {                  /* Configure the SysTick to have interrupt in 1ms time base */                  SysTick->LOAD  = (uint32_t)((HCLKFrequency / Ticks) - 1UL);  /* set reload register */                  SysTick->VAL   = 0UL;  /* Load the SysTick Counter Value */                  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |                                   SysTick_CTRL_ENABLE_Msk; /* Enable the Systick Timer */            }

但是需要自己编写延时函数,不能使用HAL库提供的HAL_Delay()。原因如下:HAL_Delay的实现是依靠一个uwTickFreq变量,uwTickFreq是在HAL_IncTick中累加的,需要在 SysTick_Handler中断函数中周期调用,这样HAL_Delay才会有一个基准

__weak void HAL_IncTick(void){  uwTick += uwTickFreq;}__weak uint32_t HAL_GetTick(void){  return uwTick;}__weak void HAL_Delay(uint32_t Delay){  uint32_t tickstart = HAL_GetTick();  uint32_t wait = Delay;   /* Add a period to guaranty minimum wait */  if (wait < HAL_MAX_DELAY)  {    wait += (uint32_t)(uwTickFreq);  }   while((HAL_GetTick() - tickstart) < wait)  {  }}

自定义的us延时

void my_delay_us(uint32_t nus){      uint32_t temp;    uint32_t fac_us = SystemCoreClock/1000000;    //为系统时钟的1/1000000      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;                 //清空计数器   }
2、如果想用systick座系统的时钟节拍,需要开启systick中断,可以直接调用 SysTick_Config 来配置,也可以使用 HAL_Init 来配置,HAL_Init 配置最终也会调用 SysTick_Config 函数
 HAL_Init(void)    ---> HAL_InitTick(uint32_t TickPriority)        ---> 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 */            }

这样配置完成之后,还需要再systick的中断中调用 osSystickHandler 和 HAL_IncTick

void SysTick_Handler(void){  osSystickHandler();//为OS提供系统时钟节拍  HAL_IncTick();//为HAL库提供时钟基准}

本文转自:https://blog.csdn.net/m0_37845735/article/details/108439464

转载此文目的在于传递更多信息,版权归原作者所有,如涉及侵权,请联系小编删除。 030940ec21eff225ae802e93862268cd.png

MCU开发加油站

关注MCU开发最新资讯及相关技术应用,交流MCU创新设计心得、与MCU开发达人结网同行!

d1c6a5f9080988ce7c037986e8487ecd.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值