2024年STM32的SysTick定时器记录一篇_tim14可以用来做systick(2),一文说清

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

在这里插入图片描述
SysTick Control and Status Register
在这里插入图片描述
在这里插入图片描述

更多寄存器详细介绍,请参考文档Cortex™-M3 r1p1 技术参考手册(TRM),这里不在一一列举。

SysTick_Config() 函数是一个 CMSIS 函数,它通过配置SysTick Reload寄存器,其值作为函数参数传递。

//core\_cm3.h P1694行~P1705行
static __INLINE uint32_t SysTick\_Config(uint32_t ticks)
{ 
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /\* Reload value impossible \*/
                                                               
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /\* set reload register \*/
  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 \*/
}

3.配置SysTick定时器的步骤

1.配置时钟源
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)

//在misc.c文件
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;
  }
}	

2.计算重载值
Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s)
3.启用 SysTick 中断
4.使能SysTick 计数器

4.程序代码(注释详细)
#include "stm32f10x.h" //包含需要的头文件
#include "delay.h"
/\*-------------------------------------------------\*/
/\*函数名:初始化延迟计数器函数 \*/
/\*参 数:无 \*/
/\*返回值:无 \*/
/\*-------------------------------------------------\*/
void Delay\_Init(void)
{
	SysTick\_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
	//SysTick\_CLKSource\_HCLK\_Div8 = 8 表示分频系数
	//因为分频系数我们设置为8,所以SysTick(滴答时钟)的频率是主频率的1/8
	//通常主频率为最大的72M,那么SysTick的频率是9M
	//那么SysTick计数器的1个数,代表(1/9)us
}

/\*-------------------------------------------------\*/
/\*函数名:延迟微秒函数 \*/
/\*参 数:us:延时多少微秒 \*/
/\*返回值:无 \*/
/\*-------------------------------------------------\*/
void delay\_us(unsigned int us)
{		
	unsigned int temp;	                      //定义一个变量待用 
	
	SysTick->LOAD=us\*9;                       //计数器的重载值,要注意SysTick是倒数计数的
	                                          //SysTick计数器每倒数一个数是1/9微秒,所以我们用us\*9,就是计数器的重载值
	SysTick->VAL=0x00;                        //清空当前计数器的值
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;  //使能SysTick计数器,重载值加载到计数器中,开始倒数计数
	do{
		temp=SysTick->CTRL;                   //循环读取SysTick状态寄存器,用于判断计时结束与否
	}while(temp&0x01&&!(temp&(1<<16)));       //等待时间到达
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;  //关闭计数器 
}

/\*-------------------------------------------------\*/
/\*函数名:延迟毫秒函数 \*/
/\*参 数:ms:延时多少毫秒 \*/
/\*返回值:无 \*/
/\*-------------------------------------------------\*/
void delay\_ms(unsigned int ms)
{
	//我们首先注意一个问题SysTick时钟计数器是24位的,9M频率下,总共能延时1864.135ms
	//所有我们以1800为界限,小于1800的延时一次计数就行,大于1800的多次计数 
	
	unsigned char i;      //定义一个变量待用 
	unsigned int temp;    //定义一个变量待用 
	
	/\*-----------if判断,小于1800ms延时的情况,执行if分支------------------\*/
	if(ms<1800){                                   
		SysTick->LOAD=(unsigned int)ms\*9\*1000;     //计数器的重载值,要注意SysTick是倒数计数的 
		                                           //SysTick计1个数是1/9微秒,换算成ms的话,乘以9再乘以1000,就是计数器的重载值
		SysTick->VAL=0x00;                         //清空当前计数器的值
		SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;   //使能SysTick计数器,重载值加载到计数器中,开始倒数
		do{
			temp=SysTick->CTRL;                    //循环读取SysTick状态寄存器,判断计时结束与否
		}while(temp&0x01&&!(temp&(1<<16)));        //等待时间到达
		SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;}  //关闭计数器 
	
	/\*--------------大于1800ms延时的情况,执行else分支-------------------\*/
	else{ 
		for(i=0;i<(ms/1800);i++){                     //除以1800,整数部分,用for循环,每次延时1800ms
			SysTick->LOAD=(unsigned int)1800\*9\*1000;  //计数器的重载值,要注意SysTick是倒数计数的 
													  //SysTick一个数是1/9微秒,1800ms就是 1800\*9\*1000
			SysTick->VAL=0x00;                        //清空当前计数器的值
			SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;  //使能SysTick计数器,重载值加载到计数器中,开始倒数
			do{
				temp=SysTick->CTRL;                   //循环读取SysTick状态寄存器,判断计时结束与否
			}while(temp&0x01&&!(temp&(1<<16)));       //等待时间到达
			SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;} //关闭计数器 
		
		//接下来余数部分的延时
		SysTick->LOAD=(unsigned int)(ms%1800)\*9\*1000; //计数器的重载值,要注意SysTick是倒数计数的 
		                                              //SysTick一个数是1/9微秒,余数部分就是(ms%1800)\*9\*1000
		SysTick->VAL =0x00;                           //清空当前计数器的值
		SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;      //使能SysTick计数器,重载值加载到计数器中,开始倒数 
		do{
			temp=SysTick->CTRL;                       //循环读取SysTick状态寄存器,判断计时结束与否
		}while(temp&0x01&&!(temp&(1<<16)));           //等待时间到达
		SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;      //关闭计数器
	}
} 


关于Cortex-M3核心、SysTick定时器和NVIC的详细说明,请参考另一篇ST的文档和一篇ARM的文档: 《STM32F10xxx Cortex-M3编程手册》和《Cortex™-M3技术参考手册》

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

那么很难做到真正的技术提升。**

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值