外设高级定时器互补输出带死区控制实验

互补输出带死区控制介绍,H桥,通道介绍

本小节我们来学习使用高级定时器的互补输出带死区控制功能。对于刚接触这个知识的朋 友可能会问:什么是互补输出?还带死区控制?What?下面给大家简单说一下。

 上图中,CH1 输出黄色的 PWM,它的互补通道 CH1N 输出绿色的 PWM。通过对比,可以 知道这两个 PWM 刚好是反过来的,CH1 的 PWM 为高电平期间,CH1N 的 PWM 则是低电平, 反之亦然,这就是互补输出。

下面来看一下什么是带死区控制的互补输出?

上图中,CH1 输出的 PWM 和 CH1N 输出的 PWM 在高低电平转换间,插入了一段时间才 实现互补输出。这段时间称为死区时间,可以通过 DTG[7:0]位配置控制死区时间的长度,后面 会详细讲解如何配置死区时间。上图中,箭头指出的两段死区时间的长度是一样的,因为都是 由同一个死区发生器产生。

理解了互补输出和带死区控制的互补输出,下面来看一下带死区控制的互补输出有什么用? 带死区控制的互补输出经常被用于控制电机的 H 桥中,下面给大家画了一个 H 桥的简图: 

图 22.4.3 是 H 桥的简图,实际控制电机正反转的 H 桥会根据复杂些,而且更多的是使用 MOS 管,这里只是为了解释带死区控制的互补输出在 H 桥中的控制逻辑原理,大家理解原理 就行。上图的 H 桥搭建全部使用的是 NPN,并且导通逻辑都是基极为高电平时导通。如果 Q1 和 Q4 三极管导通,那么电机的电流方向是从左到右(假设电机正转);如果 Q2 和 Q3 三极管 导通,那么电机的电流方向是从右到左(假设电机反转)。上述就是 H 桥控制电机正反转的逻 辑原理。但是同一侧的三极管是不可以同时导通的,否则会短路,比如:Q1 和 Q2 同时导通或 者 Q3 和 Q4 同时导通,这都是不可取的。

下面大家想一下图 22.4.1 的 OC1(CH1)和 OC1N(CH1N)输出的 PWM 输入到图 22.4.3 的 H 桥中,会怎样?按理来说应该是 OC1N 输出高电平的时候,OC1 输出就是低电平,刚好 Q2 和 Q3 导通,电机的电流方向是从右到左(假设电机反转);反之,OC1 输出高电平的时候, OC1N 输出就是低电平,刚好 Q1 和 Q4 导通,电机的电流方向是从左到右(假设电机正转), 这似乎已经完美解决电机正反转问题了。实际上,元器件是有延迟特性的,比如:控制信号从 OC1 传导至电机,是要经过一定的时间的,复杂的 H 桥电路更是如此。由于元器件特性,就会 导致直接使用互补输出信号驱动 H 桥时存在短路现象。为了避免这种情况,于是就有了带死区 控制的互补输出来驱动 H 桥电路。如图 22.4.2 的死区时间就是为了解决元器件延迟特性的。用 户必须根据与输出相连接的器件及其特性(电平转换器的固有延迟、开关器件产生的延迟)来 调整死区时间。 

 死区时间计算

高级定时器互补输出带死区控制实验配置步骤 

 

1. HAL_TIMEx_ConfigBreakDeadTime 函数 

定时器的断路和死区时间配置初始化函数,其声明如下:

HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim,
 TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig);

⚫ 函数描述: 用于初始化定时器的断路(即刹车)和死区时间。

⚫ 函数形参: 形参 1 是 TIM_HandleTypeDef 结构体类型指针变量,基本定时器的时候已经介绍。 形参 2 是 TIM_BreakDeadTimeConfigTypeDef 结构体类型指针变量,用于配置断路和死区参数,其定义如下:

typedef struct
{
     uint32_t OffStateRunMode; /* 运行模式下的关闭状态选择 */
     uint32_t OffStateIDLEMode; /* 空闲模式下的关闭状态选择 */
     uint32_t LockLevel; /* 寄存器锁定配置 */
     uint32_t DeadTime; /* 死区时间设置 */
     uint32_t BreakState; /* 断路(即刹车)输入使能控制 */
     uint32_t BreakPolarity; /* 断路输入极性 */
     uint32_t BreakFilter; /* 断路输入滤波器 */
     uint32_t AutomaticOutput; /* 自动恢复输出使能控制 */
} TIM_BreakDeadTimeConfigTypeDef;

⚫ 函数返回值: HAL_StatusTypeDef 枚举类型的值。

2. HAL_TIMEx_PWMN_Start 函数

定时器的互补输出启动函数。其声明如下:

HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, 
                                            uint32_t Channel);

⚫ 函数描述: 该函数用于启动定时器的互补输出。

⚫ 函数形参: 形参 1 是 TIM_HandleTypeDef 结构体类型指针变量,用于配置定时器基本参数。 形参 2 是定时器通道,范围:TIM_CHANNEL_1 到 TIM_CHANNEL_4。

⚫ 函数返回值: HAL_StatusTypeDef 枚举类型的值。

代码 

atim.c

#include "./BSP/ATIM/atim.h"

TIM_HandleTypeDef g_timx_cplm_pwm_handle;/* 定时器x句柄 */
TIM_BreakDeadTimeConfigTypeDef g_sbreak_dead_time_config = {0};/* 死区时间设置 */

void atim_timx_cplm_pwm_init(uint16_t psc, uint16_t arr)
{
    TIM_OC_InitTypeDef tim_oc_cplm_pwm = {0};
    
    g_timx_cplm_pwm_handle.Instance = TIM1;
    g_timx_cplm_pwm_handle.Init.Prescaler = psc;
    g_timx_cplm_pwm_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
    g_timx_cplm_pwm_handle.Init.Period = arr;
    g_timx_cplm_pwm_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4;
    g_timx_cplm_pwm_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; /* 使能影子寄存器TIMx_ARR */
    HAL_TIM_PWM_Init(&g_timx_cplm_pwm_handle);
    
    tim_oc_cplm_pwm.OCMode = TIM_OCMODE_PWM1;
    tim_oc_cplm_pwm.OCPolarity = TIM_OCPOLARITY_HIGH;/* OCy 高电平有效 */
    tim_oc_cplm_pwm.OCNPolarity = TIM_OCNPOLARITY_HIGH;/* OCyN 高电平有效 */
    tim_oc_cplm_pwm.OCIdleState = TIM_OCIDLESTATE_RESET;/* 当MOE=0,OCx=0 */
    tim_oc_cplm_pwm.OCNIdleState = TIM_OCNIDLESTATE_RESET;/* 当MOE=0,OCxN=0 */
    HAL_TIM_PWM_ConfigChannel(&g_timx_cplm_pwm_handle, &tim_oc_cplm_pwm, TIM_CHANNEL_1);
    
    g_sbreak_dead_time_config.OffStateRunMode = TIM_OSSR_DISABLE;
    g_sbreak_dead_time_config.OffStateIDLEMode = TIM_OSSI_DISABLE;
    g_sbreak_dead_time_config.LockLevel = TIM_LOCKLEVEL_OFF;
    g_sbreak_dead_time_config.BreakState = TIM_BREAK_ENABLE;
    g_sbreak_dead_time_config.BreakPolarity = TIM_BREAKPOLARITY_HIGH;/* 刹车输入有效信号极性为高 */
    g_sbreak_dead_time_config.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;/* 使能AOE位,允许刹车结束后自动恢复输出 */
    HAL_TIMEx_ConfigBreakDeadTime(&g_timx_cplm_pwm_handle, &g_sbreak_dead_time_config);
    
     HAL_TIM_PWM_Start(&g_timx_cplm_pwm_handle, TIM_CHANNEL_1);/* 使能OCy输出 */
     HAL_TIMEx_PWMN_Start(&g_timx_cplm_pwm_handle, TIM_CHANNEL_1);/* 使能OCyN输出 */
}

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM1)
    {
        GPIO_InitTypeDef gpio_init_struct = {0};
        __HAL_RCC_TIM1_CLK_ENABLE();
        __HAL_RCC_GPIOE_CLK_ENABLE();
        
        gpio_init_struct.Pin = GPIO_PIN_9;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOE, &gpio_init_struct);
        
        gpio_init_struct.Pin = GPIO_PIN_8;
        HAL_GPIO_Init(GPIOE, &gpio_init_struct);
        
        gpio_init_struct.Pin = GPIO_PIN_15;
        HAL_GPIO_Init(GPIOE, &gpio_init_struct);
        
        __HAL_RCC_AFIO_CLK_ENABLE();
        __HAL_AFIO_REMAP_TIM1_ENABLE();/* 映射定时器IO,PE不是本例程所用定时器的默认IO,需要复用 */
    }
}

void atim_timx_cplm_pwm_set(uint16_t ccr, uint16_t dtg)
{
    __HAL_TIM_SET_COMPARE(&g_timx_cplm_pwm_handle, TIM_CHANNEL_1, ccr);/* 设置比较寄存器 */
    
    g_sbreak_dead_time_config.DeadTime = dtg;/* 死区时间设置 */
    HAL_TIMEx_ConfigBreakDeadTime(&g_timx_cplm_pwm_handle, &g_sbreak_dead_time_config);
}



main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/ATIM/atim.h"

int main(void)
{
    uint8_t t;
    
    HAL_Init();                         /* 初始化 HAL 库 */
    sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    delay_init(72);                     /* 延时初始化 */
    usart_init(115200);                 /* 串口初始化为115200 */
    
    led_init();
    atim_timx_cplm_pwm_init(72 - 1, 1000 - 1);
    atim_timx_cplm_pwm_set(700 - 1, 100);
    
    while(1)
    {
        
        
        t++;
        if(t > 20)
        {
            t = 0;
            LED0_TOGGLE();
        }
        delay_ms(10);
    }
}




注意:因为 PE8/PE9/PE15, 默 认并不是 TIM1 的复用功能脚, 必须开启完全重映射。

第一部分,使能定时器和相关通道对应的 GPIO 时钟,以及初始化相关 IO 引脚。

第二部分,通过 HAL_TIM_PWM_Init 函数初始化定时器的 ARR 和 PSC 等参数。

第三部分,通过 HAL_TIM_PWM_ConfigChannel 函数设置 PWM 模式 1、输出极性,以及 输出空闲状态等。

第四部分,通过 HAL_TIMEx_ConfigBreakDeadTime 函数配置断路功能。

最后一定记得要调用 HAL_TIM_PWM_Start 函数和 HAL_TIMEx_PWMN_Start 函数启动通 道输出和互补通道输出。

通过重新调用 HAL_TIMEx_ConfigBreakDeadTime 函数设置死区时间,注意这里的 g_sbreak_dead_time_config 是全局结构体变量,在 atim_timx_cplm_pwm_init 函数已经初始化其 他结构体成员了,这里只是对 DeadTime 成员(死区时间)配置。

先看 atim_timx_cplm_pwm_init(1000 - 1, 72 - 1)这个语句,这两个形参分别设置自动重载寄 存器的值为 999,以及定时器预分频器寄存器的值为 71。先看预分频系数,我们设置为 72 分 频,定时器 1 的时钟源频率等于 APB2 总线时钟频率,即 72MHz,可以得到计数器的计数频率 是 1MHz,即每 1us 计数一次。再到自动重载寄存器的值为 999 决定的是 PWM 的频率(周期), 可以得到 PWM 的周期为(999+1)*1us = 1000us = 1ms。边沿对齐模式下,使用 PWM 模式 1 或 者 PWM 模式 2,得到的 PWM 周期是定时器溢出时间。这里的 1ms,也可以直接通过定时器溢 出时间计算公式 Tout= ((arr+1)*(psc+1))/Tclk 得到。

调用 atim_timx_cplm_pwm_set(700, 100) 这个语句,相当于设置捕获/比较寄存器的值为 700, DTG[7:0]的值为 100。通过计算可以得到 PWM 的占空比为 70%,死区时间为 5.56us。根据 PWM 生成原理分析,以及我们在 atim_timx_cplm_pwm_init 函数 配置 PWM 模式 1、OCy 输出极性为高,占空比的计算很简单,可以由700/1000 得到。

互补输出的 PWM 波的正脉宽减去正常的 PWM 的负脉宽的值除以 2 就是死区 时间,也可以是正常的 PWM 的正脉宽减去互补输出的 PWM 波的负脉宽的值除以 2。我们使用 第一种方法得到:死区时间 =(705 – 694)/2 us=5.5us。与我们理论到的的值 5.56us 基本一样, 这样的误差是正常的。

刹车功能验证:当给刹车输入引脚(PE15)接入高电平(这里直接用杜邦线连接 PE15 到 3.3V)时,就会进行刹车,即 PE9 和 PE8 停止输出 PWM 波,MOE 位被硬件清零。我们设置当 MOE=0 时,OCx=0、OCxN=0, 即 PE9 和 PE8 都是输出低电平。

另外因为我们使能了 AOE 位(即把该位置 1),如果刹车输入为无效极性时,MOE 位在发 生下一个更新事件时自动置 1,恢复运行模式(即继续输出 PWM)。因此当停止给 PE15 接入低 电平(拔掉之前连接的杜邦线),PWM 会自动恢复输出。

### 回答1: STM32高级定时器(PWM互补输出)是指通过使用STM32系列微控制器的高级定时器模块,以实现PWM互补输出功能。 PWM互补输出是一种常见的电路控制技术,可以用于调节电压、电流或动力系统中的电机速度和方向等应用。这种技术通过在一个周期内交替地激活一个信号的正向和负向来实现输出STM32系列微控制器的高级定时器模块支持多通道的PWM输出功能,能够同时控制多个输出通道的PWM信号。而在PWM互补输出模式下,这些通道中的一对通道将被配置为互补输出,在一个周期内交替激活正向和负向信号。 通过使用PWM互补输出,我们可以实现更高级别的电机控制,比如进行电机的前进和倒退运动。在使用PWM互补输出时,我们需要定义适当的参数,如PWM周期、占空比等,来实现所需的电路控制。 通过配置和编程STM32高级定时器的寄存器和相关寄存器以及使用适当的算法和控制策略,我们可以在STM32系列微控制器上实现PWM互补输出。这种技术在许多电机控制应用中具有广泛的应用前景,如无人机、机器人、电动车等。 总之,STM32高级定时器的PWM互补输出功能是一种非常有用的技术,可以在电机控制和其他电路控制应用中实现更高级别和更灵活的功能。 ### 回答2: STM32高级定时器的PWM互补输出功能是指可以通过配置定时器工作模式和输出比较通道来实现互补输出的PWM波形。 在互补输出模式下,我们需要设置两个定时器输出通道作为互补输出。其中一个通道称为主输出通道,另一个通道称为从输出通道。两个通道的输出互补的,也就是一个通道在高电平时,另一个通道处于低电平。 首先,我们需要选择一个高级定时器(如TIM1或TIM8)来使用。然后,设置定时器的工作模式为互补模式。在这种模式下,主输出通道用于产生PWM信号,而从输出通道则产生互补的PWM信号。 接下来,我们需要设置定时器输出比较通道。通过设置主输出通道和从输出通道的比较值,可以控制PWM波形的占空比和频率。我们可以使用定时器的寄存器来设置通道的比较值,以达到我们期望的PWM波形。 最后,我们还可以设置互补输出的极性,以及死区时间来避免互补输出通道之间的冲突。通过配置极性,我们可以选择保持主输出通道为正电平,还是保持从输出通道为正电平。而通过设置死区时间,可以在互补输出切换时增加一段延时,以防止输出短路。 总的来说,STM32高级定时器的PWM互补输出功能可以通过配置定时器工作模式、设置输出比较通道、设置极性和死区时间等参数来实现。这种互补输出功能可以应用于很多领域,比如电机控制、电源控制等需要互补PWM的应用场景。 ### 回答3: STM32高级定时器提供了PWM互补输出功能,可以方便地实现PWM信号的互补输出。PWM互补输出是指同时输出两个互补的PWM波形,一个为高电平,一个为低电平。通过互补输出,可以达到高精度的控制,尤其适合用于驱动电机等需要精确控制的应用。 在STM32高级定时器中,实现PWM互补输出需要以下步骤: 1. 配置定时器的工作模式为PWM模式,并设置计数器的自动重载值。通过设置自动重载值,可以决定PWM信号的周期。 2. 配置定时器输出比较通道,设置PWM信号的占空比。通过设置比较寄存器的值,可以决定PWM信号的高电平持续时间。 3. 配置另一个输出比较通道,设置互补PWM信号的占空比。通过设置比较寄存器的值,可以决定互补PWM信号的低电平持续时间。 4. 配置定时器互补输出使能位。通过使能互补输出,可以使得两个比较通道的PWM信号互补输出。 通过以上步骤,就可以实现STM32高级定时器的PWM互补输出。需要注意的是,在配置互补输出时,还需要设置极性,决定PWM信号和互补PWM信号的极性关系。 PWM互补输出在工业控制、机器人和无人机等领域有广泛的应用。通过高级定时器的PWM互补输出功能,可以实现精确的电机控制、灯光控制等应用,提高系统的稳定性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值