[9]STM32 SysTick嘀嗒定时器

2023-10-28 14:59
文章标签 stm32 定时器 systick 嘀嗒

本文主要是介绍[9]STM32 SysTick嘀嗒定时器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

这次主要讲了STM32 systick嘀嗒定时器和相关函数的应用,通过systick实现计时,但实际上正点原子的开发板已经把systick封装起来了用的自己的delay函数,反而更方便,这篇博客主要讲一下systick的相关寄存器和库函数,以及systick的应用。

SysTick基础知识

SysTick 是一个 24 位的倒计数定时器,当计数到 0 时,将从RELOAD 寄存器中自动重装载定时初值,开始新一轮计数,这是Systick的主要功能,就是一个无限循环的一个计数器。
SysTick 有四个寄存器分别是CTRL(SysTick控制及状态寄存器),LOAD(SysTick重装载数值寄存器),VAL(SysTick当前数值寄存器),CALIB(SysTick校准数值寄存器),因为systick是内核级别的,所以可以参考《Cortex-M3权威指南-中文》第八章最后一个小节,里面对怎么配置寄存器有详细的介绍。

SysTick寄存器

typedef struct
{__IO uint32_t CTRL;                         /*!< Offset: 0x00  SysTick Control and Status Register */__IO uint32_t LOAD;                         /*!< Offset: 0x04  SysTick Reload Value Register       */__IO uint32_t VAL;                          /*!< Offset: 0x08  SysTick Current Value Register      */__I  uint32_t CALIB;                        /*!< Offset: 0x0C  SysTick Calibration Register        */
} SysTick_Type;

如下图所示是M3权威指南里面的表格。
CTRL寄存器第0位是使能,第1位就是中断,第2位是选择时钟源,外部时钟源是HCLK(AHB总线时钟)的1/8,而内部时钟源就是HCLK,具体可参考[7]STM32基础知识-时钟系统里面的时钟框图。而16位是检测Systick定时器是否归0
LOAD寄存器,顾名思义就是在SysTick定时器计时完之后对其进行装载一个数,使其继续计时。
VAL寄存器,就是清空计数器,在每次进行计数时一般都要清空计数器再进行装载
在这里插入图片描述

SysTick相关函数

**SysTick_CLKSourceConfig()**函数主要是配置CTRL寄存器,对Systick时钟源进行选择

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; //对第2位寄存器进行判断,选择时钟源}else{SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;}
}

**SysTick_Config(unit32_t ticks)**函数用于初始化systick,时钟为HCLK,并开启中断。ticks表示两次中断之间的计数间隔。

static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);      /      /* Reload value impossible(ticks有效性判断,因为systick是一个24位计数器) */SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register (装载数是ticks-1,比如计数器是从1000计数到0,在计数到0之后装载999到计数器中)*/NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */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中断服务函数:void SysTick_Handler(void);

用中断的方式实现Delay延时

static __IO uint32_t TimingDelay;
void Delay(__IO uint32_t nTime)
{ TimingDelay = nTime;while(TimingDelay != 0);
}
void SysTick_Handler(void)
{if (TimingDelay != 0x00) { TimingDelay--;//共200ms}
}//是在stm32f10x_it.c定义好的”void SysTick_Handler(void){}”就差填里面的函数体,中断的时候自动调用。int main(void){  …if (SysTick_Config(SystemCoreClock / 1000)) //systick时钟为HCLK(时钟72MHz,中断频率为时钟频率的1/1000),中断时间间隔1ms{while (1);}while(1){ Delay(200);//200ms… }
}

正点原子的Delay函数

static u8  fac_us=0;							//us延时倍乘数			   
static u16 fac_ms=0;							//ms延时倍乘数,在ucos下,代表每个节拍的ms数
void delay_init()
{
#if SYSTEM_SUPPORT_OS  							//如果需要支持OS.u32 reload;
#endifSysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);	//选择外部时钟  HCLK/8fac_us=SystemCoreClock/8000000;				//为系统时钟的1/8  
#if SYSTEM_SUPPORT_OS  							//如果需要支持OS.reload=SystemCoreClock/8000000;				//每秒钟的计数次数 单位为K	   reload*=1000000/delay_ostickspersec;		//根据delay_ostickspersec设定溢出时间//reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右	fac_ms=1000/delay_ostickspersec;			//代表OS可以延时的最少单位	   SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;   	//开启SYSTICK中断SysTick->LOAD=reload; 						//每1/delay_ostickspersec秒中断一次	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;   	//开启SYSTICK    #elsefac_ms=(u16)fac_us*1000;					//非OS下,代表每个ms需要的systick时钟数   
#endif
}								    

void delay_us(u32 nus)
{		u32 temp;	    	 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;      					 //清空计数器	 
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864 
void delay_ms(u16 nms)
{	 		  	  u32 temp;		   SysTick->LOAD=(u32)nms*fac_ms;				//时间加载(SysTick->LOAD为24bit)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;       					//清空计数器	  	    
} 

思路还是比较简单的,就是用函数封装配置寄存器的操作,在之后的程序里面就可以直接调用写好的delay_ms()或者delay_us()的函数进行延时控制了。

参考资料

《STM32F1开发指南-库函数版本》5.1小节
《Cortex-M3权威指南-中文》第八章最后一个小节

这篇关于[9]STM32 SysTick嘀嗒定时器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/293991

相关文章

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

STM32 ADC+DMA导致写FLASH失败

最近用STM32G070系列的ADC+DMA采样时,遇到了一些小坑记录一下; 一、ADC+DMA采样时进入死循环; 解决方法:ADC-dma死循环问题_stm32 adc dma死机-CSDN博客 将ADC的DMA中断调整为最高,且增大ADCHAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_Buffer_Size); 的ADC_Bu

【Qt】定时器事件

定时器事件 在之前学习QTimer中实现了定时器的功能,而在QTimer背后是QTimerEvent定时器事件进行支撑的。在QObject中提供了一个timeEvent这个函数。 startTimer启动定时器killTimer关闭定时器 Qt 中在进⾏窗⼝程序的处理过程中,经常要周期性的执⾏某些操作,或者制作⼀些动画效果,使⽤定 时器就可以实现。所谓定时器就是在间隔⼀定时间后,去执⾏某⼀

独立按键单击检测(延时消抖+定时器扫描)

目录 独立按键简介 按键抖动 模块接线 延时消抖 Key.h Key.c 定时器扫描按键代码 Key.h Key.c main.c 思考  MultiButton按键驱动 独立按键简介 ​ 轻触按键相当于一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通与断开。  ​ 按键抖动 由于按键内部使用的是机

基于stm32的河流检测系统-单片机毕业设计

文章目录 前言资料获取设计介绍功能介绍具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机设计精品

STM32的使用方法一

注:我采用的是STM32F103RC芯片、相应的电路图和STM32CubeIDE软件这是在STM32CubeIDE软件定义芯片后,所给的必要的代码逻辑,加上了注释 #include "main.h"/* Private variables ---------------------------------------------------------*//* Private function