主题中讨论的其他器件: CCStudio、 SysConfig
1.
2.
3. 下面是我的代码,如果它有帮助:
#include "F2837xD_DEVICE.h"
#include "F2837xD_examples.h"
#include "F2837xD_ePWM_definites.h" //初始化定义
#include "SFO_v8.h"
#include "board.h"
#包含
//---------------- 设置周期和数据库------------------------------------------------------- //
float PeriodeNANOsec = 200 ; /国家海洋环境中的边界
浮点占空比= 0.5;
float dutyDB = 0; //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 CMPB;
uint16_t CMPA;
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);
//初始化控制和模拟子系统的系统控制
//启用外设时钟
EALLOW;
InitSysCtrl();
EDIS;
//通过所有 PWM 实现 EPWM1A 和 EPWM1B
initGPIO();
Dint;
InitPieCtrl();
//禁用 CPU 中断并清除所有 CPU 中断标志:
EALLOW;
IER = 0x0000;
IFR = 0x0000;
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)
{
浮点 周期;//周期的新值
printf ("期间的新值(单位 ns):");
scanf ("%f"、&periode);
printf("\n");
PRD_CMP_DB_calculation (periode、dutycycle、dutyDB);
for (I=1;I<last_epwm_index;I++)
{
(* ePWM[i]).TBPRD= PRD;
(* ePWM[i]).CMPA.all =(long) CMPA << 16 | CMPHR<< 8; //启用 HRPWM 占空比
(* ePWM[i]).CMPB.all =(long) CMPB << 16 | CMHR << 8;
(* ePWM[i]).DBRED.all = feed; //解压组件
(* ePWM[i]).DBFED.all = FED;
(* ePWM[i]).DBREDHR.bit.DBREDHR = FEDHR; //解压两个 PW1Ms 的上升
(* ePWM[i]).DBFEDHR.bit.DBFEDHR = FEDHR;
(* 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 =(长) CMPA << 16 | CMPHR<< 8; //启用 HRPWM 占空比
(* ePWM[j]).CMPB.all =(长) CMPB << 16 | CMHR << 8;
(* ePWM[j]).TBPHS.all = 0;
(* ePWM[j]).TBCTR = 0;
(* ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //选择向上向下计数模式
(*ePWM[j]).TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
(* 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_SET; // PWM 切换为高电平/低电平
(* ePWM[j]).AQCTLA.bit.cbd = AQ_CLEAR; //不设置为 ZRO、HR 周期不稳定
(* ePWM[j]).AQCTLB.bit.CAU = AQ_CLEAR; // PWM 切换高电平/低电平
(* ePWM[j]).AQCTLB.bit.bd = AQ_SET; //不设置为 ZRO、HR 周期不稳定
//---------------- 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 的下降值
(* ePWM[j]).TBPRDHR= PRD1_HR<<8;
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= 0;
PRDfrac = periode*invTBCLK*0.5; //页的 TBCLK 数量
PRD=(PRDfrac); //分割周期的整数部分
PRD1_HR=((PRDfrac-PRD))*256;
//------- CMP 和 CMHR 计算 ------- //
float fracPRD = 0;
fracPRD = period*invTBCLK;
浮点恢复= 0;
Reste = fracPRD * 0.5; //Euclidean 除法、了解如何计算50%占空比下的 CMP
如果(reste ==(int) reste) //如果 periode /(2.TBCLK) 是整数 (例如:180ns / 20ns = 9 CLK =PRD)
{
浮点电阻2 = 0;
实验2 = PRD *0.5;
if (reste2 ==(int) reste2 ) // if 如果 PRD/2是整数(ex: 200ns : PRD=10 CLK and PRD/2=5)
{
CMPA=PRD/2;
CMPB = PRD/2;
}
else //如果 PRD/2不是整数(例如180ns -> PRD= 9 CLK 且 PRD/2= 4.5)
{
浮点 CMPfrac = PRD/2;
CMPA =(CMPfrac);
CMPB = CMPA + 1;
}
}
else //如果 periode/2.TBCLK 不是整数(例如190ns/20ns = 9.5 CLK =PRD)
{
浮点 CMPfrac = PRD/2;
int CMPent =(CMPfrac);
CMPA = CMPent - 1;
CMPB = CMPent + 1;
}
浮点 FRAC = 0;
FRAC = PRDfrac*占空比; //计算 CMHR = FRAC (PRDfrc*占空比)
INT ent = 0;
Ent =(FRAC);
浮点 CMPHRfrac = 0;
CMPHRfrac =分数元;
CMPHRfrac = CMPHRfrac*256;
CMPHR=(CMPHRfrac);
//------- 死区和 DBHR 计算------- //
float RequiredDBvalue= 0;
RequiredDBvalue = Duty*period*dutyDB;
float fracFED= 0;
fracFED = RequiredDBvalue*0.2;//*0.2 相当于除以10ns/2或半个时钟周期
fed=(fracFED);
float fracFEDH= 0;
fracFEDH=(fracFED-feed)*128;//DBFED 在7位上,因此对于 cacul 我们实现了(fractionalpart*128)
FEDH=(fracFEDHR);
}