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

相关推荐
wotaifuzao12 小时前
SPI通信:从原理到工程实践
stm32·单片机·mcu·物联网·iot·spi
最后一个bug13 小时前
linux内核中的一致性DMA与流式DMA
linux·开发语言·嵌入式硬件·系统架构·计算机外设
猪八戒1.014 小时前
按键与中断
单片机·嵌入式硬件
Hello阿尔法14 小时前
【ElfBoard】ELF 2 搭载 RK3588 “出道即巅峰”
linux·嵌入式硬件·ubuntu
清风66666614 小时前
基于单片机的N型热电偶PID锅炉温度控制系统
数据库·单片机·mongodb·毕业设计·课程设计·期末大作业
点灯小铭14 小时前
基于单片机的智能定时闹钟
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
不做无法实现的梦~1 天前
如何使用px4来开发新机型
linux·嵌入式硬件·机器人·自动驾驶
一路往蓝-Anbo1 天前
STM32单线串口通讯实战(四):裸机架构 —— 事件驱动与状态机设计
c语言·开发语言·stm32·单片机·嵌入式硬件·架构
v先v关v住v获v取1 天前
轴流泵的水力及结构设计9张cad+设计说明书
科技·单片机·51单片机
Source.Liu1 天前
【ESP32】全面介绍
单片机·嵌入式硬件