PWM互补输出,以及死区时间计算

您所在的位置:网站首页 计算死亡时间的函数 PWM互补输出,以及死区时间计算

PWM互补输出,以及死区时间计算

2023-04-01 13:25| 来源: 网络整理| 查看: 265

本文基于野火例程进行解说

实验内容

本次实验输出一对互补的pwm波,且进行死区时间的计算说明。

代码

互补输出对应的定时器初始化代码: bsp_advance_tim.c

/** ****************************************************************************** * @file bsp_advance_tim.c * @author STMicroelectronics * @version V1.0 * @date 2015-xx-xx * @brief 高级控制定时器互补输出范例 ****************************************************************************** * @attention * * 实验平台:野火 STM32 F407 开发板 * 论坛 :http://www.firebbs.cn * 淘宝 :http://firestm32.taobao.com * ****************************************************************************** */ #include "./tim/bsp_advance_tim.h" TIM_HandleTypeDef TIM_TimeBaseStructure; TIM_OC_InitTypeDef TIM_OCInitStructure; __IO uint16_t ChannelPulse = 500; /** * @brief 配置TIM复用输出PWM时用到的I/O * @param 无 * @retval 无 */ static void TIMx_GPIO_Config(void) { /*定义一个GPIO_InitTypeDef类型的结构体*/ GPIO_InitTypeDef GPIO_InitStructure; /*开启定时器相关的GPIO外设时钟*/ ADVANCE_OCPWM_GPIO_CLK_ENABLE(); ADVANCE_OCNPWM_GPIO_CLK_ENABLE(); ADVANCE_BKIN_GPIO_CLK_ENABLE(); /* 定时器功能引脚初始化 */ GPIO_InitStructure.Pin = ADVANCE_OCPWM_PIN; GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; GPIO_InitStructure.Alternate = ADVANCE_OCPWM_AF; HAL_GPIO_Init(ADVANCE_OCPWM_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.Pin = ADVANCE_OCNPWM_PIN; GPIO_InitStructure.Alternate = ADVANCE_OCNPWM_AF; HAL_GPIO_Init(ADVANCE_OCNPWM_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.Pin = ADVANCE_BKIN_PIN; GPIO_InitStructure.Alternate = ADVANCE_BKIN_AF; HAL_GPIO_Init(ADVANCE_BKIN_GPIO_PORT, &GPIO_InitStructure); } /* * 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有 * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可, * 另外三个成员是通用定时器和高级定时器才有. *----------------------------------------------------------------------------- * TIM_Prescaler 都有 * TIM_CounterMode TIMx,x[6,7]没有,其他都有(基本定时器) * TIM_Period 都有 * TIM_ClockDivision TIMx,x[6,7]没有,其他都有(基本定时器) * TIM_RepetitionCounter TIMx,x[1,8]才有(高级定时器) *----------------------------------------------------------------------------- */ static void TIM_Mode_Config(void) { TIM_BreakDeadTimeConfigTypeDef TIM_BDTRInitStructure; // 开启TIMx_CLK,x[1,8] ADVANCE_TIM_CLK_ENABLE(); /* 定义定时器的句柄即确定定时器寄存器的基地址*/ TIM_TimeBaseStructure.Instance = ADVANCE_TIM; /* 累计 TIM_Period个后产生一个更新或者中断*/ //当定时器从0计数到999,即为1000次,为一个定时周期 TIM_TimeBaseStructure.Init.Period = 1000-1; // 高级控制定时器时钟源TIMxCLK = HCLK=168MHz // 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=1MHz TIM_TimeBaseStructure.Init.Prescaler = 168-1; // 采样时钟分频 TIM_TimeBaseStructure.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1; // 计数方式 TIM_TimeBaseStructure.Init.CounterMode=TIM_COUNTERMODE_UP; // 重复计数器 TIM_TimeBaseStructure.Init.RepetitionCounter=0; // 初始化定时器TIMx, x[1,8] HAL_TIM_PWM_Init(&TIM_TimeBaseStructure); /*PWM模式配置*/ //配置为PWM模式1 TIM_OCInitStructure.OCMode = TIM_OCMODE_PWM1; TIM_OCInitStructure.Pulse = ChannelPulse; TIM_OCInitStructure.OCPolarity = TIM_OCPOLARITY_HIGH; TIM_OCInitStructure.OCNPolarity = TIM_OCNPOLARITY_HIGH; TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_SET; TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET; //初始化通道1输出PWM HAL_TIM_PWM_ConfigChannel(&TIM_TimeBaseStructure,&TIM_OCInitStructure,TIM_CHANNEL_1); /* 自动输出使能,断路、死区时间和锁定配置 */ TIM_BDTRInitStructure.OffStateRunMode = TIM_OSSR_ENABLE; TIM_BDTRInitStructure.OffStateIDLEMode = TIM_OSSI_ENABLE; TIM_BDTRInitStructure.LockLevel = TIM_LOCKLEVEL_1; TIM_BDTRInitStructure.DeadTime = 0xff; TIM_BDTRInitStructure.BreakState = TIM_BREAK_ENABLE; TIM_BDTRInitStructure.BreakPolarity = TIM_BREAKPOLARITY_LOW; TIM_BDTRInitStructure.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE; HAL_TIMEx_ConfigBreakDeadTime(&TIM_TimeBaseStructure, &TIM_BDTRInitStructure); /* 定时器通道1输出PWM */ HAL_TIM_PWM_Start(&TIM_TimeBaseStructure,TIM_CHANNEL_1); /* 定时器通道1互补输出PWM */ HAL_TIMEx_PWMN_Start(&TIM_TimeBaseStructure,TIM_CHANNEL_1); } /** * @brief 初始化高级控制定时器定时,1s产生一次中断 * @param 无 * @retval 无 */ void TIMx_Configuration(void) { TIMx_GPIO_Config(); TIM_Mode_Config(); } /*********************************************END OF FILE**********************/

头文件: bsp_advance_tim.h

#ifndef __ADVANCE_TIM_H #define __ADVANCE_TIM_H #include "stm32f4xx.h" /* 定时器 */ #define ADVANCE_TIM TIM8 #define ADVANCE_TIM_CLK_ENABLE() __TIM8_CLK_ENABLE() /* TIM8通道1输出引脚 */ #define ADVANCE_OCPWM_PIN GPIO_PIN_6 #define ADVANCE_OCPWM_GPIO_PORT GPIOC #define ADVANCE_OCPWM_GPIO_CLK_ENABLE() __GPIOC_CLK_ENABLE() #define ADVANCE_OCPWM_AF GPIO_AF3_TIM8 /* TIM8通道1互补输出引脚 */ #define ADVANCE_OCNPWM_PIN GPIO_PIN_5 #define ADVANCE_OCNPWM_GPIO_PORT GPIOA #define ADVANCE_OCNPWM_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE() #define ADVANCE_OCNPWM_AF GPIO_AF3_TIM8 /* TIM8断路输入引脚 */ #define ADVANCE_BKIN_PIN GPIO_PIN_6 #define ADVANCE_BKIN_GPIO_PORT GPIOA #define ADVANCE_BKIN_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE() #define ADVANCE_BKIN_AF GPIO_AF3_TIM8 extern TIM_HandleTypeDef TIM_TimeBaseStructure; void TIMx_Configuration(void); #endif /* __ADVANCE_TIM_H */ 代码讲解 断路功能 //在初始化文件里这几句代码配置了断路功能的模式 TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_SET;//当空闲状态下PWM通道置高电平 TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET;//当空闲模状态下PWM互补通道置低电平 TIM_BDTRInitStructure.BreakState = TIM_BREAK_ENABLE;//开启断路功能 TIM_BDTRInitStructure.BreakPolarity = TIM_BREAKPOLARITY_LOW;//低电平断路 TIM_BDTRInitStructure.AutomaticOutput=TIM_AUTOMATICOUTPUT_ENABLE;//断路状态消失后,自动恢复输出

以上语句表示当断路功能对应的引脚输入变为低电平时,互补输出的功能就被禁止,此时变为空闲状态,而pwm对应的通道输出高电平,互补对应的通道变为低电平,而当断路功能对应的引脚变为高电平时,互补输出又再次出现。

死区时间计算请添加图片描述

请添加图片描述 通过上面两张图,就可以知道死区时间的计算公式了

下面列举出配置死区时间的代码

TIM_TimeBaseStructure.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//设置分频系数,详细看第一张图。 TIM_BDTRInitStructure.DeadTime = 0xff;//配置死区时间,具体计算看第二章图

开始计算,假设定时器的频率为165Mhz,且配置语句TIM_BDTRInitStructure.DeadTime = 0xff,则DTG[7:0]被写入11111111,则对应第四个计算方式,TIM_TimeBaseStructure.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1表示对定时器频率1分频,则此时tDTS=1*Tck_int = (1/165000000)s,此时代码计算公式 DT=(32+DTG[4:0])*Tdtg=(32+31)16(1/165000000)*1000000us=6us



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3