[应用相关]

如何使用STM32单片机systick来实现延时定时功能

[复制链接]
494|7
手机看帖
扫描二维码
随时随地手机跟帖
火星国务卿|  楼主 | 2021-4-23 13:56 | 显示全部楼层 |阅读模式
        1、前言
        CM4内核的处理和CM3一样,内部都包含了一个SysTick定时器,SysTick 是一个24 位的倒计数定时器,当计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。这样可以用systick来实现延时定时功能,不用再占用系统定时器。systick也多用做系统的时钟节拍,如freeRTOS等OS,再启动调度器的时候,就会将systick配置成其系统时钟,给系统提供心跳。systick中有4个寄存器CTRL、LOAD、VAL、CALIB
        pIYBAF_9XjWAZY1uAAQTsF9Rra4795.png
        2、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库提供时钟基准}

使用特权

评论回复
两只袜子| | 2021-4-23 14:22 | 显示全部楼层
排版有点乱啊

使用特权

评论回复
wiba| | 2021-5-11 10:30 | 显示全部楼层
延时精度能达到多少

使用特权

评论回复
zljiu| | 2021-5-11 10:30 | 显示全部楼层
需要对时钟非常的了解啊

使用特权

评论回复
qcliu| | 2021-5-11 10:31 | 显示全部楼层
两个内核的处理速度不同

使用特权

评论回复
tfqi| | 2021-5-11 10:33 | 显示全部楼层
这个排版有点乱啊

使用特权

评论回复
coshi| | 2021-5-11 10:33 | 显示全部楼层
勉强的看一下吧

使用特权

评论回复
呐咯密密| | 2021-5-11 10:50 | 显示全部楼层
图片看完就没法看了,使用代码框啊,直接粘贴进来可太苦了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

681

主题

1534

帖子

7

粉丝