STM32学习笔记——systick

STM32HAL库之HAL_Delay()

  • HAL_Init()
    初始化hal库,其中有一个函数是初始化systick的,HAL_InitTick是用于初始化systick。systick 上电初始化(外部晶振还没开始工作,此时系统默认使用内部 HSI 提供时钟源)
main() -> HAL_Init() -> HAL_InitTick() -> HAL_SYSTICK_Config() -> 
SysTick_Config(SystemCoreClock / (1000U / uwTickFreq)

其中SysTick_Config()这个函数传递值是初始化如下 LOAD的值

typedef struct
{
  // 控制位
  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
  //reload 也就是初始值,val需要要等与reload才会产生中断。
  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
  // 目前值,达到load产生一次中断。
  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
} SysTick_Type;
  • SystemClock_Config()
    初始化系统时钟,初始化时钟树里面描述的所有信息。其中也包括了systick这个系统定时器。
AL_RCC_ClockConfig() -> HAL_InitTick() -> HAL_SYSTICK_Config() -> 
SysTick_Config(SystemCoreClock / (1000U / uwTickFreq)

下面我们说一下 HAL_Delay()是如何实现的。
stm3214xx_hal.c

__weak void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick(); //最初为1
  uint32_t wait = Delay; //延时的时间

  /* Add a period to guaranty minimum wait */
  if (wait < HAL_MAX_DELAY) //为了防止Delay延时时间为0,所以加一个1
  {
    wait += (uint32_t)uwTickFreq;
  }

  while ((HAL_GetTick() - tickstart) < wait))
  {
  }
}

HAL_GetTick()每一次中断加1,中断是由 val加到 reload产生一次中断,reload的值是(SystemCoreClock / (1000U / uwTickFreq)根据这个表达式来的,如果uwTickFreq的值越小,那么reload的值越大,当uwTickFreq等于1的时候,那么reload就是72MHZ,也就是延时最小是1s的了。上述的是uwTickFreq等于1000,那么reload就是72MHZ/1000,因为每秒产生72000 000个脉冲,如果除以1000,那么reload等于72000,因为72MHZ是1秒,那么72000就是1ms。所以while ((HAL_GetTick() - tickstart) < wait)),这个代表因为没产生一个中断HAL_GetTick()加1,也就是1ms加1,那么等到1000ms的时候HAL_GetTick()也等于1000,这个时候延时就停止。

stm3214xx_it.c
中断服务程序,每当val = 72000的时候,就产生一个中断,执行 SysTick_Handle()

void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

HAL_IncTick()
HAL_GetTick(void)

__weak void HAL_IncTick(void)
{
  uwTick += (uint32_t)uwTickFreq; //每次中断uwTick +1
}

__weak uint32_t HAL_GetTick(void)
{
  return uwTick; //获取当前uwTick的值,当Delay(100)时候,就要让uwTick==100,即产生100次中断。
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值