初学stm32 -- SysTick定时器

以delay延时函数来介绍SysTick定时器的配置与使用

首先是delay_init()延时初始化函数,这个函数主要是去初始化SysTick定时器;

cpp 复制代码
void delay_init()
{

	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);	//选择外部时钟  HCLK/8
	fac_us=SystemCoreClock/8000000;				//为系统时钟的1/8  
	fac_ms=(u16)fac_us*1000;					//代表每个ms需要的systick时钟数   
}	

在FWLIB文件夹里的misc.c文件中定义了一个函数SysTick_CLKSourceConfig(),用来配置使用那个HCLK作为时钟源,还是外部时钟HCLK_Div8作为时钟源。

cpp 复制代码
/**
  * @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;
  }
}

这里选择外部时钟 HCL/8 对于系统时钟为72MHz的stm32中,这个定时器一跳的频率为 9MHz。

然后计算us级延时的计算因子fac_us和ms级延时的计算因子fac_ms。这个计算因子表示:比如72MHz的系统时钟,us级延时,那么us级延时的计算因子fac_us为72000000000000 / 8000000 = 9000000。所有定时器需要经过9000000跳(周期),才经过1us时间。同理9000000000跳才经历1ms。

us级延时函数定义如下:

cpp 复制代码
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;      					 //清空计数器	 
}

这里要先说一下 sysTick 是 MDK 定义了的一个结构体(在 core_m3.h 里面),里面包含 CTRL、 LOAD、 VAL、CALIB 等 4 个寄存器

SysTick->CTRL 的各位定义如图1 所示:
图1 SysTick->CTRL 寄存器各位定义

SysTick-> LOAD 的定义如图2 所示:
图2 SysTick->LOAD 寄存器各位定义

SysTick-> VAL 的定义如图3 所示:
图3 SysTick->VAL 寄存器各位定义

先把要延时的 us 数换算成 SysTick 的时钟数,然后写入 LOAD 寄存器。然后清空当前寄存器 VAL 的内容,再开启倒数功能。等到倒数结束,即延时了 nus。最后关闭 SysTick,清空 VAL 的值。实现一次延时 nus的操作,但是这里要注意 nus 的值,不能太大,必须保证 nus<=(2^24) /fac_us,否则将导致延时时间不准确。 这里特别说明一下: temp&0x01,这一句是用来判断 systick 定时器是否还处于开启状态,可以防止 systick 被意外关闭导致的死循环。

相关推荐
星夜夏空995 小时前
STM32单片机学习(10)——GPIO输入
stm32·单片机·学习
secondyoung7 小时前
Arm架构解析:Cortex-R系列架构概览
arm开发·单片机·嵌入式硬件·mcu·arm
FreakStudio9 小时前
开源分享|用MicroPython 做了个 AI 小鸡,它会长大,还记得我所有的情绪
python·单片机·嵌入式·面向对象·并行计算·电子diy·电子计算机
黑白园11 小时前
I2C_GPIO模拟 读取AS5600编码器数据
stm32·单片机·嵌入式硬件
羽获飞11 小时前
从零开始学嵌入式之STM32——34.ADC-模数转换
stm32·单片机·嵌入式硬件
csg110711 小时前
智慧养殖篇(四):猪场自动化饲喂与疫病预警
运维·单片机·嵌入式硬件·物联网·自动化
羽获飞11 小时前
从零开始学嵌入式之STM32——33.直接存储器访问-DMA
stm32·单片机·嵌入式硬件
jllllyuz12 小时前
stm32“多串口并发采集 + 无线传输”系统实现
stm32·单片机·嵌入式硬件
LCG元12 小时前
STM32实战:基于STM32F103的简易示波器(ADC+DMA+LCD)
stm32·单片机·嵌入式硬件
小灰灰搞电子13 小时前
rt-thread UART串口使用详解
单片机·嵌入式硬件·串口