每日更新教程,评论区答疑解惑,小白也能变大神!"
目录
一.高级定时器(ATIM)
1.1概述
- 高级定时器 (ATIM) 由一个 16 位的自动重载计数器和 7 个比较单元组成,并由一个可编程的预分频器驱动。ATIM 支持 6 个独立的捕获 / 比较通道,可实现 6 路独立 PWM 输出或 3 对互补 PWM 输出或对 6 路输入进行捕获。可 用于基本的定时 / 计数、测量输入信号的脉冲宽度和周期、产生输出波形(PWM、单脉冲、插入死区时间的互补 PWM 等)。
1.2主要特性
- 16 位向上、向下、向上 / 向下自动装载计数器
- 6 个独立通道输入捕获和输出比较
- PWM 输出,边沿或中央对齐模式
- 死区时间可编程的互补 PWM 输出
- 刹车功能
- 单脉冲模式输出
- 正交编码计数功能
- 支持中断和事件:
- ‒ 计数器上溢、下溢
- ‒ 捕获、比较事件
- ‒ 捕获数据丢失
- ‒ 刹车事件
- ‒ 更新事件
- ‒ 触发事件
1.3功能框图
- 通过 16 位计数器和 7 路比较单元的结合,可以实现输入捕获、输出比较的功能,可以用来测量输入信号的脉宽、 周期,可以输出 PWM 波形。
1.4输入捕获功能
- 边沿对齐模式和中央对齐模式都支持输入捕获功能。设置通道 x 控制寄存器 ATIM_CHxCR 的 CSy 位域为 1,使通 道 CHxy(x = 1 ~ 3,y = A,B)工作在输入捕获模式,可通过软件或硬件触发输入捕获。 软件触发:设置 ATIM_CHxCR.CCGy 为 1 时,立即软件触发一次捕获,主计数寄存器 ATIM_CNT 的值被锁存到对 应通道的比较捕获寄存器 ATIM_CHxCCRy 中,完成一次捕获,捕获完成后 CCGy 位被硬件自动清零。 硬件触发:当检测到通道 CHxy 上的有效边沿后,主计数寄存器 ATIM_CNT 的值被锁存到对应通道的比较捕获寄 存器 ATIM_CHxCCRy 中,完成一次捕获。触发捕获的有效边沿通过 ATIM_CHxCR 寄存器的 BKSy 位域来选择, 如下表所示:
1.5PWM 输入模式
- PWM 输入模式是输入捕获模式的一个应用。设置通道 x 控制寄存器 ATIM_CHxCR 的 BKSy 位域为 0x03,使定时 器在 PWM 输入信号的上升沿和下降沿都发生捕获,经过三次捕获后,可计算出 PWM 信号的脉宽和周期。 CH3B 通道的 PWM 信号测量示意图如下图所示:
1.6输入捕获触发源
- ATIM 的输入捕获触发源可选择外部 CHxy 引脚输入信号,或者内部触发 TS 信号。
- 通道 CH2A、CH2B、CH3A、CH3B 的输入捕获只能选择对应的外部 GPIO 引脚输入,可通过滤波寄存器 ATIM_FLTR 的 OCMxyFLTxy 位域进行通道滤波设置,通过 ATIM_CHxCR.BKSy 位域进行相位的设置。
- ATIM 的 CH1 是一个具有高级功能的输入通道,输入端 CH1A、CH1B 既可用作触发捕获,又可用作主计数器的触 发启动。
- CH1A 的输入捕获由主从模式控制寄存器 ATIM_MSCR 的 IA1S 位域确定,可选择 CH1A 输入或 CH1A、CH2A、 CH3A 的异或输入。
- 当设置 ATIM_MSCR.IA1S 为 0 时选择 CH1A 输入,可通过 ATIM_FLTR.OCM1AFLT1A 设置通道滤波,通过 ATIM_CH1CR.BKSA 设置相位;设置 ATIM_MSCR.IA1S 为 1 时选择 CH1A、CH2A、CH3A 的异或输入,该特性 用于连接霍尔传感器。
- CH1B 的输入捕获由主从模式控制寄存器 ATIM_MSCR 的 IB1S 位域确定,可选择 CH1B 输入或内部触发 TS 信号。 当设置 ATIM_MSCR.IB1S 为 0 时选择 CH1B 输入,可通过 ATIM_FLTR.OCM1BFLT1B 设置通道滤波,通过 ATIM_CH1CR.BKSB 设置相位;
- 当设置 ATIM_MSCR.IB1S 为 1 时选择内部触发 TS 信号,通过 ATIM_MSCR.TS 配置 TS 信号的来源,如下表所示:
1.9输出比较功能
- 设置通道 x 控制寄存器 ATIM_CHxCR 的 CSy 位域为 0,使通道 CHxy 工作在输出比较模式。在输出比较模式下, 将计数寄存器 ATIM_CNT 的值与对应通道 CHxy 的比较捕获寄存器 ATIM_CHxCCRy 的值相比较,当两者匹配时, 比较捕获通道 CHxy 输出为可设定的电平状态。
- 比较通道的输出状态由 ATIM_FLTR 寄存器的 OCMxyFLTxy 位域设置,如下表所示:
- ATIM_FLTR 寄存器中的输出极性控制位 CCPxy,可设置 CHxy 的输出极性。 当发生比较匹配时,硬件将通道比较匹配中断标志位 ATIM_ISR.CxyF 置位,同时:
- 如果允许中断, 即 ATIM_CHxCR.CIEy 为 1,将产生中断请求。
- 如果允许触发 DMA,即 ATIM_MSCR.CCDS 为 0,比较匹配触发一次 DMA 请求。
- 如果允许使能 DMA,即 ATIM_CHxCR.CDEy 为 1,比较匹配使能 DMA。
- 如果允许触发 ADC,即 ATIM_TRIG.ADTE为 1,且 ATIM_TRIG.CMxyE为 1,比较匹配将触发一次 ADC转换请求。 比较捕获寄存器 ATIM_CHxCCRy 具有缓存功能,通过 ATIM_CHxCR 寄存器的 BUFEy 位选择是否使用缓存功能。 当 ATIM_CHxCR.BUFEy 为 0 时,禁止通道 CHxy 的比较缓存功能,可在任意时候通过软件更新 ATIM_CHxCCRy 寄存器,更新值立即生效并影响输出波形;当 ATIM_CHxCR.BUFEy 为 1 时,使能通道 CHxy 的比较缓存功能,更 新 ATIM_CHxCCRy 寄存器不会立即更新缓存寄存器,仅当发生更新事件 UEV 时才会将 ATIM_CHxCCRy 寄存器的 值更新到缓存寄存器中。
1.10编程示例
- 如何在 CH1A 输入信号的上升沿时捕获计数器的值到 ATIM_CH1CCRA 寄存器中,
- 步骤如下:
- 步骤 1:设置 SYSCTRL_APBEN2.ATIM 位为 1,打开 ATIM 模块;
- 步骤 2:设置寄存器 ATIM_CR 的 MODE 位为 0x02,使 ATIM 的计数模式为边沿对齐模式,以便 ATIM 可以工作在 输入捕获模式;
- 步骤 3:设置寄存器 ATIM_CH1CR 的 CSA 位为 0x01,配置 CH1A 为输入捕获模式;
- 步骤 4:设置寄存器 ATIM_CH1CR 的 BKSA 位为 0x01,配置 CH1A 上升沿捕获;
- 步骤 5:根据输入信号的特点,设置 ATIM_FLTR 寄存器的 FLT1A 位,配置输入滤波器为所需的带宽;
- 步骤 6:设置 ATIM_ICR 寄存器的相关位为 0,清除标志位,防止之前设置对本次运行结果的影响; 步骤 7:根据输入信号的特点,设置 ATIM_ARR 寄存器的值,选择合适的自动重载值;
- 步骤 8:设置 ATIM_CR 寄存器的 EN 位为 0x01,允许捕获计数器的值到捕获寄存器中;
- 步骤 9:如果需要,通过设置 ATIM_CH1CR 寄存器中的 CIEA 位使能相关中断请求,通过设置 ATIM_CH1CR 寄存 器中的 CDEA 位允许 DMA 请求。
PWM 输入
- 如何测量从 CH3B 通道输入的 PWM 信号的脉宽和周期,
- 步骤如下:
- 步骤 1:设置 SYSCTRL_APBEN2.ATIM 位为 1,打开 ATIM 模块;
- 步骤 2:设置寄存器 ATIM_CR 的 MODE 位为 0x02,使 ATIM 的计数模式为边沿对齐模式,以便 ATIM 可以工作在 输入捕获模式;
- 步骤 3:设置寄存器 ATIM_CH3CR 的 CSB 位为 0x01,配置 CH3B 为输入捕获模式;
- 步骤 4:设置寄存器 ATIM_CH3CR 的 BKSB 位为 0x11,配置 CH3B 上升沿 / 下降沿捕获;
- 步骤 5:根据输入信号的特点,设置 ATIM_FLTR 寄存器的 FLT3B 位,配置输入滤波器为所需的带宽;
- 步骤 6:设置 ATIM_ICR 寄存器的相关位为 0,清除标志位,防止之前设置对本次运行结果的影响;
- 步骤 7:根据输入信号的特点,设置 ATIM_ARR 寄存器的值,选择合适的自动重载值;
- 步骤 8:设置 ATIM_CR 寄存器的 EN 位为 0x01,允许捕获计数器的值到捕获寄存器中;
- 步骤 9:如果需要,通过设置 ATIM_CH3CR 寄存器中的 CIEA 位允许相关中断请求;
- 步骤 10:等待捕获发生三次,每次捕获发生后读取 ATIM_CH3CCRB 寄存器中捕获的数值,清除捕获中断标志位;
- 步骤 11:根据三次读到的 ATIM_CH3CCRB 寄存器的值,可得到 PWM 的周期为第 3 次值 - 第 1 次值,PWM 的脉 宽为第 3 次值 - 第 1 次值或为第 2 次值 - 第 1 次值。
输出比较功能
- 输出比较模式的配置步骤:
- 步骤 1:选择计数器时钟(内部、外部、预分频因子);
- 步骤 2:将相应的数据写入 ATIM_ARR 和 ATIM_CHxCCRy 寄存器中;
- 步骤 3:如果要产生一个中断请求,设置 ATIM_CHxCR 寄存器中的 CIEy 位;
- 步骤 4:选择输出模式,如需要翻转输出,则设置 ATIM_FLTR.OCMxy = 0x4;
- 步骤 5:设置 ATIM_CHxCR 寄存器中的 CSy 位,使相应的通道作为比较输出使用;
- 步骤 6:清除相关中断标志;
- 步骤 7:设置 ATIM_FLTR 寄存器中的 CCPxy 位,选择需要的输出相位;
- 步骤 8:设置 ATIM_CR 寄存器中的 EN 位,启动计数器。
二.案例-ATIM的输出比较功能,生成PWM波形
初始化配置
int32_t main(void)
{
// 定义ATIM(高级定时器)初始化结构体
ATIM_InitTypeDef ATIM_InitStruct;
ATIM_OCInitTypeDef ATIM_OCInitStruct;
// 系统时钟配置
RCC_Configuration();
// GPIO引脚配置
GPIO_Configuration();
// 中断控制器配置
NVIC_Configuration();
LogInit();
printf("ATIM Initial...\n");
// ATIM基础参数配置
ATIM_InitStruct.BufferState = DISABLE; // 禁用缓冲
ATIM_InitStruct.ClockSelect = ATIM_CLOCK_PCLK; // 选择PCLK作为时钟源
ATIM_InitStruct.CounterAlignedMode = ATIM_COUNT_MODE_EDGE_ALIGN; // 边沿对齐模式
ATIM_InitStruct.CounterDirection = ATIM_COUNTING_UP; // 向上计数
ATIM_InitStruct.CounterOPMode = ATIM_OP_MODE_REPETITIVE; // 重复计数模式
ATIM_InitStruct.OverFlowMask = DISABLE; // 关闭溢出掩码
ATIM_InitStruct.Prescaler = ATIM_Prescaler_DIV8; // 预分频8(1MHz计数时钟)
ATIM_InitStruct.ReloadValue = 9999; // 重载值(10ms溢出周期)
ATIM_InitStruct.RepetitionCounter = 0; // 重复计数器清零
ATIM_InitStruct.UnderFlowMask = DISABLE; // 关闭下溢掩码
ATIM_Init(&ATIM_InitStruct); // 初始化ATIM
// 输出比较(OC)参数配置
ATIM_OCInitStruct.BufferState = ENABLE; // 启用输出缓冲
ATIM_OCInitStruct.OCDMAState = DISABLE; // 禁用DMA
ATIM_OCInitStruct.OCInterruptSelect = ATIM_OC_IT_UP_COUNTER; // 向上计数时触发中断
ATIM_OCInitStruct.OCInterruptState = ENABLE; // 启用输出比较中断
ATIM_OCInitStruct.OCMode = ATIM_OCMODE_PWM1; // PWM模式1
ATIM_OCInitStruct.OCPolarity = ATIM_OCPOLARITY_NONINVERT; // 非反相极性
ATIM_OC2BInit(&ATIM_OCInitStruct); // 初始化OC2B通道
// 中断与PWM输出配置
ATIM_ITConfig(ATIM_CR_IT_OVE, ENABLE); // 启用溢出中断
ATIM_CH2Config(ATIM_CHxB_CIE, ENABLE); // 启用通道2B中断
ATIM_SetCompare2B(0); // 初始占空比为0
ATIM_Cmd(ENABLE); // 启动定时器
ATIM_CtrlPWMOutputs(ENABLE); // 启用PWM输出
printf("ATIM is running.\n");
while (1) {}
}
时钟配置
void RCC_Configuration(void)
{
RCC_HSI_Enable(RCC_HSIOSC_DIV6); // 启用HSI时钟并6分频
__RCC_ATIM_CLK_ENABLE(); // 启用ATIM时钟
__RCC_GPIOB_CLK_ENABLE(); // 启用GPIOB时钟
}
GPIO配置
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.IT = GPIO_IT_NONE; // 无中断
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出模式
GPIO_InitStruct.Pins = GPIO_PIN_14; // 配置PB14引脚
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 高速模式
PB14_AFx_ATIMCH2B(); // 将PB14复用为ATIM通道2B
GPIO_Init(CW_GPIOB, &GPIO_InitStruct); // 初始化GPIOB
}
中断控制器配置
void NVIC_Configuration(void)
{
__disable_irq(); // 全局禁用中断
NVIC_EnableIRQ(ATIM_IRQn); // 启用ATIM中断通道
__enable_irq(); // 全局启用中断
}
中断服务函数
void ATIM_IRQHandlerCallBack(void)
{
static uint16_t duration = 0; // PWM占空比变量
static uint8_t cnt = 1; // 溢出计数变量
static uint8_t dir = 0; // 方向标志(0:增加,1:减少)
// 溢出中断处理
if (ATIM_GetITStatus(ATIM_IT_OVF))
{
ATIM_ClearITPendingBit(ATIM_IT_OVF); // 清除溢出中断标志
if (cnt++ > 10) // 每10次溢出调整一次占空比
{
cnt = 1;
if (!dir) // 方向判断
{
duration += 200; // 占空比增加200
if (duration >= 10000) // 达到最大值时反转方向
{
dir = 1;
}
}
else
{
duration -= 200; // 占空比减少200
if (duration == 0) // 达到最小值时反转方向
{
dir = 0;
}
}
ATIM_SetCompare2B(duration); // 更新PWM占空比
}
}
// 通道2B中断处理(仅清除标志)
if (ATIM_GetITStatus(ATIM_IT_C2BF))
{
ATIM_ClearITPendingBit(ATIM_IT_C2BF);
}
}
关键点:
- 主函数:包含定时器初始化、PWM配置和启动流程。
- RCC配置:时钟源选择和外设时钟使能。
- GPIO配置:引脚复用为定时器输出功能。
- NVIC配置:中断优先级和使能设置。
- 中断回调:实现PWM占空比动态调整(呼吸灯效果)。