0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

电子设计 来源:CSDN博主 作者:hurryddd 2021-02-14 06:25 次阅读

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库提供时钟基准
}

编辑:hfy

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6002

    文章

    43990

    浏览量

    620954
  • 寄存器
    +关注

    关注

    30

    文章

    5042

    浏览量

    117768
  • 定时器
    +关注

    关注

    23

    文章

    3148

    浏览量

    112061
  • STM32单片机
    +关注

    关注

    58

    文章

    545

    浏览量

    57944
  • Systick
    +关注

    关注

    0

    文章

    62

    浏览量

    12954
收藏 人收藏

    评论

    相关推荐

    Systick到底是用作延时好还是用作定时好?都有什么优缺点?

    功能,作基础定时用,而不建议用作延时功能,方便后面程序移植. 最好有个定论,方便后面程序的移植,不能各自玩各自的,一个公司里面写程序的风格和标准需要统一。 想问下各位,
    发表于 04-08 07:37

    AvR单片机1us延时函数数怎么写

    在编写AvR单片机的1us延时函数之前,我们首先需要了解几个关键概念。 单片机延时函数是通过控制器在特定的时间间隔内执行一系列的指令来实现
    的头像 发表于 12-26 14:02 395次阅读

    stm32delay函数怎么写

    STM32延时函数可以使用SysTick定时器来实现SysTick
    的头像 发表于 12-21 17:53 747次阅读

    CKS32F4xx系列MCU SysTick定时器的原理及使用方法

    本课将为大家讲解CKS32F4xx系列产品的SysTick定时器原理及使用方法。SysTick定时器也叫SysTick滴答
    的头像 发表于 12-18 09:21 535次阅读
    CKS32F4xx系列MCU <b class='flag-5'>SysTick</b><b class='flag-5'>定时</b>器的原理及使用方法

    systick_handler无法进入怎么解决

    种情况下,我们需要采取一些措施来解决这个问题。 在解决这个问题之前,我们需要了解一下SysTick模块和其相关概念。 首先,SysTick是一个与外设模块时钟频率相对应的计数器,它通过加载一个初始值和递减计数来实现
    的头像 发表于 12-01 15:36 1401次阅读

    STM32如何使用定时实现微秒(us)级延时

    STM32如何使用定时实现微秒(us)级延时? 在STM32微控制器中,可以使用定时
    的头像 发表于 11-06 11:05 3075次阅读

    51单片机如何实现毫秒级精确延时

    51单片机如何实现毫秒级精确延时
    发表于 10-27 06:25

    STM32基于HAL库实现微秒延时

    HAL只提供了ms级的延时,但有些特殊场景,比如与通信速率较慢的设备通信时,会需要用到us级延时STM32标准库一般是使用系统嘀嗒定时器来进行微妙级别的
    的头像 发表于 10-25 15:31 1730次阅读
    <b class='flag-5'>STM32</b>基于HAL库<b class='flag-5'>实现</b>微秒<b class='flag-5'>延时</b>

    SysTick定时器的应用(2)#单片机

    单片机STM32电子技术
    未来加油dz
    发布于 :2023年08月11日 16:46:04

    SysTick定时器的应用(1)#单片机

    单片机STM32电子技术
    未来加油dz
    发布于 :2023年08月11日 16:45:10

    STM32定时器#单片机

    单片机STM32
    未来加油dz
    发布于 :2023年08月11日 16:30:39

    STM32单片机延时原理和延时函数方法

    当涉及到单片机编程时,延时是一项常见但关键的任务。在许多应用中,我们需要控制程序暂停一段时间,以实现精确的时间控制或协调不同设备之间的操作。本文将以STM32为例,介绍关于
    发表于 08-09 09:13 1w次阅读

    STM32有哪几种定时STM32高级定时器有哪些功能

    SysTick定时器的功能比较单一,主要是供给系统使用的,系统默认设置为1ms触发一次中断。而用户想要使用自己的定时器,STM32提供的用户
    的头像 发表于 07-27 16:25 3872次阅读
    <b class='flag-5'>STM32</b>有哪几种<b class='flag-5'>定时</b>器 <b class='flag-5'>STM32</b>高级<b class='flag-5'>定时</b>器有哪些<b class='flag-5'>功能</b>

    STM32 SysTick配置函数

    之前使用SysTick滴答定时器都是通过查找内核编程手册配置寄存器让SysTick滴答定时器工作的。
    的头像 发表于 07-22 10:21 1144次阅读
    <b class='flag-5'>STM32</b> <b class='flag-5'>SysTick</b>配置函数

    51单片机定时器讲解

    前面我们讲解了通用IO输入输出,延时函数和外部中断,今天我们讲解单片机另一个重要的功能定时器。顾名思义,定时器就是用来
    发表于 07-14 16:22 1603次阅读
    51<b class='flag-5'>单片机</b><b class='flag-5'>定时</b>器讲解