大家好、我不熟悉微控制器编程。 我使用您的其中一个产品:TMS320F28379D。 CCS 上执行代码。 我希望生成一个 PWM 信号。
我已经使用 SFO()文件配置了 EPWM 输出、向上计数以及高周期分辨率。 我的问题如下:
我已将动作限定符配置为在 TBCLK 达到零和达到 PRD 周期时进行设置和切换。 我想这样做、因为我确信占空比正好是50%。 问题是、当我将资格认证操作设置为 ZRO 和 PRD (而不是 CMPA 和 CMPB)时、HR 周期不再稳定、只发生大致变化。 以下是该代码的摘录:
(* ePWM[j]).AQCTLA.bit.ZRO = AQ_SET;
(* ePWM[j]).AQCTLA.bit.PRD = AQ_TOGGLE;
但 HR 周期信号能很好地与这些代码行配合工作、但这不是我想要的:
(* ePWM[j]).AQCTLA.bit.CAU = AQ_SET;
(* ePWM[j]).AQCTLA.bit.CAD = AQ_CLEAR;
您是否知道如何使期间内的 HRPWM 与 ZRO 和 PRD 上的合格操作正常工作?
如果您需要任何进一步的信息、请随时与我联系。
这是我的完整程序:
#include "F28x_Project.h"
#include "F2837xD_DEVICE.h"
#include "F2837xD_examples.h"
#include "F2837xD_ePWM_definites.h" //初始化定义
#include "SFO_v8.h" // besoin pour CALIBERR MEP
#include "board.h" //adresse des PWM
#包含
//---- 定义--//
#define LAST_EPWM_INDEX 4
//---------------- Selection de la periode ------------------------------------------------------- //
浮点 PeriodeNANOsec = 105;
//---------------- GLOBAL ------------------------ //
uint16_t status、PeriodFine、compCount;
int MEP_ScaleFactor = 56;
INT PRD1、PRD1_HR;
浮点 PRDHR解码;
易失性结构 ePWM_regs * ePWM[]={0、&EPwm1Regs、&EPwm2Regs、&EPwm3Regs}; //更改 ePWM
Volatile uint32_t PWM[]={0、myEPWM1_base、myEPWM2_base、myEPWM3_base};
//--appel de fonction--//
void PRDcalculation (float32_t periode);
void initGPIO (void);
void initPWM (void);
//***** 代码主体***** //
int main()
{
PRDcalculation(PeriodeNANOsec);
//初始化控制和模拟子系统的系统控制
//启用外设时钟
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) //semble pas util relire le 15-7
{
Status = SFO(); // SFO 函数返回2 (如果发生错误)以及 MEP 的数量
if (STATUS == SFO_ERROR) //步进/粗步进超过最大值255。
{
ESTOP0;
}
}
uint16_t i = 0;
PeriodFine=0;
SYSCTL_disablePeripheral (SYSCTL_Periph_CLK_TBCLKSYNC);
initPWM();
SYSCTL_enablePeripheral (SYSCTL_Periph_CLK_TBCLKSYNC);
while (1)
{
for (PeriodFine = 0x3333;PeriodFine < 0x3334;PeriodFine++)
{
for (I=1;I<last_epwm_index;I++)
{
(* ePWM[i]).TBPRDHR =(PRD1_HR<<8);//采用 Q16格式
}
Status = SFO ();//在后台,MEP 校准模块
//持续更新 MEP_ScaleFactor
if (status == SFO_error)
{
ESTOP0; // SFO 函数在发生错误时返回2,以及
} // MEP 步长/粗步长超过最大值255。
}//循环的结束 PeriodFine
}
}
//---------------- 初始化 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= PRD1; // PWM 频率= 1/(2*TBPRD)
(* ePWM[j]).CMPA.bit.CMPA = PRD1/2; //初始设置占空 比50%//在端口切换和切换时设置端阻尼因子
(* ePWM[j]).CMPA.bit.CMPAHR =(1 << 8); //初始化 HRPWM 扩展
(* ePWM[j]).CMPB.bit.CMPB = PRD1/2; //初始设置占空比50%
(* ePWM[j]).cmpb.all |= 1;
(* ePWM[j]).TBPHS.all = 0;
(* ePWM[j]).TBCTR = 0;
(* ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //选择向上向下计数模式
(* 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 = 11;
//---------------- SHADOWS --------------------- //
(* ePWM[j]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; //在 CTR = 0上加载 CMPA
(* ePWM[j]).CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
(* ePWM[j]).CMPCTL.bit.SHDWAMODE = CC_shadow;
(* ePWM[j]).CMPCTL.bit.SHDLBMODE = CC_HOLD;
//---------------- 动作限定符------------------------------------------------------- //
(* ePWM[j]).AQCTLA.bit.ZRO = AQ_SET; // PWM 切换为高电平/低电平
(* ePWM[j]).AQCTLA.bit.PRD = AQ_TOGGLE;
/*
(* ePWM[j]).AQCTLA.bit.CAU = AQ_SET; // PWM 切换为高电平/低电平
(* ePWM[j]).AQCTLA.bit.CAD = AQ_CLEAR;
(* ePWM[j]).AQCTLB.bit.CBU = AQ_CLEAR; // PWM 切换高电平/低电平
(* ePWM[j]).AQCTLB.bit.cbd = AQ_SET; */
//---------------- HRPWM --------------------- //
EALLOW;
(* ePWM[j]).HRCNFG.all = 0x0;
(* ePWM[j]).HRCNFG.bit.EDGMODE = HR_BEP; // 两个边沿上的 MEP 控制。
(* 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; // 两个边沿上的 MEP 控制
(* 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.AUTOCONV = 1; //启用 HR 周期的自动转换
(* ePWM[j]).HRPCTL.bit.TBPHSHRLOADE = 1; //启用 TBPHSHR 同步 (对于更新计数 HR 控制是必需的)
(* ePWM[j]).HRPCTL.bit.HRPE = 1; //开启高分辨率周期控制。
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; //在 ePWM 中启用 TBCLK
(* ePWM[j]).TBCTL.bit.SWFSYNC = 1; //将高分辨率相位同步到起始 HR 周期
EDIS;
}
}
//---------------- 初始化 GPIO ------------------------------------------------------- //
void initGPIO()
{
EALLOW;
// CONFIGURER GPIO 0覆铜 PWM1A
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;
// CONFIGURE GPIO 1加注 PWM1B
GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;
EDIS;
}
void PRDcalculation (float32_t periode)
{
浮点 NUMBER_TBCLK=0; //霍洛奇政变党=10ns
float invTBCLK= 0.10; // 1/TBCLK = 0.1毫微秒
Number_TBCLK = period*invTBCLK;
int integer _number_TBCLK =(NUMBER_TBCLK);
PRD1 = INTEGRAT_NUMBER_TBCLK/2;
PRDHRdec =(((number_TBCLK-integer_number_TBCLK)* MEP_ScaleFactor+0.5)* 2);
PRD1_HR=(PRDHRdec);
}
