目录
1.认识TIM
TIM,也就是Timer,定时器。那在开始学习之前呢,先做好心理准备,这对初学者来说必然是一块硬骨头。但也只能一点一点的蚕食了。
STM32的定时器分为高级定时器丶通用定时器丶基本定时器。其复杂程度逐级递减,高级定时器包括通用定时器的全部功能,通用计时器又包括基本定时器的全部功能。
2.定时器介绍
2.1基本定时器
基本定时器作为三类定时器中最简单的定时器,掌握其结构可以为其他定时器的学习打下基础。基本定时器功能:定时中断,主模式触发DAC。注意基本定时器只有内部时钟一种计时源。另外,这三个寄存器,PSC预分频器,计数器,自动重装载寄存器都是16位的,且这三者的组合称为时基单元。
CK_PSC与内部时钟CK_INT直接相连接,内部时钟为72MHZ,通过PSC预分频器。PSC预分频器是对输入的CK_PSC进行(PSC+1)分频,举个例子,要对输入时钟进行2分频,则PSC预分频器赋值1,则两个时钟信号周期PSC预分频器向计数器发送一个脉冲,要进行3分频,PSC赋值2,每三个时钟信号周期PSC预分频器向计数器发送一个脉冲CK_CNT,所以CK_CNT也称计数器时钟。
计数器部分,顾名思义,CK_CNT每次上升沿时计数器加一,一直到与自动重装载寄存器内通过代码设定的数值一致时,计数器被清零,并发出中断请求。这种中断请求被成为更新中断,通过图中UI发送到NVIC,再配置好NVIC,则CPU就可以响应定时器的中断请求。而UI下方,箭头方向朝右下的箭头代表产生一个事件,称为更新事件,它并不会触发中断,而是用于与其他部分电路的联动。
以上是基本定时器的定时中断功能,基本定时器的主模式触发DAC功能在后续学习中会另外学习,在此有大致了解即可。基本定时器中TRGO接到DAC,如果需要每隔一段事件进行一次DAC转换,当然可以将其放在中断里,每隔一段时间调用一次DAC转换函数。但是STM32的主模式可以将基本定时器中“更新事件”的端口映射到TRGO,即TRGO的状态与“更新时间”端口一样,这样通过映射和“更新事件”,不用中断,只利用定时器的计时功能就可以实现每隔一段事件进行一次DAC转换。实现硬件的自动化。
2.2通用定时器
通过框图一眼看去,通用定时器比基本定时器复杂的多,但是再复杂也要坚持。通用定时器的功能:包括了基本定时器的所有功能,另外还有内外时钟源选择,输入捕获,输出比较,编码器接口,主从触发模式等功能。且时基单元中的计数器不单单只有向上计数模式,还有向下计数模式和中央对齐计数模式。
向上/向下/中央对齐计时模式:向上就是从小到大计数,例如从0计到15,然后被清零又从0开始计数。向下计数就是从大到小,例如从15计到0,然后被重置为15重新开始计数。中央对齐就是从0计到15,再从15计到0。
从熟悉的时基单元开始看,和基本定时器中一样,然后顺藤摸瓜,PSC预分频器的输入大相径庭。触发控制器的输入由四部分组成:
1.最上面的内部时钟与基本定时器一样,不做过多叙述。
2.下面紧接的是ETR外部时钟,可以在STM32引脚表中查看哪些引脚具有ETR的功能。ETR通过的极性选择丶边沿检测和预分频器,输入滤波,都是为了稳定输入信号,ETR外部时钟是通过GPIO口输入的,这种外部输入方式产生的信号很容易受影响产生毛刺(即信号高低电平有波动)。经过滤波后的输入信号,可以直接通过控制器作为时钟信号,成为“外部时钟模式2”也可以通过TRGI输入,当TRGI被当作时钟信号的输入时成为“外部时钟模式1”,当然TGRI还有一些其他功能,这里还没涉及到。注意,每个TIM对应的外部时钟输入引脚是固定的,如TIM2对应的外部输入引脚为PA0,如果使用其他引脚是不会触发定时器计时的。
3.再下面就是TRGI了,可以由其他定时器产生时钟信号,也可以由ETR外部时钟信号产生时钟,这种ETR产生时钟称为“外部时钟模式1”。
4.TLX捕获通道,本节课没学到。
这是定时器的时钟源的4种选择方案,在时基单元的下方,是输入捕获和输出比较,这些在后续课程中学习,这里不用了解。
2.3高级定时器
暂时不做介绍,一方面是比较复杂,另一方面是对于初学者来说一般用不到。
3.定时器中断大致结构
选择时钟源-->配置时基单元-->使能中断输出-->配置NVIC-->打开定时器运行。
4.时基单元时序
4.1预分频器时序
CK_PSC是时基单元的时钟信号,CNT_EN是计数器的时钟使能,CK_CNT是定时器的时钟信号。可以看到,计数器寄存器在FC之后变成00,可以知道FC就是重载值。预分频控制寄存器是我们通过代码读写的寄存器,可以看到,修改预分频控制寄存器的值后,真正起预分频作用的预分频计数器并没有直接同步预分频控制寄存器的值,而是等待当前计数完成,再将预分频控制寄存器的值传给预分频计数器。
计数器溢出频谱 = CK_PSC / (PSC + 1)(ARR + 1)
其他时序,了解即可:
5.Keil5代码
5.1.部分常用函数
TIM_DeInit 复位
时基单元:
TIM_TimeBaseInit 时基单元初始化
TIM_TimeBaseStructInit 给时基单元数组赋一个默认值
运行控制:
TIM_Cmd 使能计时器,允许/停止 计时器工作
中断输出控制:
TIM_ITConfig 使能外设(定时器)的中断输出
时钟源选择:
TIM_InternalClockConfig 使用内部时钟
TIM_ITRxExternalClockConfig 使用其他ITRx定时器的时钟
TIM_TIxExternalClockConfig 使用TIx捕获通道(目前还没学到)作为时钟
TIM_ETRClockMode1Config 使用ETR,以外部输入模式1作为时钟
TIM_ETRClockMode2Config 使用ETR,以外部输入模式1作为时钟
TIM_ETRConfig 专门用来配置ETR输入的极性,滤波器,预分频器
为了方便,某些值可以通过函数直接更改
TIM_PrescalerConfig 预分频值
TIM_CounterModeConfig 改变计时器的计时模式
TIM_ARRPreloadConfig 自动重装器预装功能配置
TIM_SetCounter 给计数器写入一个值
TIM_SetAutoreload 给自动重装器写一个值
TIM_GetCounter 获取当前计数器的值
TIM_GetPrescaler 获取当前预分频器的值
获取标志位/清除标志位:
TIM_GetFlagStatus
TIM_ClearFlag
TIM_GetITStatus
TIM_ClearITPendingBit
5.2.使用流程
//第一步,使能TIM2时钟,并配置对应GPIO(外部时钟源为例)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_Initstructure;
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Initstructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_Initstructure);
//第二步,选择时钟源
TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x00);//TIM_ExtTRGPolarity_NonInverted为上升沿触发,TIM_ExtTRGPSC_OFF是预分频,0x0F外部输入滤波器
//第三步,配置时基单元
TIM_TimeBaseInitTypeDef TIM_Initstructure;
TIM_Initstructure.TIM_ClockDivision = TIM_CKD_DIV1 ;//直接由内部时钟产生分频来减小时钟信号的毛刺
TIM_Initstructure.TIM_CounterMode = TIM_CounterMode_Up;//向上/下/中央分频计数
TIM_Initstructure.TIM_Period = 3 - 1;//计几次数进一次中断
TIM_Initstructure.TIM_Prescaler = 2 - 1;//记一次数要几个机械周期
TIM_Initstructure.TIM_RepetitionCounter = 0;//重复计数器,高级计数器才有,这里用不到就给0
TIM_TimeBaseInit(TIM2,&TIM_Initstructure);
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
//第四步,中断输出控制
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
//第五步,NVIC
NVIC_InitTypeDef NVIC_Initstructure;
NVIC_Initstructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_Initstructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_Initstructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_Initstructure);
//第六步,运行控制
TIM_Cmd(TIM2,ENABLE);
标签:NVIC,定时器,STM32,TIM,Initstructure,GPIO,时钟
From: https://blog.csdn.net/2303_76686142/article/details/139841602