热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

本文基于野火例程进行解说实验内容

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

实验内容

本次实验输出一对互补的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)=1MHzTIM_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模式1TIM_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_TIM8extern 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


推荐阅读
  • 设计模式笔记12:迭代器模式(Iterator Pattern) ... [详细]
  • 本文深入探讨了企业级开发框架NHibernate和Spring.NET的关键特性之一——面向方面编程(AOP)。文章不仅介绍了AOP的基本概念及其如何增强面向对象编程(OOP),还详细说明了Spring.NET中AOP的具体应用,包括事务管理和自定义方面的实现。 ... [详细]
  • 本文介绍了如何在 Linux 系统上构建网络路由器,特别关注于使用 Zebra 软件实现动态路由功能。通过具体的案例,展示了如何配置 RIP 和 OSPF 协议,以及如何利用多路由器查看工具(MRLG)监控网络状态。 ... [详细]
  • 本文探讨了如何在Django中创建一个能够根据需求选择不同模板的包含标签。通过自定义逻辑,开发者可以在多个模板选项中灵活切换,以适应不同的显示需求。 ... [详细]
  • 本文介绍了NHibernate中通过定义接口和实现类来管理会话工厂的方法,包括接口的优势、模型文件夹的结构以及具体的代码示例。 ... [详细]
  • 首先说一下,这是我在CSDN上的第一个文章,其实这个账号早在几年前就申请了,不过当时只是为了下载一个资源,而且也不怎么懂信息技术相关的领域,后来就再也没怎么动过,直到今天我才开始使用这个账号 ... [详细]
  • 学习目的:1.了解android线程的使用2.了解主线程与子线程区别3.解析异步处理机制主线程与子线程:所谓主线程,在Windows窗体应用程序中一般指UI线程,这个是程序启动的时 ... [详细]
  • OpenWrt 是一款高度可定制的嵌入式 Linux 发行版,广泛应用于无线路由器等领域,拥有超过百个预装软件包。本文详细探讨如何在 OpenWrt 上通过 Luci 构建自定义模块,以扩展其功能。 ... [详细]
  • 一个产品数组拼图|集合 2 (O(1)空间) ... [详细]
  • databasesync适配openGauss使用指导书
    一、database-sync简介database-sync作为一种开源辅助工具,用于数据库之间的表同步,更确切的说法是复制,可以从一个数据库复制表到另一个数据库该工具支持的功能如 ... [详细]
  • 程序打印菱形 ... [详细]
  • 本文档提供了几个经典的Java编程示例,包括多线程处理、基本程序结构以及简单的逻辑运算,旨在帮助初学者更好地理解和掌握Java语言的核心特性。 ... [详细]
  • 本文探讨了如何利用自定义URI方案和注册表编辑,在Windows操作系统中实现从Web浏览器启动本地应用程序的方法,同时强调了这一过程中的安全考虑。 ... [详细]
  • 深入探讨配置文件的管理与优化
    尽管配置文件的重要性不言而喻,但其管理和安全性问题却常被忽视。本文将详细讨论配置文件的不同管理策略及其优缺点。 ... [详细]
  • 该问题探讨了将一个十进制数的每个数字分别提升至五次方后求和的情况,特别关注那些其五次方和等于自身的特殊数字。例如,1024的五次方和计算为1^5 + 0^5 + 2^5 + 4^5 = 1057。这类数字非常罕见,且数量有限。 ... [详细]
author-avatar
福田汽车-唐山万联
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有