STM32学习系列(二)--- 基本定时器

本文详细介绍了STM32F103的基本定时器功能、原理应用、硬件平台配置,包括计时与中断设置,并分享了代码实例及常见问题解决。适合初学者了解STM32定时器的基础操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STM32学习系列(二)— 基本定时器

#STM32
2022-05-11 20:41

该系列是为了记录自己的学习过程,如有错误和不足,欢迎指出,感谢!

一、简介

STM32F103有三种定时器:

  1. 基本定时器(TIM6,TIM7)
  2. 通用定时器
  3. 高级控制定时器(TIM1,TIM8)

功能从简单到复杂,可以根据不同的需求来选择不同的定时器。

如果是用来基础的定时,那就可以选择基本定时器;
用来输出PWM波形,输入捕获等功能,就需要用通用定时器;
要求更高一些,或者PWM波形的通道数多的时候,可能就需要高级控制定时器。

基本定时器的功能比较简单,使用的主要目的,就是用来计算时间,或者进行计数。
基本定时器没有对应的IO引脚,这点需要注意。
拥有:

  1. 16位自动装载的累加计数器;
  2. 16位可编程的预分频器;【0~65535】
  3. 计数溢出时,能产生中断或者DMA请求【我在使用中主要是产生中断,进行基础的计时】
  4. 触发DAC同步电路【这个我没有用过】

在这里插入图片描述

二、原理

2.1 当做定时器来使用
简单概括来说,通过公式Time (us)= (arr + 1)* (psc + 1) / Ft ,来设置需要的中断间隔时间,arr为自动装载值,psc为分频器系数,Ft为定时器工作的频率(MHz)。
例如:系统时钟为72MHz,我需要一个1ms一次的中断时间。
将参数带入 Time = (arr + 1)* (psc + 1) / Ft 进行计算;
1ms =1000us = (arr + 1)* (psc + 1) / 72 【psc 取值为0~65535】
(arr + 1)* (psc + 1) = 72000
(199 + 1)* (359 + 1) = 72000
也就是说arr取199,psc取359,那么定时器就会在1ms产生一次中断。
最难的部分,应该就是自动装载值和分频系数的计算上了。

2.2 当做计数器来使用
单纯的用作计数器,我没有这样使用过,但是思路是:
配置完成之后,通过定时器开启和关闭,来完成计数的目的。
可以参考超声波测距的教程,很多里面都是把基本定时器当做计数器来使用,我是通过计算时间差来完成声波计算的。

三、硬件平台

韦东山stm32开发板

四、编程思维

  1. 基本定时器没有IO引脚,不需要IO初始化
  2. 初始化定时器结构体,参数和模式设置
  3. 打开中断
  4. 中断服务函数编写
  5. 中断服务函数的回调函数编写

五、代码实现

程序初始化:

TIM_HandleTypeDef 	TIM6_Handler;      	//定时器句柄 


//基本定时器中断初始化
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
//这里使用的是定时器6!
void TIM6_Init(u16 arr,u16 psc)
{  
    TIM6_Handler.Instance=TIM6;                          //基本定时器6
    TIM6_Handler.Init.Prescaler=psc;                     //分频系数
    TIM6_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;    //向上计数器,从0开始计数
    TIM6_Handler.Init.Period=arr;                        //自动装载值
    TIM6_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频因子
    HAL_TIM_Base_Init(&TIM6_Handler);//使能定时器6 
    
    HAL_TIM_Base_Start_IT(&TIM6_Handler); //定时器6更新中断   
}

//定时器6中断服务函数
void TIM6_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&TIM6_Handler);
}

//回调函数,定时器中断服务函数调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{

	if(htim==(&TIM6_Handler))
    {
		++ RunTimems ; // 每1ms,做一次累计,我就是使用这个变量
	}
}

六、总结

整体来说,需要配置的东西比较少,主要就是自动装载值和分频系数的计算。

在调试的过程中,发现了一个问题。
初始化TIM6_Init(200,360),之后,定时器并没有跑起来,而且也没有进入定时中断,去找了资料才发现是启动文件的问题,用的是正点原子的工程,我的硬件是韦东山的开发板,flash是512KB的。所以启动文件要用hd.s,既startup_stm32f10x_hd.s,这个文件里面才有TIM6的中断函数,更换了启动文件之后,运行正常。
![[Pasted image 20220511230601.png]]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值