一文详解STM32的嘀嗒时钟(SysTick)

发布时间:2024-03-12  

简要说明

1概述

嘀嗒时钟(SysTick)是一个简单的系统时钟节拍计数器,它属于Cortex-M4内核嵌套向量中断控制器(NVIC)里的一个功能单元。他是一个24位的倒计时定时器(在NVIC中),当systick计数值到0的时候,SysTick重装载寄存器就会自动重新装载初值。只要SysTick控制和状态寄存器(CTRL)中的使能位没有ENABLE清除掉,那么就会永远的执行下去。


SysTick定时器被捆绑在NVIC中,可产生SysTick异常(异常号:15),属于Cortex-M4内核里的一个功能单元。

SysTick常作为系统节拍定时器用于操作系统(如mCOS-Ⅱ、FreeRTOS等)的系统节拍定时,从而推动任务和时间的管理。

SysTick的最大使命,就是作为系统的时基定期地产生异常请求。

在不采用操作系统的情况下,完全可以作为通用定时器、计数器使用的。

下图是SysTick控制控制和状态寄存器描述,(地址:0xe000e010)

SysTick 控制及状态寄存器:

截图20230109091048.png

SysTick 寄存器:

截图20230109091048.png

SysTick 重装载数值寄存器:地址 0XE000E014

截图20230109091048.png

特别注意:计数最大值是)0XFFFFFF,在设置重装在值得时候不能大于这个。

SYSTick当前数值寄存器(VAL),地址:0XE000E018

截图20230109091048.png

毕业寄语:

毕业,是一首离别的歌,更是青年成长的里程碑。四年的时光一千多日夜就这样瞬息即过,但它却是你们的瑰丽人生中最浓丽的一抹色彩!如一条条的小溪汇成了一条多彩的河流。你们成了校园里最靓丽的一道风景。

SYSTick校准数值寄存器(VAL),地址:0XE000E018

截图20230109091048.png

配置SysTick作为时钟基准,主要通过对SysTick控制与状态寄存器、SysTick重装载数值寄存器和SysTick当前数值寄存器三个寄存器进行初始化。需要配置的内容如下:

① SysTick时钟源选择。

② 异常请求设置。

③ SysTick时钟使能。

④ 初始化SysTick重装数值。

⑤ 清零SysTick当前数值寄存器。


库函数

SysTick的库函数


1、SysTick寄存器结构体类型


/** rief Structure type to access the System Timer (SysTick).


*/


typedef struct

{

  __IO uint32_t CTRL;                    /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */

  __IO uint32_t LOAD;                    /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register       */

  __IO uint32_t VAL;                     /*!< Offset: 0x008 (R/W)  SysTick Current Value Register      */

  __I  uint32_t CALIB;                   /*!< Offset: 0x00C (R/ )  SysTick Calibration Register        */

} SysTick_Type;

2、SysTick时钟源初始化函数


/**


@brief Configures the SysTick clock source.

@param SysTick_CLKSource: specifies the SysTick clock source.

This parameter can be one of the following values:

@arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.

@arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.

@retval None

*/


void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)

{

  /* Check the parameters */

  assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));

  if (SysTick_CLKSource == SysTick_CLKSource_HCLK)

  {

    SysTick->CTRL |= SysTick_CLKSource_HCLK;

  }

  else

  {

    SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;

  }

}

SysTick_CLKSourceConfig函数被定义在misc.c文件中,配置的是SysTick控制与状态寄存器中的位2。


设置为0:选择使用HCLK/8作为时钟源。


设置为1:选择使用HCLK作为时钟源。


在实际使用的过程中参数宏在misc.h文件里面。


#define SysTick_CLKSource_HCLK_Div8((uint32_t)0xFFFFFFFB)

#define SysTick_CLKSource_HCLK  ((uint32_t)0x00000004)

3、SysTick配置函数


__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)

{

  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */





  SysTick->LOAD  = ticks - 1;                                  /* set reload register */

  NVIC_SetPriority (SysTick_IRQn, (1<<__nvic_prio_bits set priority for systick interrupt>  SysTick->VAL   = 0;                                          /* 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 (0);                                                  /* Function successful */

}

SysTick_Config函数被定义在core_cm3.h文件中,它的功能是初始化并开启SysTick计数器及其中断,输入参数ticks是两次中断间的ticks数值。通过次函数可以初始化系统嘀嗒定时器及其中断并开启系统嘀嗒定时器在自由运行模式下以产生周期中断。


SysTick异常服务函数


void SysTick_Handler(void)


SysTick_Handler的服务函数已在启动文件中定义过,并定义了[WEAK]属性,函数内执行的是空循环。


这就要求用户在使用SysTick异常服务时,需要在启动文件之外的其他文件重新定义服务程序,并且其函数名要和启动文件中的函数名保持一致,只有这样才能在编译阶段,将重定义的服务程序函数入口地址替换到SysTick在异常/中断向量表的位置。


应用小栗子

01应用实例


使用SysTick产生1s的定时,控制LED灯以2s为周期进行闪烁。


假设HCLK=180MHz。


在system_stm32f4xx.c文件中定义了全局变量uint32_t SystemCoreClock=180000000,并在头文件system_stm32f4xx.c->stm32f4xx.h中声明。


1-配置SysTick


按照1ms进行分片,配置程序如下:


SysTick_Config(SystemCoreClock/1000);

这样,SysTick会每1ms产生一次异常请求。全局变量定义:


volatile   uint32_tTimingDelay;

volatile防止变量TimingDelay在使用过程中被优化


2-写延时函数


编写以1ms为计时基准的函数:


void delay_ms(uint32_t nTime)

TimingDelay=nTime;

while(TimingDelay!=0);

}

其中,nTime是需要计时的ms数。


3-写中断服务函数


每1ms SysTick都会产生一次异常请求,执行其异常服务程序SysTick_Handler。对SysTick异常服务程序进行编写,每1ms对变量TimingDelay减1次。


void SysTick_Handler(void)

{

  if (TimingDelay!=0)

TimingDelay--;

}

}

4-应用


int main(void)

{

/*配置SysTick为每1ms异常一次*/

if (SysTick_Config(SystemCoreClock/1000))

/*SystemCoreClock/1000超出计数最大值时报错,程序陷入空循环*/ 

while (1);

}

/*初始化LED灯的GPIO*/

LED_Config ();

while (1)

{

/*反转LED灯状态*/

LED_TOGGLE;

/*延时1s*/

delay_ms (1000);

}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>