STM32_SysTick_系统定时器

文章目录

  • 一、SysTick
  • 二、SysTick功能
    • [   1、基本框图](#   1、基本框图)
    • [   2、SysTick寄存器](#   2、SysTick寄存器)
    • [   3、SysTick定时时间计算](#   3、SysTick定时时间计算)
  • 三、SysTick定时实验
    • [   1、编程要点](#   1、编程要点)
    • [   2、文件配置](#   2、文件配置)
    • [   3、代码](#   3、代码)
    • [   4、一种简洁的代码](#   4、一种简洁的代码)

一、SysTick

SysTick:系统定时器,24位,只能递减,存在于内核,嵌套在NVIC中,所有的Cortex-M内核的单片机都具有这个定时器。

SysTick---系统定时器是属于CM3内核中的一个外设,内嵌在NVIC中。

系统定时器是一个24bit的向下递减的计数器, 计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK等于  72M。

当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。

二、SysTick功能

1、基本框图

counter在时钟的驱动下,从reload初值开始往下递减计数到0,产生中断和置位COUNTFLAG标志。

然后又从reload值开始重新递减计数,如此循环。

系统定时器是一个24bit的向下递减的计数器, 计数器每计数一次的时间为1/SYSCLK。

一般我们设置系统时钟SYSCLK等于72M。

当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。

2、SysTick寄存器

SysTick寄存器汇总

SysTick控制及状态寄存器

SysTick重装载数值寄存器

SysTick当前数值寄存器

SysTick校准数值寄存器

3、SysTick定时时间计算

t = reload * (1/CLK)

CLK= 72M时,t = (72)*(1/72M) = 1us

CLK= 72M时,t = (72000)*(1/72M) = 1ms

时间换算参考:

1s = 1000ms = 1000 000us = 1000 000 000ns

三、SysTick定时实验

1、编程要点

设置重装载寄存器的值。

清除当前数值寄存器的值。

配置控制与状态寄存器。

2、文件配置

SysTick.c、SysTick.h存放驱动程序及相关宏定义,中断服务在stm32f10x_it.c文件中。

3、代码

SysTick配置库函数

c 复制代码
			// 这个 固件库函数 在 core_cm3.h中 仅参考
			__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
			{
			    // 不可能的重装载值,超出范围
			    if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) {
			        return (1UL);
			    }
			
			    // 设置重装载寄存器
			    SysTick->LOAD  = (uint32_t)(ticks - 1UL);
			
			    // 设置中断优先级
			    NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
			
			    // 设置当前数值寄存器
			    SysTick->VAL   = 0UL;
			
			    // 设置系统定时器的时钟源为AHBCLK=72M
			    // 使能系统定时器中断
			    // 使能定时器
			    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
			                    SysTick_CTRL_TICKINT_Msk   |
			                    SysTick_CTRL_ENABLE_Msk;
			    return (0UL);
			}

配置SysTick中断优先级

c 复制代码
			// 设置系统定时器中断优先级
			NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
			__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
			{
			    if ((int32_t)IRQn < 0) {
			        SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] =
			        (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
			    } else {
			        NVIC->IP[((uint32_t)(int32_t)IRQn)] =
			        (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
			    }
			}

SysTick初始化函数

c 复制代码
			/**
			* @brief  启动系统滴答定时器 SysTick
			* @param  无
			* @retval 无
			*/
			void SysTick_Init(void)
			{
			    /* SystemFrequency / 1000    1ms中断一次
			    * SystemFrequency / 100000  10us中断一次
			    * SystemFrequency / 1000000 1us中断一次
			    */
			    if (SysTick_Config(SystemCoreClock / 100000)) {
			        /* Capture error */
			        while (1);
			    }
			}

SysTick定时函数

c 复制代码
			/**
			* @brief   us延时程序,10us为一个单位
			* @param
			*   @arg nTime: Delay_us( 1 ) 则实现的延时为 1 * 10us = 10us
			* @retval  无
			*/
			void Delay_us(__IO u32 nTime)
			{
			    TimingDelay = nTime;
			
			    while (TimingDelay != 0);
			}

SysTick中断服务函数

c 复制代码
			/**
			* @brief  获取节拍程序
			* @param  无
			* @retval 无
			* @attention  在 SysTick 中断函数 SysTick_Handler()调用
			*/
			void TimingDelay_Decrement(void)
			{
			    if (TimingDelay != 0x00) {
			        TimingDelay--;
			    }
			}
			void SysTick_Handler(void)
			{
			    TimingDelay_Decrement();
			}

主函数

c 复制代码
			int main(void)
			{
			    /* LED 端口初始化 */
			    LED_GPIO_Config();
			
			    /* 配置SysTick 为10us中断一次,时间到后触发定时中断,
			    *进入stm32fxx_it.c文件的SysTick_Handler处理,通过数中断次数计时
			    */
			    SysTick_Init();
			
			    while (1) {
			
			        LED_ON;
			        Delay_us(100000);   // 10000 * 10us = 1000ms
			
			        LED2_ON;
			        Delay_us(100000);   // 10000 * 10us = 1000ms
			
			        LED3_ON;
			        Delay_us(100000);   // 10000 * 10us = 1000ms
			    }
			}

4、一种简洁的代码

直接在函数内部配置SysTick

c 复制代码
		void SysTick_Delay_Ms( __IO uint32_t ms)
		{
		    uint32_t i;
		    SysTick_Config(SystemCoreClock/1000);
		
		    for (i=0; i<ms; i++) {
		        // 当计数器的值减小到0的时候,CRTL寄存器的位16会置1
		        // 当置1时,读取该位会清0
		        while ( !((SysTick->CTRL)&(1<<16)) );
		    }
		    // 关闭SysTick定时器
		    SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
		}
		void SysTick_Delay_Us( __IO uint32_t us)
		{
		    uint32_t i;
		    SysTick_Config(SystemCoreClock/1000000);
		
		    for (i=0; i<us; i++) {
		        // 当计数器的值减小到0的时候,CRTL寄存器的位16会置1
		        while ( !((SysTick->CTRL)&(1<<16)) );
		    }
		    // 关闭SysTick定时器
		    SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
		}

systick 配置函数参考

c 复制代码
		// 这个 固件库函数 在 core_cm3.h中
		static __INLINE uint32_t SysTick_Config(uint32_t ticks)
		{
		    // reload 寄存器为24bit,最大值为2^24
		    if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);
		// 配置 reload 寄存器的初始值
		    SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
		// 配置中断优先级为 1<<4 -1 = 15,优先级为最低
		    NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
		// 配置 counter 计数器的值
		    SysTick->VAL   = 0;
		// 配置systick 的时钟为 72M
		    // 使能中断
		    // 使能systick
		    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
		                    SysTick_CTRL_TICKINT_Msk   |
		                    SysTick_CTRL_ENABLE_Msk;
		    return (0);
		}
相关推荐
逐步前行3 小时前
STM32_外部中断_寄存器操作
stm32·单片机·嵌入式硬件
Saniffer_SH3 小时前
【高清视频】AI服务器调试利器:PCIe功耗分析设备 Quarch PAM 深度解析
网络·人工智能·驱动开发·嵌入式硬件·测试工具·计算机外设·压力测试
安庆平.Я3 小时前
STM32——FreeRTOS - 任务创建和删除*
stm32·单片机·嵌入式硬件
BT-BOX11 小时前
第三章|新建STM32CubeMX工程生成keil工程和proteus联调仿真
stm32·嵌入式硬件·proteus
forAllforMe12 小时前
用STM32+LAN9252, 生成一个etherCAT 从机系统,实现数据采集功能
网络·stm32·嵌入式硬件
yezhailiaoke13 小时前
【CANoe测试系列】-程控电源控制
单片机·嵌入式硬件
-Springer-16 小时前
STM32 学习 —— 个人学习笔记9-2(USART串口数据包 & 串口收发 HEX 及 文本 数据包)
笔记·stm32·学习
白掰虾17 小时前
一分钟上手STM32CubeMX2——STM32C5点灯
stm32·单片机·嵌入式硬件·stm2cubemx2·stm32c5
YY_Share17 小时前
为什么笔记本电脑电源适配器基本是19V供电
嵌入式硬件·电路设计