国产MCU学习Day22——CW32F030C8T6 ATIM高级定时器:PWM波形生成全攻略

每日更新教程,评论区答疑解惑,小白也能变大神!"

目录

一.高级定时器(ATIM)

二.案例-ATIM的输出比较功能,生成PWM波形

初始化配置

时钟配置

GPIO配置

中断控制器配置

中断服务函数

关键点

一.高级定时器(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);
    }
}

关键点:

  1. 主函数:包含定时器初始化、PWM配置和启动流程。
  2. RCC配置:时钟源选择和外设时钟使能。
  3. GPIO配置:引脚复用为定时器输出功能。
  4. NVIC配置:中断优先级和使能设置。
  5. 中断回调:实现PWM占空比动态调整(呼吸灯效果)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值