5、TIM定时器中断
5、TIM定时器中断
1、 TIM简介
定时器:可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
STM32在72MHz计数时钟下可以实现最大59.65s的定时。
16位计数器:执行计数定时的一个寄存器,每来一个时钟,计数器加1
预分频器:可以对计数器的时钟进行分频,让这个计数更加灵活
自动重装寄存器:计数的目标值(计多少个时钟申请中断),这些寄存器构成了最核心的部分。
这三部分组成了定时器的时基单元(计数器、自动重装寄存器、预分频器)
不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
- 内外时钟源选择:STM32定时器允许你选择内部时钟源或外部时钟源,以满足不同的时序要求。这使得定时器能够适应不同的时钟环境。
- 输入捕获:定时器可以捕获外部事件的时间戳,例如上升沿或下降沿触发。这对于测量脉冲宽度、频率或其他时间相关的应用非常有用。
- 输出比较:定时器可以与输出比较功能一起使用,以在特定时间点产生或清除输出信号。这用于生成PWM信号、产生精确的脉冲输出等。
- 编码器接口:某些定时器可以配置为编码器接口模式,用于读取旋转编码器的位置或方向信息。这在机械系统中的位置反馈中很有用。
- 主从触发模式:定时器可以配置为主从触发模式,其中一个定时器可以触发另一个定时器的启动或停止。这对于精确的时间同步和多个定时器的协同工作非常有用。
根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型:
STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4
2、 基本定时器
可以完成定时中断,主模式触发DAC的功能。
DAC功能:数模转换
内部时钟(CK_CNT):一般就是系统的主频72MHz,通向时基单元的输入。
时基单元:16位预分频器 + 16位计数器 + 16位自动重装载寄存器。
预分频器:对输入的72MHz时钟进行预分频,寄存器内存储的值是实际的分频系数减一。写0就是不分频,写1就是2分频,写2就是3分频……
计数器:对预分频后的计数时钟进行计数,每遇到上升沿就加一。
自动重装载寄存器:存储计数的最大值,到达此值后触发中断并清零计数器。
折线UI:向上的折线箭头表示该位置会产生中断信号——“更新中断”(由计数值等于自动重装值产生的中断),这个中断信号会通向NVIC
折线U:向下的折线箭头表示该位置会产生事件——“更新事件”,这个更新事件不会触发中断,但可以触发内部其他电路的工作。比如将更新事件映射到触发输出TRGO,然后TRGO直接接到DAC的触发转换引脚上。
主模式触发DAC数模转换功能:
stm32的一大特色就是主从触发模式,可以让内部的硬件在不受程序的控制下自动运行,可以极大地减轻CPU的负担。
驱动DAC正常思路及其问题:
每隔一段时间就产生一个定时中断,手动更新DAC的值。但这样子会频繁的产生中断,会影响主程序的运行和其他中断的响应。
解决方法:
定时器设计了一个主模式,使用主模式可以将定时器的“更新事件”映射到“触发输出TRGO”,然后TRGO直接接到DAC的触发转换引脚上,于是定时器的更新就不需要中断来实现了。整个过程无需软件参与,实现了硬件的自动化。
3、 通用定时器
时基单元:PSC预分频器、CNT计数器、自动重装寄存器。通用定时器和高级定时器新增两个功能:向下计数模式、中央对齐计数模式。
向上计数模式(常用):从0开始累加,到自动重装值触发中断。
向下计数模式:从自动重装值递减,到0触发中断
中央对齐计数模式:从0开始累加,到自动重装载值触发中断,然后递减,到0再次触发中断。常用于电机控制的SVPWM算法中。
内外时钟源选择和主从触发模式结构:上面的一大块。下面介绍各种各样的内外时钟源:
定时器中断基本结构:
时基单元:中间的粉色部分。
运行控制:控制寄存器的一些位,如启动停止、向上或向下计数等,操作这些寄存器就可以控制时基单元的运行了。
内部时钟模式、外部时钟模式2、外部时钟模式1:外部时钟源选择。这个选择器的输出就是为时基单元提供时钟。
编码器模式:编码器独有的模式,一般用不到。
中断申请控制:由于定时器内部有很多地方要申请中断,“中断申请控制”就用来使能控制这些中断是否使能。比如,中断信号会先在状态寄存器里置一个中断标志位,这个标志位会通过中断输出控制,到NVIC申请中断。
1 | /** |
这些注释提供了对每个函数的功能和参数的清晰解释。如果有任何进一步的疑问,请随时提出。
4、 定时器初始化步骤
开启RCC内部时钟:首先,您需要启用与所选定时器相关的RCC (Reset and Clock Control) 时钟。这可以通过调用适当的RCC函数来实现,例如
RCC_APB1PeriphClockCmd()
或RCC_APB2PeriphClockCmd()
。选择时基单元的时钟源:定时器的时基单元需要一个时钟源来进行计数。您可以选择内部时钟源或外部时钟源,具体取决于您的应用。通常,对于定时中断,内部时钟源足够。您可以使用
TIM_InternalClockConfig()
函数来选择内部时钟源。配置时基单元:时基单元
TIM_TimeBaseInitTypeDef
由TIM_ClockDivision
分频系数、TIM_CounterMode
计数方向、TIM_Period
自动重装载值、TIM_Prescaler
预分频器、TIM_RepetitionCounter
重复计数器的值,用于高级定时器配置输出中断控制:如果您需要在定时器溢出或到达某个特定值时触发中断,您需要配置输出中断控制。使用
TIM_ITConfig()
函数来启用或禁用定时器的特定中断。配置NVIC:在配置输出中断后,您需要在NVIC (Nested Vector Interrupt Controller) 中启用定时器中断通道,并为该中断通道分配一个优先级。使用
NVIC_Init()
函数来完成此操作。运行控制:最后,您可以使用
TIM_Cmd()
函数来启动或停止定时器的计数。如果您已正确配置了时基单元、中断和NVIC,则定时器将在满足特定条件时触发中断。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42void Timer_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 开启TIM2的时钟
TIM_InternalClockConfig(TIM2);
// 配置TIM2的时钟源为内部时钟
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
// 配置TIM2的时间基准参数
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
// 时钟分频因子
TIM_TimeBaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;
// 计数模式为向上计数
TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;
// 自动重装载寄存器的值,决定了定时器的周期
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
// 预分频器的值,决定了计数器时钟的频率
//72M对7200分频,得到的就是10K的计数频率,在10的频率下计一万个数就是1s的时间
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
// 重复计数器的值,用于高级定时器,TIM2为基本定时器,可以忽略
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
// 清除TIM2的更新标志位
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// 使能TIM2的更新中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// 配置NVIC,设置中断优先级
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
// 中断通道为TIM2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// 使能中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
// 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
// 子优先级
NVIC_Init(&NVIC_InitStructure);
// 启动TIM2定时器
TIM_Cmd(TIM2, ENABLE);
}这段代码完成了以下操作:
- 打开TIM2的时钟,确保TIM2可以正常工作。
- 配置TIM2的时钟源为内部时钟,即使用内部时钟作为计数器的时钟源。
- 配置TIM2的时间基准参数,包括时钟分频因子、计数模式、周期和预分频器的值。这些参数决定了TIM2的工作频率和计数周期。
- 清除TIM2的更新标志位,以确保不会立即触发中断。
- 使能TIM2的更新中断,以便在计数器溢出时触发中断。
- 配置NVIC,为TIM2中断通道分配抢占优先级和子优先级。
- 启动TIM2定时器,开始计数。
最终,TIM2将以预定的周期和预分频器配置工作,并在计数器溢出时触发TIM2_IRQn中断,执行与中断相关的处理程序。
5、 TIM输出比较原理
输出比较(Output Compare,简称OC)是STM32定时器功能中的一种重要特性,用于生成PWM(脉冲宽度调制)信号或其他需要定时控制的输出信号。下面是关于输出比较的一些要点:
- 用途:输出比较主要用于生成PWM信号,其中包括控制信号的占空比和频率。除了PWM之外,它还可以用于产生其他类型的定时控制信号,如脉冲信号、方波信号等。
- 比较操作:输出比较的原理是将定时器的计数值(通常是CNT寄存器的值)与比较寄存器(通常是CCR寄存器)的值进行比较。根据比较的结果,可以执行以下操作:
- 当计数器的值小于CCR寄存器的值时,输出置1。
- 当计数器的值等于CCR寄存器的值时,输出置0。
- 当计数器的值大于CCR寄存器的值时,输出保持不变(可以是1或0,取决于配置)。
- 通道数量:每个高级定时器和通用定时器都拥有多个输出比较通道,通常有4个。这意味着你可以同时控制多个不同的输出信号。
- PWM波形生成:通过适当配置输出比较通道的CCR寄存器值,你可以生成具有不同占空比的PWM波形。这对于驱动电机、LED灯和其他需要精确控制的应用非常有用。
- 高级定时器功能:高级定时器(如TIM1和TIM8)的输出比较通道具有额外的功能,包括死区生成和互补输出。死区生成用于防止同一通道上的两个PWM信号同时处于高电平或低电平状态,以防止短路。互补输出用于产生互补的PWM信号,可用于驱动半桥或全桥电路。
CCR:Capture Compare,捕获比较寄存器。
脉冲宽度调制(PWM,Pulse Width Modulation)是一种用于控制模拟信号的技术,通常用于模拟电子电路中,特别是用于控制电机速度、LED亮度和音频信号等应用。以下是一些关于PWM的重要概念:
频率(Frequency):PWM信号的频率是指PWM周期的倒数,通常以赫兹(Hz)为单位表示。频率决定了PWM波形的周期,即PWM信号从低电平到高电平再到低电平的一个完整周期需要多少时间。频率一般在几千赫兹(kHz)到几十千赫兹(十几kHz或百kHz)之间。
占空比(Duty Cycle):占空比是PWM信号中高电平的持续时间与一个周期内的总时间之比。它表示了PWM信号中高电平的相对时间。占空比通常以百分比表示,例如,如果PWM的周期是10毫秒,而高电平持续时间是2毫秒,那么占空比为20%。
分辨率(Resolution):分辨率是指PWM信号占空比变化的精细程度,通常以位数表示。例如,8位分辨率的PWM可以将占空比分成256个不同的级别,每个级别之间的占空比差异是1/256,即约0.39%。分辨率越高,可以表示的占空比级别就越多,PWM信号的精度也就越高。
定时中断:在STM32定时器中,PWM的频率由定时中断的频率决定。通过调整定时器的预分频器、自动重装载值和计数模式,可以控制定时中断的频率,从而影响PWM信号的频率。
自动重装载值:自动重装载值(ARR,Auto-Reload Register)决定了PWM信号的周期。它表示PWM信号从低电平到高电平再到低电平的一个完整周期的时间。通过调整ARR的值,可以改变PWM信号的频率。
总之,PWM是一种强大的信号调制技术,用于控制模拟电路中的各种设备。通过调整频率和占空比,可以实现对输出信号的精确控制,以满足不同应用的需求。在STM32等微控制器中,PWM通常由定时器模块生成,可以根据需要进行配置和调整。
6、 通用定时器输出比较通道
REF:reference,参考信号
输出比较模式:
置有效电平:置高电平
置无效电平:置低电平
PWM模式1:常用向上计数的方式