初学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 被意外关闭导致的死循环。

相关推荐
HRTOS5 小时前
HRTOS 任务优先级与调度模式说明
单片机·嵌入式硬件·系统架构·51单片机
cu1435 小时前
细谈GM7123C的具体功能与其应用
c语言·c++·人工智能·嵌入式硬件
嵌入式分享6 小时前
驱动之路#44:硬件 I2C 和软件 I2C 谁更坑?
linux·嵌入式硬件
嵌入式分享7 小时前
嵌入式分享#19:《嵌入式外设调试思路》--I2C设备篇
单片机·嵌入式硬件
WD137298015577 小时前
WD5030K输入工作电压 7.5‑30V,适合12A 及以内量产项目
stm32·单片机·嵌入式硬件·51单片机
千秋岁rr7 小时前
12.IIC
单片机·嵌入式硬件
光子物联单片机8 小时前
STM32传感器模块编程实践(二十二)DIY智能WIFI视频控制小车
c语言·stm32·单片机·嵌入式硬件·音视频
jucat8 小时前
拆个烟雾报警器
嵌入式硬件
HRTOS9 小时前
HRTOS 高速任务与中断嵌套的 8051 寄存器组资源说明
单片机·嵌入式硬件·系统架构·51单片机
新晨单片机设计9 小时前
S010C-基于STM32单片机水温控制系统(OLED显示)【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus·水温控制系统