stm32入门之通用定时器(TIM2~TIM5)

2023-04-12 02:30   343   0  

在stm32的开发中我们经常会用到定时器,因此在学习stm32的过程中定时器是必须要学的,而定时主要又分为三大类分别为:


高级控制定时器(TIM1与TIM8)


通用定时器(TIM2~TIM5)


基本定时器(TIM6与TIM7)


今天我只要想给大家介绍的是第二种通用定时器(TIM2~TIM5),还是老样子我先以文字给大家简单概述,在通过视频详细为大家分析细节。


精通定时间的老油条勿喷!!!


首先我们先来了解一下TIM2~TIM5定时器基本功能


(1)16位向上、向下、向上/向下自动装载计数器


(2)16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值


(3)4个独立通道:


─ 输入捕获


─ 输出比较


─ PWM生成(边缘或中间对齐模式)


─ 单脉冲模式输出


(4)使用外部信号控制定时器和定时器互连的同步电路


(5)如下事件发生时产生中断/DMA:


─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)


─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)


─ 输入捕获


─ 输出比较


─ 支持针对定位的增量(正交)编码器和霍尔传感器电路


─ 触发输入作为外部时钟或者按周期的电流管理


然后在带大家看一下通用定时器(TIM2~TIM5)通道对应的引脚


2ecd4822-ac53-11ed-bcd2-b8ca3a6cb5c4.jpg


上面的定时器对应的引脚只能说是一般情况下是这样的,如果考虑定时器复用功能重映射的话,则会有些出入,在《参考手册》中列出了一些定时器重映射的引脚,如下面几张图片所示:


2ecd4823-ac53-11ed-bcd2-b8ca3a6cb5c4.jpg2ecd4824-ac53-11ed-bcd2-b8ca3a6cb5c4.jpg2fc25f10-ac53-11ed-bcd2-b8ca3a6cb5c4.jpg2fc25f11-ac53-11ed-bcd2-b8ca3a6cb5c4.webp


最后我们来给大家来通过实际配置来举例


在配置之前我们首先要了解通用定时器的时钟可来自于外部或内部,选用默认即是采用内部的。通用定时器的时钟来源为APB1总线,所以首先,得将APB1外设时钟打开。


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);


其次,就是定时器的相关参数信息的配置,这些参数信息都在TIM_TimeBaseInitTypeDef这么一个结构体当中,所以得定义这么一个结构体变量。结构体中的有关成员含义如下:


TIM_TimeBaseInitStrcture.TIM_Prescaler = 0x1c20; //时钟预分频系数,看单词意思就知道了,即是将APB1时钟进行相应分频得到一个合适的频率
TIM_TimeBaseInitStrcture.TIM_CounterMode = TIM_CounterMode_Up; //计数模式
TIM_TimeBaseInitStrcture.TIM_Period = 0x270f; //计数周期,即是往ARR寄存器中填的一个自动转载值,这个值等于目标值-1
TIM_TimeBaseInitStrcture.TIM_ClockDivision=TIM_CKD_DIV1; //这是数字滤波器的相关设置,定时的时候不用外部时钟,所以这个设为0即可,TIM_CKD_DIV1这个就是等价于0,你要是设为其他值也不影


下面自然是初始化这个结构体当中的参数信息了。
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStrcture);
再次,就是定时器中断的相关配置了,在配置中断的时候特别一定要注意顺序,否则就会出问题,我一开始就是没注意这个顺序问题,看着错误还不知道怎么回事,还好后面被我发现,哈哈。在使能中断之前一定得先清掉中断中断标志位和中断挂起位,如下:


TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_ClearITPendingBit(TIM2, TIM_FLAG_Update);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);


如果不先清掉挂起位和标志位,那么一使能中断,就立马进入中断服务函数,显然这不是我们想要的,我就被这个问题整了一下。接下来就是使能定时器了,TIM_Cmd(TIM2, ENABLE);这自不用说。
最后,就是配置NVIC嵌套向量中断控制寄存器了。


NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00);//the second parameter must be a multiple of 0x200
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//2 bits for pre-emption priority, 2 bits for subpriority
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);


其实,我认为在主函数里调用定时器配置函数和NVIC配置函数时,应该先调用NVIC配置函数,因为先设置好中断分组等相关参数信息后,再去打开定时器,定时器中断就能按照NVIC的信息去工作。
接下来的就是在stm32f10x_it.c中写自己的中断服务函数了。
void TIM2_IRQHandler(void)
{
…………
}
到此,通用定时器配置成功。




登录icspec成功后,会自动跳转查看全文
博客评论
还没有人评论,赶紧抢个沙发~
发表评论
说明:请文明发言,共建和谐网络,您的个人信息不会被公开显示。