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

相关推荐
会编程的小孩5 小时前
STM32用PWM驱动步进电机
stm32·单片机·嵌入式硬件
努力做小白6 小时前
Linux驱动11 --- buildroot&杂项驱动开发方法
linux·运维·驱动开发·单片机·嵌入式硬件
小眼睛FPGA7 小时前
【RK3568+PG2L50H开发板实验例程】FPGA部分 | 以太网传输实验例程
科技·单片机·嵌入式硬件·ai·fpga开发·fpga
小刘摸鱼中7 小时前
INA226 数据手册解读
stm32·单片机·嵌入式硬件·芯片
切糕师学AI8 小时前
MCU中的系统控制器(System Controller)是什么?
嵌入式硬件·mcu
蜡笔小电芯11 小时前
【STM32】const 变量存储学习笔记
笔记·stm32·学习
扣篮发型不乱14 小时前
STM32 | HC-SR04 超声波传感器测距
stm32·单片机·嵌入式硬件
几个几个n16 小时前
STM32-第五节-TIM定时器-1(定时器中断)
stm32·单片机·嵌入式硬件
EutoCool17 小时前
Qt窗口:QToolBar、QStatusBar、QDockWidget、QDialog
开发语言·数据库·c++·嵌入式硬件·qt·前端框架
国科安芯18 小时前
车规级ASM1042芯片在汽车无线充电模块中的应用探索
人工智能·单片机·嵌入式硬件·物联网·安全·汽车