主题中讨论的其他器件: C2000WARE、 SysConfig
大家好、我不熟悉微控制器编程。 我使用: TMS320F28379D. CCS 上执行代码。 我希望 在 F2837xD 上以向上计数模式在有效复杂模式下以50%占空比生成 PWM 信号(高分辨率)、并生成死区。
当死区被停用(HRPE 打开)时、PWM 信号在50%占空比下正常工作。 但当死区打开时、PWM 信号不稳定。
死区有两种情况:
- 首先,当高分辨率周期被激活且 TBPRDHR=0 <<8 信号是稳定的、死区在工作。 示例:period=210ns、所以 TBPRD=20、TBPRDHR=0和 105ns 的占空比。
第二,当高分辨率周期被激活且 TBPRDHR 非零时,信号不稳定。 示例:周期206ns、所以 TBPRD = 19、TBPRDHR = 0.6<<8、占空比= 103ns。
我观察到了10ns 的变化(1 TBCLK)。 我还观察到 EPwm1B 信号稳定、但当触发器在 EPwm1B 通道上时、EPw1A 信号不稳定。 但 EPw1A 的通道上没有、两个通道都不稳定。
我不知道如何使信号稳定。
提前感谢您的帮助。
以下是信号和差异的照片(香奈儿1 : Epwm1B 和香奈儿2 : Epwm1A ),图片代表一个 PWM 信号206ns 周期,双周期50%和死区30%的死区时间的死区时间等(30.9ns):
连续信号采集: 
单次采集 :


以下是我的完整代码、如果它有所帮助:
#include "F28x_Project.h"
#include "F2837xD_DEVICE.h"
#include "F2837xD_examples.h"
#include "F2837xD_ePWM_definites.h" //初始化定义
#include "SFO_v8.h"
#include "board.h"
#包含
float periodeNANOsec = 206; //在 NANOSECONDE 边缘
浮点占空比= 0.5;
浮点 dutyDB = 0.30; //DN (ns)= dutyDB * period/2
//---------------- DEFINITION -------------- //
#define LAST_EPWM_INDEX 4
//---------------- VARIABLE ---------------- //
uint16_t PRD1_HR;
uint16_t FED;
uint16_t FEDHR;
uint16_t PRD;
uint16_t CMP;
uint16_t CMHR;
//---------------- GLOBAL ------------------------ //
int MEP_ScaleFactor;
易失性结构 ePWM_regs *ePWM[]={0、&EPwm1Regs、&EPwm2Regs、&EPwm3Regs};
uint16_t 状态;
浮点 DBns;
//--appel de fonction--//
void PRD_CMP_DB_calculation (float32_t periode、float32_t Duty、float32_t dutyDB); //计算 PRD、CMP 和 DB 值(高分辨率)
void initGPIO (void); //GPIO 初始化
void initPWM (void); //pwm 初始化
//***** 代码主体***** //
int main()
{
PRD_CMP_DB_calculation (PeriodeNANOsec、dutycycle、dutyDB);
DBns = dutyDB * PeriodNANOsec/2;
//初始化控制和模拟子系统的系统控制
//启用外设时钟
EALLOW;
InitSysCtrl();
EDIS;
//通过所有 PWM 实现 EPWM1A 和 EPWM1B
initGPIO();
Dint;
//将 PIE 控制寄存器初始化为默认状态。
//默认状态是所有 PIE 中断都被禁用并且标志
//被清除。
InitPieCtrl();
//禁用 CPU 中断并清除所有 CPU 中断标志:
EALLOW;
IER = 0x0000;
IFR = 0x0000;
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使中断
//在本例中未使用。 这对于调试十分有用。
//在 F2837xD_DefaultIsr.c 中可找到 shell ISR 例程。
//此函数可以在 F2837xD_PieVect.c 中找到。
InitPieVectTable();
//启用全局中断和更高优先级的实时调试事件:
EINT; //启用全局中断 INTM
ERTM; //启用全局实时中断 DBGM
//调用 SFO()用校准的 MEP_ScaleFactor 更新 HRMSTEP 寄存器。
//在启用之前必须使用比例因子值填充 HRMSTEP
//高分辨率周期控制。
while (status == SFO_Incomplete)
{
Status = SFO(); // SFO 函数返回2 (如果发生错误)以及 MEP 的数量
if (STATUS == SFO_ERROR) //步进/粗步进超过最大值255。
{
ESTOP0;
}
}
SYSCTL_disablePeripheral (SYSCTL_Periph_CLK_TBCLKSYNC);
initPWM();
SYSCTL_enablePeripheral (SYSCTL_Periph_CLK_TBCLKSYNC);
uint32_t i;
while (1)
{
for (I=1;I<last_epwm_index;I++)
{
(* ePWM[i]).TBPRDHR= PRD1_HR<<8;
}
Status = SFO ();//在后台,MEP 校准模块
//持续更新 MEP_ScaleFactor
if (status == SFO_error)
{
ESTOP0; // SFO 函数在发生错误时返回2,以及
} // MEP 步长/粗步长超过最大值255。
}
}
//---------------- 初始化 HRPWM ------------------------------------------------------- //
void initPWM()
{
uint16_t j;
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; //禁用 ePWM 内的 TBCLK
EDIS;
对于(j=1;j<last_epwm_index;j++)
{
//---------------- 时基/ CMP ------------------ //
(* ePWM[j]).TBCTL.bit.PRDLD = TB_shadow; //设置影子加载
(* ePWM[j]).TBPRD= PRD; // PWM 频率= 1/(2*TBPRD)
(* ePWM[j]).CMPA.all =(long) CMP << 16 | CMPHR<< 8; //启用 HRPWM 占空比
(* ePWM[j]).CMPB.all =(long) CMP << 16 | CMHR << 8;
(* ePWM[j]).TBPHS.all = 0;
(* ePWM[j]).TBCTR = 0;
(* ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_UP; //选择向上/向下计数模式
(* ePWM[j]).TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
(* ePWM[j]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
(* ePWM[j]).TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
(* ePWM[j]).TBCTL.bit.FREE_SOFT = 3;
//---------------- SHADOWS ------------------------- //
(* ePWM[j]).CMPCTL.bit.LOADAMODE = CC_CTR_PRD; //在 CTR = PRD 上加载 CMPA
(* ePWM[j]).CMPCTL.bit.LOADBMODE = CC_CTR_PRD;
(* ePWM[j]).CMPCTL.bit.SHDWAMODE = CC_shadow;
(* ePWM[j]).CMPCTL.bit.SHDLBMODE = CC_HOLD;
//---------------- 动作限定符------------------------------------------------------- //
(* ePWM[j]).AQCTLA.bit.CAU = AQ_CLEAR; // PWM 切换高电平/低电平
(* ePWM[j]).AQCTLA.bit.PRD = AQ_SET; //不设置为 ZRO、HR 周期不稳定
//(* ePWM[j]).AQCTLB.bit.CBU = AQ_SET; // PWM 切换为高电平/低电平
//(* ePWM[j]).AQCTLB.bit.PRD = AQ_CLEAR;
//---------------- HRPWM -------------------------- //
EALLOW;
(* ePWM[j]).HRCNFG.all = 0x0;
(* ePWM[j]).HRCNFG.bit.EDGMODE = HR_BEP; // HR 周期的 BOht Edge to Work
(* ePWM[j]).HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR 和 TBPRDHR HR 控制。
(* ePWM[j]).HRCNFG.bit.HRLOAD = HR_CTR_Zero_PRD; //在 CTR = 0 且 CTR = TBPRD 时加载
(* ePWM[j]).HRCNFG.bit.EDGMODEB = HR_BEP; // HR 周期的 BOht 边沿开始工作
(* ePWM[j]).HRCNFG.bit.CTLMODEB = HR_CMP; // CMPBHR 和 TBPRDHR HR 控制
(* ePWM[j]).HRCNFG.bit.HRLOADB = HR_CTR_Zero_PRD; //在 CTR = 0 且 CTR = TBPRD 上加载
(* ePWM[j]).HRCNFG.bit.SWAPAB = 0; // ePWMxA 和 ePWMxB 输出不变
(* ePWM[j]).HRCNFG.bit.AUTOCONV = 1; //启用 HR 周期的自动转换
(* ePWM[j]).HRPCTL.bit.TBPHSHRLOADE = 0; //启用 TBPHSHR 同步 (对于更新计数 HR 控制是必需的)
(* ePWM[j]).HRPCTL.bit.HRPE = 1; //开启高分辨率周期控制。
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; //在 ePWM 中启用 TBCLK
(* ePWM[j]).TBCTL.bit.SWFSYNC = 1; //将高分辨率相位同步到起始 HR 周期
//---------------- 死区------------------------------------------------------- //
(* ePWM[j]).DBCTL.bit.IN_MODE = DBA_ALL; //ICI EPWMxA est la source des retards de front-子孙 和 Front monant。
(* ePWM[j]).DBCTL.bit.out_mode=DB_FULL_ENABLE; //见表15-8
(* ePWM[j]).DBCTL.bit.POLSEL=DB_ACTV_HIC; //高电平有效互补-> Tableau 15-8
(* ePWM[j]).DBCTL.bit.HALFCYCLE = 1; //该位必须设置为 HR 死区(DB 为时钟5ns)
(* ePWM[j]).DBCTL.bit.OUTSWAP = 0;
(* ePWM[j]).DBCTL.bit.SHDWDBREDMODE = 1;
(* ePWM[j]).DBCTL.bit.SHDWDBFEDMODE = 1;
(* ePWM[j]).DBCTL.bit.LOADREDMODE = 2;
(* ePWM[j]).DBCTL.bit.LOADFEDMODE = 2;
(* ePWM[j]).DBRED.all = feed; //解封组件
(* ePWM[j]).DBFED.all = FED;
(* ePWM[j]).HRCNFG2.bit.EDGMODEDB= HR_BEP; // DBREDHR 和 DBFEDHR
(* ePWM[j]).HRCNFG2.bit.CTLMODEDBFED =2; //在 ZRO 上加载
(* ePWM[j]).HRCNFG2.bit.CTLMODEDBRED =2;
(* ePWM[j]).DBREDHR.bit.DBREDHR = FEDHR; //解压两个 PW1Ms 的上升
(* ePWM[j]).DBFEDHR.bit.DBFEDHR = FEDHR; //解压两个 PW1Ms 的下降值
EDIS;
}
}
//---------------- 初始化 GPIO ------------------------------------------------------- //
void initGPIO()
{
EALLOW; //启用对 GPIO 配置寄存器的访问
//为 PWM1A 配置 GPIO 0
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; //激活引脚上的上拉电阻
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; //针对 PWM1A 功能配置引脚
//为 PWM1B 配置 GPIO 1
GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0; //激活引脚上的上拉电阻
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; //针对 PWM1B 功能配置引脚
EDIS; //禁止访问 GPIO 配置寄存器
}
void PRD_CMP_DB_calculation (float32_t 周期、float32_t DUTY、float32_t dutyDB)
{
//------- 期间和 PRDHR 计算 ----------------------------------------------------- //
float invTBCLK= 0.10; //1/TBCLK = 0.1纳秒、TBCLK=10ns 时的时钟冲数
float PRDfrac=periode*invTBCLK; //排列 p 的 TBCLK 的数量
int PRDint=(PRDfrac); //分割周期的整数部分
PRD=PRDint-1;
PRD1_HR=(PRDfrac-PRDint)*256;
//------- CMP 和 CMHR 计算 ------- //
Int reste = PRD/2; //Euclidean 除法、了解如何计算50%占空比下的 CMP
if (reste!=0) //如果 PRD 是奇数
{
CMP=PRDint/2 - 1;
}
else //如果 PRD 为偶数
{
CMP=PRD/2;
}
浮点 FRAC = PRDfrac*占空比; //计算 CMHR = FRAC (PRDfrc*占空比)
int ent =(FRAC);
浮点 CMPHRfrac =分数端;
CMPHRfrac = CMPHRfrac*256;
CMPHR=(CMPHRfrac);
//------- 死区和 DBHR 计算------- //
float RequiredDBvalue=Duty*period*dutyDB;
float fracFED=RequiredDBvalue*0.2;//*0.2 相当于除以10ns/2或半个时钟周期
fed=(fracFED);
float fracfedHR=(facFED-feed)*128;//DBFED 在7位上,因此对于 cacul 我们实现了(fractionalpart*128)
FEDH=(fracFEDHR);
}