首页 > 编程知识 正文

stm32cubemx systick,stm32 systick寄存器

时间:2023-05-04 09:02:09 阅读:184743 作者:3592

一、STM32的SysTick简介

 

  SysTick是一个24位的系统节拍定时器system tick timer,SysTick,具有自动重载和溢出中断功能,所有基于Cortex_M3处理器的微控制器都可以由这个定时器获得一定的时间间隔。

systick的作用:

  在单任务引用程序中,因为其架构就决定了它执行任务的串行性,这就引出一个问题:当某个任务出现问题时,就会牵连到后续的任务,进而导致整个系统崩溃。要解决这个问题,可以使用实时操作系统(RTOS).

  因为RTOS以并行的架构处理任务,单一任务的崩溃并不会牵连到整个系统。这样用户出于可靠性的考虑可能就会基于RTOS来设计自己的应用程序。这样SYSTICK存在的意义就是提供必要的时钟节拍,为RTOS的任务调度提供一个有节奏的“心跳”。

  微控制器的定时器资源一般比较丰富,比如STM32存在8个定时器,为啥还要再提供一个SYSTICK?原因就是所有基于ARM Cortex_M3内核的控制器都带有SysTick定时器,这样就方便了程序在不同的器件之间的移植。而使用RTOS的第一项工作往往就是将其移植到开发人员的硬件平台上,由于SYSTICK的存在无疑降低了移植的难度。

    SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等。要注意的是,当处理器在调试期间被喊停(halt)时,则SysTick定时器亦将暂停运作。

systick的时钟选择:

二、SYSTICK的寄存器

三、SYSTICK的配置和函数解析

SysTick定时器的使用主要有HAL_SYSTICK_Config()函数和HAL_SYSTICK_CLKSourceConfig()函数。如下,

/**Configure the Systick interrupt time */ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);// 设置定时时间 /**Configure the Systick */ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//选择SYSTICK时钟源, /* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);//设定优先级  

Systick定时时间的设定:

重装载值=systick 时钟频率(Hz)X想要的定时时间(S)

如:时钟频率为:AHB的8分频;AHB=72MHz那么systick的时钟频率为72/8MHz=9MHz;要定时1秒,则

重装载值=9000000X1=9000000;

定时10毫秒

重状态值=9000000X0.01=90000

//两个时钟源的定义 #define SYSTICK_CLKSOURCE_HCLK_DIV8    (0x00000000U)#define SYSTICK_CLKSOURCE_HCLK         (0x00000004U) uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb){ return SysTick_Config(TicksNumb);} brief System Tick Configuration details Initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts. param [in] ticks Number of ticks between two interrupts. return 0 Function succeeded.//返回0,配置成功 return 1 Function failed.//返回1,失败 note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b> must contain a vendor-specific implementation of this function. */__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks){ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)//超过最大定时值,返回1,SysTick_LOAD_RELOAD_Msk值为2的24方-1;即0xFFFFFF { 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; //SysTick Current Value Register,设为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 (0UL); /* Function successful */}

SYSTICK内部寄存器的结构体定义,和上面图中的寄存器一一对应。

typedef struct{ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */} SysTick_Type;

SysTick定时器的时钟源选择函数如下:

void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource){ /* Check the parameters */ assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource)); if (CLKSource == SYSTICK_CLKSOURCE_HCLK) { SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;//见上面的宏定义,(0x00000004U),即把CLKSOURCE控制寄存器位置1; } else { SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;//把CLKSOURCE控制寄存器位置0; }}

systick定时器的处理函数为空,并未执行任何动作,如下:

void SysTick_Handler(void){ /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); HAL_SYSTICK_IRQHandler(); /* USER CODE BEGIN SysTick_IRQn 1 */ /* USER CODE END SysTick_IRQn 1 */} void HAL_SYSTICK_IRQHandler(void){ HAL_SYSTICK_Callback();}

 

__weak void HAL_SYSTICK_Callback(void){ /* NOTE : This function Should not be modified, when the callback is needed, the HAL_SYSTICK_Callback could be implemented in the user file */}

注意:当主芯片需使用SLEEP模式时,SYSTICK的异常请求会唤醒SLEEP模式,进入SLEEP模式前需要把TICKINT控制器置为0。

HAL_SuspendTick();//把TICKINT控制寄存器置0;HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);HAL_ResumeTick();//把TICKINT控制寄存器置1; __weak void HAL_SuspendTick(void){ /* Disable SysTick Interrupt */ CLEAR_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk);//置0} __weak void HAL_ResumeTick(void){ /* Enable SysTick Interrupt */ SET_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk);//置1}






 





 

 

 

 

 

 

 

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。