This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/TMS320F28027:使用 ADC 的三相逆变器的 SPWM 闭环控制

Guru**** 2193080 points
Other Parts Discussed in Thread: CONTROLSUITE
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/676686/ccs-tms320f28027-spwm-closed-loop-control-of-a-three-phase-inverter-using-adc

器件型号:TMS320F28027
Thread 中讨论的其他器件:controlSUITE

工具/软件:Code Composer Studio

您好!

我使用的是 F28027 DSP、我正在从事一个制作三相 SPWM 闭环逆变器的大学项目。

我已经在 DSP 上生成了 SPWM 信号、但我不知道如何在项目中实现 ADC (仅编码而不是概念)。

我已经看到了一些 ADC 程序的示例、并尝试将它们添加到单个程序中、但它不起作用。

我尝试实现 ADC 程序的代码如下所示。 我找不到这方面的问题。

感谢您的任何帮助。

用户通过适当设置
// EPWM1_TIMER_TBPRD 变量来设置 SPWM 的频率。 PWM、递增和递减模式的频率、
//遵循以下公式:TPWM=2xTBPRDxTTBCLK、TTBCLK=SYSCLKOUT/(HSPCLKDIVxCLKDIV)。
//默认情况下:HSPCLKDIV=2、CLKDIV=1。
//
//芯片 ROM 读取 PWM 的正弦。 正弦表由
// 512个元素组成。
//正弦 PWM 的频率由 timer0中断的周期定义。
//对于50Hz,必须读取正弦表,整个时间为20msec。 这意味
着// timer0中断必须每20/512毫秒发生一次。
//的常规类型为 ttimer=Tsin*FCPU/index。
////
正弦的120度差由以下变量设定:
//索引= 0,零度
//索引2= 170,120度
//索引3=340,240度
//
//
////////---
///--------------------------------------------
#include 
#include 
#include "DSP28x_Project.h"// DSP28x 头文件
#include "F2802x_common/include/f2802x_IQPrototypes.h"
#include "F2802x_common/include/exclk.h"#include "f2802x_common/包含

"#f2802x_包含"#f2802x_common/包含"#f2802x/exclk.h/include





#include #f2802x_common/包含"#f2802x/包含"#f2802x_gpio.h/include #include #include #f2802x/包含#include #f2802x_common.h/包含#f2802x/包含#include #f2802x/包含#f2802x/包含#f2802x/包含#include #f2802x/包含#include #f2802x_common.h/包含#f280n.h/包含#include #f2802x/包含#include #include "#f2802x/包含#f280n.包含#.包含#f2802x/包含#f2802x_common.h/包含#f280n.包含#.h






// timer0
中断的中断原型函数 void CPU_timer0_ISR (void);
void update_compare (void);
//全局 PWM 变量
#define EPWM1_TIMER_TBPRD 14634 // 2050.2Hz 的周期寄存
器#define PHASE 120.0 //定义相位间的实数相位、120deg
#define TTIMEREG 2343 // 50Hz SPWM
UINT16 EPWM_PHASE=(EPWM1_TIMER_TBPRD* PHASE/180.0)的定时器中断;//从 ePWM 模块
UINT16 DUTAY_CYCLE = 1000看到的相位;//初
始设置占空比50% UINT16 DUTAY_B=1000;//初始设置占空比50%
UINT16索引= 0; //零度正弦
uint16 index2=170; // 120度正弦差
uint16 index3=340; // 240度正弦扩散
UINT16死区时间_R=5.0; //死区时间5usec
UINT16死区时间_F=5.0; //死区时间5usec
//处理设置
cpu_handle myCpu;
pll_handle myPll;
wDOG_handle myWedDog;
clk_handle myClk;
adc_handle myAdc;
FLASH_Handle myFlash;
GPIO_Handle myGpio;
PIE_Handle myPie;
// SCI_Handle mySCI;
PWM_Handle PWMA、PWMB、PWMC;
Timer_handle myTimer0;

//本示例中使用的 ADC 全局变量:
uint16_t ADC0、ADC1、ADC2、ADC3、sp、 平均值;
双误差、积分;
浮点 ma = 0.8;
浮点 Kp = 0.5;
浮点 Ki = 0.5;


//处理初始
化 void setup_handles ()
{
myClk = CLK_init ((void *) CLK_base_ADDR、sizeof (CLK_Obj));
myPll = PLL_init ((void *) PLL_base_ADDR、sizeof (PLL_Obj));
myWdDog = WDOG_INIT ((void *) WDOG_BASE_ADDR、sizeof (WDOG_Obj));
myCpu = cpu_init ((void *) NULL、sizeof (cpu_Obj));
myFlash = flash_init ((void *) flash_base_ADDR、sizeof (flash_Obj));
myGpio = GPIO_init ((void *) GPIO_base_ADDR、sizeof (GPIO_Obj));
myPie = PI_init ((void *) PI_BASE_ADDR、sizeof (PI_Obj));
// mySCI = SCI_init (((void *) SCIA_BASE_ADDR、sizeof (SCI_Obj)));
myAdc = ADC_init ((void *) ADC_base_ADDR、sizeof (ADC_Obj));
PWMA = PWM_init (((void *) PWM_ePWM1_base_ADDR、sizeof (PWM_Obj));
PWMB = PWM_init (((void *) PWM_ePWM2_base_ADDR、sizeof (PWM_Obj));
PWMC = PWM_init (((void *) PWM_ePWM3_base_ADDR、sizeof (PWM_Obj));
myTimer0 = TIMER_INIT ((void *) TIMER0_BASE_ADDR、sizeof (timer_Obj));
}
//系统初始
化 void init_system ()
{
//禁用看门狗
WDOG_DISABLE (myWdog);
// ADC 的器件校准
(* Device_cal);
//系统初始化 void init_system ();//禁用看门狗 WDOG_disable (myCLK

)* 2
);* 100MHz (rul_clrul_cld);* 2)内部振荡器设置为 PLL_clrul_clrul_clrul_clrulk (2);* 2 (针对 myclrul_clrulk_clrul_clrul_clrul_clk * 2);(1)
//禁用 PIE 外设和所有中断 PI_disable
(myPie);
PI_disableAllInts (myPie);
CPU_disableGlobalIntts (myCpu);
CPU_clearIntFlags (myCpu);
#ifdef _FLASH
memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize);
#endif
}


//GPIO 初始
化 void GPIO_init ()
{
//初始化 EPWM1A 和 EPWM1B 的 GPIO
GPIO_setPullUp (myGpio、GPIO_Number_0、GPIO_PULLUP_Disable);
GPIO_setPullUp (myGpio、GPIO_Number_1、GPIO_PULLUP_Disable);
GPIO_setMode (myGpio、GPIO_Number_0、GPIO_0_Mode_EPWM1A);
GPIO_setMode (myGpio、GPIO_Number_1、GPIO_1_Mode_EPWM1B);
GPIO_setDirection (myGpio、GPIO_Number_0、GPIO_Direction_Output);
GPIO_setDirection (myGpio、GPIO_Number_1、GPIO_Direction_Output);
//初始化 EPWM2A 和 EPWM2B 的 GPIO
GPIO_setPullUp (myGpio、GPIO_Number_2、GPIO_PULLUP_Disable);
GPIO_setPullUp (myGpio、GPIO_Number_3、GPIO_PULLUP_Disable);
GPIO_setMode (myGpio、GPIO_Number_2、GPIO_2_Mode_EPWM2A);
GPIO_setMode (myGpio、GPIO_Number_3、GPIO_3_Mode_EPWM2B);
GPIO_setDirection (myGpio、GPIO_Number_2、GPIO_Direction_Output);
GPIO_setDirection (myGpio、GPIO_Number_3、GPIO_Direction_Output);
//初始化 EPWM2A 和 EPWM2B 的 GPIO
GPIO_setPullUp (myGpio、GPIO_Number_4、GPIO_PULLUP_Disable);
GPIO_setPullUp (myGpio、GPIO_Number_5、GPIO_PULLUP_Disable);
GPIO_setMode (myGpio、GPIO_Number_4、GPIO_4_Mode_EPWM3A);
GPIO_setMode (myGpio、GPIO_Number_5、GPIO_5_Mode_EPWM3B);
GPIO_setDirection (myGpio、GPIO_Number_4、GPIO_Direction_Output);
GPIO_setDirection (myGpio、GPIO_Number_5、GPIO_Direction_Output);
}
//PWM 设置
void pwma_init ()
{
// PWMA 初始化
CLK_enablePwmClock (myClk、PWM_NUMBER_1);
//PWMA 初始化
//设置 TBCLK
PWM_setCounterMode (PWMA、PWM_CounterMode_UpDown);//递增-递减计数
PWM_setPeriod (PWMA、EPWM1_TIMER_TBPRD); //设置计时器周期
PWM_DisableCounterLoad (PWMA); //禁用相位加载
PWM_setSyncMode (PWMA、PWM_SyncMode_Disable);
PWM_setCount (PWMA、0x0000); //清除计数器
PWM_setClkDiv (PWMA、PWM_ClkDiv);
PWM_setHighSpeedClkDiv (PWMA、PWM_HspClkDiv_BY_1); //时钟与 SYSCLKOUT 的比率
//设置隐藏
PWM_setShadowImage Mode_cmpA (PWMA、PWM_ShadowImage Mode_Shadow);
PWM_setShadowImage Mode_CMPB (PWMA、PWM_ShadowImage Mode_Shadow);
PWM_setLoadMode_cmpA (PWMA、PWM_LoadMode_Zero);
PWM_setLoadMode_CMPB (PWMA、PWM_LoadMode_Zero);
PWM_setCmpA (PWMA、1000);//初始占空比
PWM_setCmpB (PWMA、1000);
//设置操作
PWM_setActionQual_CntUp_CmpA_PwmA (PWMA、PWM_ActionQual_set); //在事件 A 上设置 PWM1A、递增计数
PWM_setActionQual_CntDown_CmpA_PwmA (PWMA、PWM_ActionQual_clear);//在事件 A 上清除 PWM1A、递减计数
PWM_setActionQual_CntUp_CMPB_PwmB (PWMA、PWM_ActionQual_clear); //在事件 B 上设置 PWM1B,向上计数
PWM_setActionQual_CntDown_CMPB_PwmB (PWMA、PWM_ActionQual_set);//在事件 B 上清除 PWM1B、递减计数
//设置死区控制
PWM_setDeadBandOutputMode (PWMA、PWM_DeadBandOutputMode_EPWMxA_Rising EPWMxB_Falling);
PWM_setDeadBandPolarity (PWMA、PWM_DeadBandPolarity _EPWMxB_Inverted);
PWM_setDeadBandInputMode (PWMA、PWM_DeadBandInputMode_EPWMxA_rising_and_Falling);
PWM_setDeadBandRisingEdgeDelay (PWMA、DeadTime_R);
PWM_setDeadBandFallingEdgeDelay (PWMA,DeadTime_F);
//---------------
///--------------------------------------------------------------
//PWMB 初始化
CLK_enablePwmClock (myClk、PWM_NUMBER_2);
//设置 TBCLK
PWM_setCounterMode (PWMB、PWM_CounterMode_UpDown);//递增-递减计数
PWM_setPeriod (PWMB、EPWM1_TIMER_TBPRD);//设置定时器周期
PWM_enableCounterLoad (PWMB);
PWM_setPhaseDir (PWMB、PWM_PhaseDir_倒 计数);
PWM_setSyncMode (PWMB、PWM_SyncMode_Disable);
PWM_setCount (PWMB、0x0000); //清除计数器
PWM_setClkDiv (PWMB、PWM_ClkDiv);
PWM_setHighSpeedClkDiv (PWMB、PWM_HspClkDiv_BY_1); //时钟与 SYSCLKOUT 的比率
//设置隐藏
PWM_setShadowImage Mode_cmpA (PWMB、PWM_ShadowImage Mode_Shadow);
PWM_setShadowImage Mode_CMPB (PWMB、PWM_ShadowImage Mode_Shadow);
PWM_setLoadMode_cmpA (PWMB、PWM_LoadMode_Zero);
PWM_setLoadMode_CMPB (PWMB、PWM_LoadMode_Zero);
PWM_setCmpA (PWMB、1000);//初始占空比
PWM_setCmpB (PWMB、1000);
//设置操作
PWM_setActionQual_CntUp_CmpA_PwmA (PWMB、PWM_ActionQual_set); //在事件 A 上设置 PWM2A、递增计数
PWM_setActionQual_CntDown_CmpA_PwmA (PWMB、PWM_ActionQual_clear);//在事件 A 上清除 PWM2A、递减计数
PWM_setActionQual_CntUp_CMPB_PwmB (PWMB、PWM_ActionQual_clear); //在事件 B 上设置 PWM2B、向上计数
PWM_setActionQual_CntDown_CMPB_PwmB (PWMB、PWM_ActionQual_set);//在事件 B 上清除 PWM2B、递减计数
//设置死区控制
PWM_setDeadBandOutputMode (PWMB、PWM_DeadBandOutputMode_EPWMxA_Rising EPWMxB_Falling);
PWM_setDeadBandPolarity (PWMB、PWM_DeadBandPolarity _EPWMxB_Inverted);
PWM_setDeadBandInputMode (PWMB、PWM_DeadBandInputMode_EPWMxA_rising_and_Falling);
PWM_setDeadBandRisingEdgeDelay (PWMB、死区时间_R);
PWM_setDeadBandFallingEdgeDelay (PWMB、DeadTime_F);
//---------------
///------------------------------------------------------------
//PWMC 初始化
CLK_enablePwmClock (myClk、PWM_NUMBER_3);
//设置 TBCLK
PWM_setCounterMode (PWMC、PWM_CounterMode_UpDown);//递增-递减计数
PWM_setPeriod (PWMC、EPWM1_TIMER_TBPRD);//设置定时器周期
PWM_enableCounterLoad (PWMC);
PWM_setPhaseDir (PWMC、PWM_PhaseDir_CountUp);
PWM_setSyncMode (PWMC、PWM_SyncMode_Disable);
PWM_setCount (PWMC、0x0000); //清除计数器
PWM_setClkDiv (PWMC、PWM_ClkDiv_BY_1);
PWM_setHighSpeedClkDiv (PWMC、PWM_HspClkDiv_BY_1); //时钟与 SYSCLKOUT 的比率
//设置隐藏
PWM_setShadowImage Mode_cmpA (PWMC、PWM_ShadowImage Mode_Shadow);
PWM_setShadowImage Mode_CMPB (PWMC、PWM_ShadowImage Mode_Shadow);
PWM_setLoadMode_cmpA (PWMC、PWM_LoadMode_Zero);
PWM_setLoadMode_CMPB (PWMC、PWM_LoadMode_Zero);
PWM_setCmpA (PWMC、1000);//初始占空比
PWM_setCmpB (PWMC、1000);
//设置操作
PWM_setActionQual_CntUp_CmpA_PwmA (PWMC、PWM_ActionQual_set); //在事件 A 上设置 PWM3A、递增计数
PWM_setActionQual_CntDown_CmpA_PwmA (PWMC、PWM_ActionQual_clear);//在事件 A 上清除 PWM3A、递减计数
PWM_setActionQual_CntUp_CMPB_PwmB (PWMC、PWM_ActionQual_clear); //在事件 B 上设置 PWM3B、递增计数
PWM_setActionQual_CntDown_CMPB_PwmB (PWMC、PWM_ActionQual_set);//在事件 B 上清除 PWM3B、递减计数
//设置死区控制
PWM_setDeadBandOutputMode (PWMC、PWM_DeadBandOutputMode_EPWMxA_Rising EPWMxB_Falling);
PWM_setDeadBandPolarity (PWMC、PWM_DeadBandPolarity _EPWMxB_Inverted);
PWM_setDeadBandInputMode (PWMC、PWM_DeadBandInputMode_EPWMxA_rising_and_Falling);
PWM_setDeadBandRisingEdgeDelay (PWMC、死区时间_R);
PWM_setDeadBandFallingEdgeDelay (PWMC、死区时间_F);
clk_enableTbClockSync (myClk);
}
//pie 设置
void PI_init ()
{
PIE_ENABLE (myPie);
EALLOW;
EDIS;
PI_registerPieIntHandler (myPie、PI_GroupNumber_1、PI_SubGroupNumber_7、(intVec_t)&CPU_timer0_ISR);
EDIS;
}
//Timer 设置
无效 timer0_init()
{
Timer_stop (myTimer0);
Timer_setPeriod (myTimer0、TTIMERREG);
Timer_setPrescaler (myTimer0、0);
Timer_reload (myTimer0);
Timer_setEmulationMode (myTimer0、timer_EmulationMode_StopAfterNextDecrement);
Timer_enableInt (myTimer0);
Timer_start (myTimer0);
/******** 启用 ADC 中断******** /
//清除 ADCINT1标志为下一个 SOC 重新初始化
ADC_clearIntFlag (myAdc、ADC_IntNumber_1);
//启用指定的 ADC 中断
PIE_enableAdcInt (myPie、ADC_IntNumber_1);

/******** 启用计时器中断******** /
//启用指定的中断编号
CPU_enableInt (myCpu、CPU_IntNumber_1);// CPU INT1、在 CPU 定时器0上触发
//启用指定的中断编号
// cpu_enableInt (myCpu、cpu_IntNumber_13);//在 CPU 定时器1上触发 CPU INT13
//启用 CPU 定时器0中断
PIE_enableTimer0Int (myPie);

//启用全局中断
cpu_enableGlobalInts (myCpu);
}
// ADC 初始化
void adc_init()
{
/****** 初始化 ADC ******** /

//启用 ADC 带隙电路
adc_enableBandGap (myAdc);
//启用 ADC 基准缓冲器电路
ADC_enableRefBuffers (myAdc);
//为 ADC 加电
ADC_POWERUP (myAdc);
//启用 ADC
ADC_ENABLE (myAdc);
//设置电压基准源
// ADCCTL1 - ADC_ADCCTL1_ADCREFSEL_BITS
ADC_setVoltRefSrc (myAdc、ADC_VoltageRefSrc_Int);


//清除 ADCINT1标志为下一个 SOC 重新初始化
ADC_clearIntFlag (myAdc、ADC_IntNumber_1);
//启用指定的 ADC 中断
PIE_enableAdcInt (myPie、ADC_IntNumber_1);
//启用 ADC 中断
ADC_enableInt (myAdc、ADC_IntNumber_1);


//设置中断脉冲生成模式
// ADCCTL1 - ADC_ADCCTL1_INTPULSEPOS_BITS
// param[in] adcHandle ADC 对象句柄
// param[in] pulseMode 脉冲生成模式
ADC_setIntPulseGenMode (myAdc、ADC_IntPulseGenMode_Prior); //ADCINT1在 AdcResults 锁存后跳闸

//启用 ADC 中断
// INTSELxNy - ADC_INTSELxNy_Inte_BITS
// param[in] adcHandle ADC 对象句柄
// param[in] intNumber 中断编号
ADC_enableInt (myAdc、ADC_IntNumber_1);

//设置中断模式
// INTSELxNy - ADC_INTSELxNy_INTCONT_Bits
// param[in] adcHandle ADC 对象句柄
// param[in] intNumber 中断编号
// param[in] intMode 中断模式
ADC_setIntMode (myAdc、ADC_IntNumber_1、ADC_IntMode_ClearFlag);//禁用 ADCINT1连续模式

//设置中断源
// INTSELxNy - ADC_INTSELxNy_INTSEL_BITS
// param[in] adcHandle ADC 对象句柄
// param[in] intNumber 中断编号
// param[in] intSrc 中断源
ADC_setIntSrc (myAdc、ADC_IntNumber_1、ADC_IntSrc_EOC3); //设置 EOC3以触发 ADCINT1

//设置转换开始(SOC)通道编号
// ADCSOCxCTL - ADC_ADCSOCxCTL_CHSEL_BITS
// param[in] adcHandle ADC 对象句柄
// param[in] socNumber SOC 编号
// param[in]通道编号通道编号
ADC_setSockChanNumber (myAdc、ADC_SockNumber_0、ADC_SockChanNumber_A0);//将 SOC0通道选择设置为 ADCINA0
ADC_setSockChanNumber (myAdc、ADC_SockNumber_1、ADC_SockChanNumber_A1);//将 SOC1通道选择设置为 ADCINA1
ADC_setSockChanNumber (myAdc、ADC_SockNumber_2、ADC_SockChanNumber_A2);//将 SOC2通道选择设置为 ADCINA2
ADC_setSockChanNumber (myAdc、ADC_SockNumber_3、ADC_SockChanNumber_A3);//将 SOC3通道选择设置为 ADCINA3

//设置转换开始(SOC)触发源
// ADCSOCxCTL - ADC_ADCSOCxCTL_TRIGSEL_BITS
// param[in] adcHandle ADC 对象句柄
// param[in] socNumber SOC 编号
// param[in]通道编号通道编号
ADC_setSockTrigSrc (myAdc、ADC_SockNumber_0、ADC_SockTrigSrc_CpuTimer_0);//设置 CpuTimer_0上的 SOC0启动触发器、因为轮询 SOC0先转换、然后 SOC1
ADC_setSockTrigSrc (myAdc、ADC_SockNumber_1、ADC_SockTrigSrc_CpuTimer_0);//在 CpuTimer_0上设置 SOC1启动触发器、因为轮询 SOC1先转换、然后再转换 SOC2
ADC_setSockTrigSrc (myAdc、ADC_SockNumber_2、ADC_SockTrigSrc_CpuTimer_0);//设置 CpuTimer_0上的 SOC2启动触发器、因为轮询 SOC2先转换、然后再转换 SOC3
ADC_setSockTrigSrc (myAdc、ADC_SockNumber_3、ADC_SockTrigSrc_CpuTimer_0);//在 CpuTimer_0上设置 SOC4起始触发

//设置转换开始(SOC)采样延迟
// ADCSOCxCTL - ADC_ADCSOCxCTL_ACQPS_Bits
// param[in] adcHandle ADC 对象句柄
// param[in] socNumber SOC 编号
// param[in] samplpleDelay the sample delay
ADC_setSockSampleWindow (myAdc、ADC_SockNumber_0、ADC_SockSampleWindow_7_cycles);//将 SOC0 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
ADC_setSockSampleWindow (myAdc、ADC_SockNumber_1、ADC_SockSampleWindow_7_cycles);//将 SOC1 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
ADC_setSockSampleWindow (myAdc、ADC_SockNumber_2、ADC_SockSampleWindow_7_cycles);//将 SOC2 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
ADC_setSockSampleWindow (myAdc、ADC_SockNumber_3、ADC_SockSampleWindow_7_cycles);//将 SOC3 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)

/********* /

//等待 ADC 中断
while (1)
{
while (AdcRegs.ADCINTFlG.bit.ADCINT1 = 0){}//等待 ADCINT1跳闸

ADC0 = AdcResult.ADCRESULT0;
ADC1 = AdcResult.ADCRESULT1;
ADC2 = AdcResult.ADCRESULT2;
ADC3 = AdcResult.ADCRESULT3;

AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 ADCINT1

//清除 ADCINT1标志为下一个 SOC 重新初始化
//ADC_clearIntFlag (myAdc、ADC_IntNumber_1);
}
}
void main()
{
setup_handles();
init_system();
GPIO_init();
pwma_init();
PI_init();
timer0_init ();


//启用 CPU 中断
CPU_enableInt (myCpu、CPU_IntNumber_1);
//启用 PIE 模块
PIE_enableTimer0Int (myPie)的 Timer0中断;
CPU_enableDebugInt (myCpu);
cpu_enableDebugInt (myCpu);


//永久查看 enableLoop;//查看 GlobalLoop;

{
}
}
中断 void cpu_timer0_isr (void)
{
mean =(ADC0 + ADC1 + ADC2)/3;
error = sp - mean;
integral = error + integral;
ma =(KP*error)+(ki*error)+(ki*integral);
update_compare ();
//确认此中断以接收来自组1
PI_clearint (myPIE、void 1)的更多中断



PWM_setCmpA (PWMA、_IQsat (_IQ30mpy ((sine_table[索引]+_IQ30 (0.9999)))/2、EPWM1_TIMER_TBPRD)、EPWM1_TIMER_TBPRD、0);
PWM_setcmpB (PWMA、_IQsat (_IQ30mpy ((sine_table[索引]+_IQ30 (0.9999)))/2、EPWM1_TIMER_TBPRD)、EPWM1_TIMER_TBPRD、0);
PWM_setCmpA (PWMB、_IQsat (_IQ30mpy ((sine_table[index2]+_IQ30 (0.9999)))/2、EPWM1_TIMER_TBPRD)、EPWM1_TIMER_TBPRD、0);
PWM_setcmpB (PWMB、_IQsat (_IQ30mpy ((sine_table[index2]+_IQ30 (0.9999)))/2、EPWM1_TIMER_TBPRD)、EPWM1_TIMER_TBPRD、0);
PWM_setCmpA (PWMC、_IQsat (_IQ30mpy ((sine_table[index3]+_IQ30 (0.9999)))/2、EPWM1_TIMER_TBPRD)、EPWM1_TIMER_TBPRD、0);
PWM_setCmpB (PWMC、_IQsat (_IQ30mpy ((sine_table[index3]+_IQ30 (0.9999)))/2、EPWM1_TIMER_TBPRD)、EPWM1_TIMER_TBPRD、0);
如果(index++>511)索引=0;
如果(index2++>511)索引2=0;
if (index3++>511) index3=0;
}//---------------

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    马哈拉什

    1. 您尝试使用 ADC 做什么?
    2. 您已经了解、下载并浏览过 controlSUITE 的示例是什么?
      1. 如果您尚未了解、controlSUITE 中有几个很好的 ADC 示例!

    3. 您是否进行过任何调试?
      1. 什么工作正常?
      2. 什么不起作用?

    此致、
    Cody  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    首先,我尝试通过我拥有的传感器卡测量逆变器的输出电压。

    我已经了解了 controlSUITE 示例、并使用 controlsuite 为软件驱动程序函数添加头文件和定义文件。
    我查看了 ePWM 示例和 ADC 示例、并尝试将它们合并在一起、但它不能正常工作。 因此、我在 TI e2e 论坛上尝试了上述示例。 它可以正常工作、但我在 ADC 寄存器定义方面遇到了一些错误。

    是的、我在没有 ADC 的情况下调试了 SPWM 程序、它运行得不错。 我还检查了 DSO 中的波形。


    然后我发现了一个新问题
    其正弦波频率无法达到50Hz (在我所在的地区)。

    所以、我被困在这里...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    马哈拉什
    关于 PWM 频率问题、您是否检查了时钟源、乘法器和除法器?

    您是否配置了 XCLKOUT?

    您是否在 PWM 的时基子模块中使用时钟分频器(TBCTL.CLKDIV)?


    验证上述设置并使用 XCLKOUT 确定 SYSCLK 频率的值、如果这没有指出问题、则将结果发布回此处。

    此致、
    Cody
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Cody、

    是的,我已经配置了时钟分频器和 PLL。 在上面的程序中、PLL 被设置为60MHz、这个速度我具有19Hz 的最大正弦波频率。

    //将 PLL 设置为 x10 /2、从而产生60MHz = 10MHz * 12/2
    PLL_setup (myPll、PLL_Multiier_12、PLL_DivideSelect_CLKIN_BY_2); 

    将 PLL 分频器设置为1可获得120MHz 的速度、但这样、我的最大正弦波频率为38Hz。

    但在直接寄存器访问方法中、我具有50Hz 正弦波、开关频率也约为30kHz。 但缺点是 ADC 不能正常工作,每当我尝试添加 ADC 代码时,输出 SPWM 脉冲就会停止工作(无输出脉冲)。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    根据 controlSUIT 示例、我制作了一个将 ADC 和 ePWM 示例相结合的程序。

    在不添加 ADC 代码的情况下、SPWM 输出正常工作、但当我添加 ADC 代码时、输出停止工作。

    我的代码如下所示、

    #include "DSP28x_Project.h" //器件头文件和示例包括文件
    #include "math.h"
    
    //配置在 PIE 级别启用哪些 EPWM 计时器中断:
    // 1 =启用、0 =禁用
    #define PWM1_INT_ENABLE 1
    #define PWM2_INT_ENABLE 1
    #define PWM3_INT_ENABLE 1
    
    void ADC_Config (void);
    UINT16 index=0; //零度正弦
    uint16 index2=170; // 120度正弦差
    uint16 index3=340; // 240度正弦扩散//
    本示例中使用的全局变量:
    uint16_t LoopCount;
    uint16_t ConversionCount;
    uint16_t Voltage1[10];
    uint16_t Voltage2[10];
    
    //为每个计时器配置周期
    #define PWM1_TIMER_TBPRD 7000
    #define PWM2_TIMER_TBPRD 7000
    #define PWM3_TIMER_TBPRD 7000
    #define EPWM1_TIMER_TBPRD 7000 //对于 IQ 正弦表
    //#define PI 3.141592654
    #include "F2802x_common/include/IQmathLib_TBPRD 7000 #define;
    
    IQ32"/IQmath 文件/example_/IQmath (void)
    
    
    
    //此文件中找到的函数的原型语句。
    interrupt void epwm1_timer_ISR (void);
    interrupt void epwm2_timer_ISR (void);
    interrupt epwm3_timer_ISR (void);
    void InitEPwmTimer (void);
    
    //本示例中使用的全局变量
    uint32_t EPwm1TimerIntCount;
    uint32_t EPwm2m=uint16
    
    、uintc、uintc、uint1、uint1、uint1、uint1、uint1、uint1、uint1、uint1、uint1、uint1、uint1、uint1、u
    
    //float ma =0.8;
    double th=0、f=50、ma=1;
    //uint16 i=0;
    //uint16 sinewave1[100]、sinewave2[100];
    
    void main (void)
    {
    int i;
    
    //警告: 始终确保在运行 RAM 中的任何函数之前调用 memcpy
    // InitSysCtrl 包括对基于 RAM 的函数的调用,并且在不调用
    // memcpy 的情况下,处理器将"进入 weeds"
    #ifdef _flash
    funcpy (&RamfuncsRunStart、&RamsLoadStart、(size_t)&RamfuncsLoadStart、(sLoadStart)&RamfuncsLoadStart、(sLoadStart)&RamfuncsLoadSize)&Ramfuncedift/Step
    
    
    1) 初始化系统控制:
    // PLL、看门狗、启用外设时钟
    //此示例函数位于 F2802x_sysctrl.c 文件中。
    InitSysCtrl();
    
    //步骤2。 初始化 GPIO:
    //此示例函数位于 F2802x_GPIO.c 文件中,
    //说明了如何将 GPIO 设置为其默认状态。
    // InitGpio();//针对此示例跳过
    InitEPwmGpio();
    //步骤3。 清除所有中断并初始化 PIE 矢量表:
    //禁用 CPU 中断
    DINT;
    
    //将 PIE 控制寄存器初始化为默认状态。
    //默认状态是禁用所有 PIE 中断并
    清除标志//。
    //此函数位于 F2802x_PIECTRL.c 文件中。
    InitPieCtrl();
    
    //禁用 CPU 中断并清除所有 CPU 中断标志:
    IER = 0x0000;
    IFR = 0x0000;
    
    //使用指向 shell 中断
    //服务例程(service routinese, ISR)的指针初始化 PIE 矢量表。
    //这将填充整个表,即使在
    本示例中未使用中断//也是如此。 这对于调试很有用。
    //可以在 F2802x_DefaultIsr.c 中找到 shell ISR 例程
    //此函数可在 F2802x_PieVect.c 中找到
    InitPieVectTable();
    
    //此示例中使用的中断被重新映射到
    这个文件中的// ISR 函数。
    EALLOW;//这是写入 EALLOW 受保护寄存
    器 PieVectTable.EPWM1_INT =&epwm1_TIMER_ISR;
    PieVectTable.EPWM2_INT =&epwm2_TIMER_ISR;
    PieVectTable.EPWM3_INT =&epwIS_TIMER_ISR;
    
    
    这是禁用 EALWIS/ EALLOW 寄存器所需的步骤4;/写入此步骤4。 初始化所有器件外设:
    InitEPwmTimer();//对于此示例,仅初始化 ePWM 计时
    器 InitAdc ();//对于此示例,初始化 ADC
    AdcOffsetSelfCal ();
    //步骤5。 用户特定代码、启用中断:
    
    //初始化计数器:
    EPwm1TimerIntCount = 0;
    EPwm2TimerIntCount = 0;
    EPwm3TimerIntCount = 0;
    
    //启用连接到 EPWM1-6的 CPU INT3 INT:
    IER |= M_INT3;
    
    //配置 ADC
    //注: 通道 ADCINA4将被双采样、以解决修订版0器件勘误表中的 ADC 第1个采样问题
    EALLOW;
    AdcRegs.ADCCTL1.bit.INTPULSEPOS= 1;//ADCINT1在 AdcResults 锁存后跳闸
    AdcRegs.INTSEL1N2.bit.INT1E = 1;//启用 ADCINT1
    AdcRegs.INTSEL1N2.bit.INT1CONT = 0;//禁用 ADCINT1连续模式
    AdcRegs.INTSEL1N2.bit.INT1SEL= 2;//设置 EOC2以触发 ADCINT1触发
    AdcRegs.ADCSOC0CTL.bit.CHSEL= 4;//将 SOC0通道选择设置为 ADCINA4
    AdcRegs.ADCSOC1CTL.bit.CHSEL= 4;//将 SOC1通道选择设置为 ADCINA4
    AdcRegs.ADCSOC2CTL.bit.CHSEL= 2;//将 SOC1通道选择设置为 ADCINA2
    AdcRegs.ADCSOC0CTL.bit.TRIGSEL= 5;//设置 SOC0在 EPWM1A 上启动触发器,因为轮询 SOC0先转换,然后 SOC1
    AdcRegs.ADCSOC1CTL.bit.TRIGSEL= 5;//设置 EPWM1A 上的 SOC1启动触发器,因为轮询 SOC0先转换,然后 SOC1
    AdcRegs.ADCSOC2CTL.bit.TRIGSEL= 5;//设置 EPWM1A 上的 SOC2启动触发器,因为轮询 SOC0先转换 SOC1,然后转换 SOC2
    AdcRegs.ADCSOC0CTL.bit.ACQPS= 6;//将 SOC0 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
    AdcRegs.ADCSOC1CTL.bit.ACQPS= 6;//将 SOC1 S/H 窗口设置为7个 ADC 时钟周期(6个 ACQPS 加1)
    AdcRegs.ADCSOC2CTL.bit.ACQPS= 6;//将 SOC2 S/H 窗口设置为7个 ADC 时钟周期、(6个 ACQPS 加1)
    EDIS;
    
    //在 PIE 中启用 ePWM INTn:组3中断1-6
    PieCtrlRegs.PIEIER3.bit.INTx1 = PWM1_INT_ENABLE;
    PieCtrlRegs.PIEIER3.bit.INTx2 = PWM2_INT_ENABLE;
    PieCtrlRegs.PIEIER3.bit.PSITI1.R3
    
    = p1.INT3*;PSIMP3_INT.INT3*
    = PWM2_INTPSIT.INT3_INTR3.bit;PSIMP3_INTR3.bit_INTR3.T1.p1.INT3*
    PieCtrlRegs.PIEIFR3.bit.INTx3 = 1;*/
    
    
    //启用全局中断和更高优先级的实时调试事件:
    EINT;//启用全局中断 INTM
    ERTM;//启用全局实时中断 DBGM
    
    //步骤6。 空闲循环。 只需坐下来循环(可选):
    for (;)
    {
    _asm (" NOP");
    for (i=1;i<=10;i++)
    {}
    
    }}
    
    空 InitEPwmTimer()
    {
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC=0; //停止所有 TB 时钟
    EDIS;
    
    //设置同步
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;//通过
    EPwm2Regs.TBCTL.bit.SYNCOSEL = SEN_CTL_ZERO;//通过
    EPwm3Regs.TBPHS.bit.TBPHS.TS=TBPHS.TS_0
    
    
    
    
    
    ;//启用 EPwtb.TBPHS.tb.PHS.tb.PHS.tb.tb.tb.tb.tb.tp32.tp32.tp32.tb.tb.tb.tp32.tp32.tb.tb.tp32.tb.tp32.tb.tp32.tb.tp32.tb.tp32.tb.tp32.tb.tb.tp32.tp32.tb.tp32.tp32.tb.tp32.tb.tp32.tp32.tp32.tp32.tp32.tp32.tp32.tp
    
    
    
    EPwm3Regs.TBPHS.Half.TBPHS = 0;
    //EPwm1Regs.PCCTL.bit.CHPFRQ = 1;
    //EPwm1Regs.PCCTL.bit.CHPEN = 1;
    EPwm1Regs.TBPRD = PWM1_TIMER_TBPRD;EPwm1Regs.TBCTL.bit.CHPEN = 1;EPwm1RCTL.TBIT.TBIT.TPRD
    = 1;EPwm1RCOUNT_TTB;EPwmCTL.TCTL.TBIT.TBIT.
    //针对向上计数写入 TB_COUNT_向上 计数
    // EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_向上 计数;
    //EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
    EPwm1Regs.ETSEL.bit.INTSEL = ET_PRD; //选择零事件上的 INT
    EPwm1Regs.ETSEL.bit.INTEN = PWM1_INT_ENABLE;//启用 INT
    EPwm1Regs.ETPS.BIT.INTPRD = et_1st;//在第一个事件上生成 INT
    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL;// EPwdL = EPwmREF602LDC
    = EPwmREF602.DBT = DPWLDR
    
    
    
    = EPwmREF602LD.DBT = EPmREF602LD.DBT = EPmREF602LDC;// EPwMER = EPwCLD = EPmREF602LD.DBT = EPmREF602LD.DBT = EPmREF602LD.DBT = EPmREF60R = EPmCLK;// EPwMER = EPwLD.DBT = EPwCL
    // EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;//从机模块
    // EPwm2Regs.TBCTL.bit.PHSDIR = TB_UP;
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UUP; //向上计数
    EPwm2Regs.ETSEL.bit.INTSEL = et_CTR_PRD; //在零事件
    EPwm2Regs.ETSEL.bit.INTEN = PWM2_INT_ENABLE;//启用 INT
    EPwm2Regs.ETPS.BIT.INTPRD = et_1st; //在第二个事件上生成 INT
    //EPwm2Regs.ETPS.bit.INTPRD = et_1st;
    EPwm2Regs.DBCTL.bit.out_mode = DB_full_enable;//启用死区模块
    EPwm2Regs.DBCTL.bit.DPWM= DPWM150
    
    
    
    
    
    ;EPwtb.EP2Rtb = EPmRtb.TRFRT2.tb.DP/ EPmREF_CTL= EPmREF_TRD = EPmCT.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tbt = EP32.Rtbt + EP2Rtbt + EP2Rtbt = EP2Rtbt + EP_Rtbt + EP2Rtbt + EP_Rtbt + EP2Rtbt + EP2Rtbt + EP_Rtbt + EP2Rtbt + EPmRtbt = EP2r.Tbt + EP2r
    
    //向上计数
    EPwm3Regs.ETSEL.bit.INTSEL = et_CTR_PRD; //在零事件
    EPwm3Regs.ETSEL.bit.INTEN = PWM3_INT_ENABLE;//启用 INT
    EPwm3Regs.ETPS.BIT.INTPRD = et_1st; //在发生第三个事件时生成 INT
    // EPwm3Regs.ETPS.bit.INTPRD = et_1st;
    EPwm3Regs.DBCTL.bit.out_mode = DB_full_enable;//启用死区模块
    EPwm3Regs.DBCTL.bit.POLSEL = DBACTV_HIC;//启用 EPwmCLRED/每
    隔150
    
    
    个 EPmREFD/ EPmCLK = DPW150;EPwmCLD/ EPmREFD/ EPmREFD/ EPmCLD/ EPmREFD/ EPmREFD/ EPmREFD/ EPmCLD/ EPmREFD/ EPmRdT = 0
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADODE;//每0加载一次寄存器
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
    EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADODE;//每0加载一次寄存器
    EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC= 1; //启动所有同步
    的定时器 EDIS;
    }
    
    
    //中断例程在此示例中使用:
    interrupt void epwm1_timer_ISR (void)
    {
    
    
    TH = TH + 6.2832 * f / 1115;// FSW = 5000
    
    if (th>=6.2832)
    {
    
    TH = TH - 6.2832;
    }
    
    A =(unsigned int)(3500 + 3500 * ma);
    b =(unsigned int)(3500 + 3500 * ma * sin (th - 2.094395));
    c =(unsigned int)(3500 + 3500 * ma * sin (th + 2.094395));
    
    
    //a =_IQsat (th - 2.094395);// a =_pinch_prd (pin_prd
    =/pin_prd)
    
    ;/pin_pin_prd = 0.599+(pin_pin_prd =/pin_pin_prd、pin_timer);/pin_pin_prd =/pin_pru_pru_prd (pin_pin_prd =/pin_pru_pru_pru_pru_pru_pru_pru_m1+、pin_pru_pru_pru+/index+、pin_pru_pru_pru_pru_pru_pru_pru_pru_m1+、pin/index+(pin_pru+/index
    
    // if (index3++>511) index3 = 0;
    
    /* sinewave1[i]=b;
    sinewave2[i]=c;
    i++;
    if (i==200)
    {
    i=0;
    
    }*/
    
    EPwm1Regs.CMPA.half.CMPA = A;
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; //将 PWM1A 设置为零
    EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;
    
    EPwm1Regs.AQCTLB.bit.CAU = AQ_SET; //将 PWM1A 设置为零
    EPwm1Regs.AQCTLB.bit.CAD = AQ_CLEAR;
    
    EPwm2Regs.CMPA.half.CMPA = b;
    
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; //将 PWM1A 设置为零
    EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;
    
    EPwm2Regs.AQCTLB.bit.CAU = AQ_SET; //将 PWM1A 设置为零
    EPwm2Regs.AQCTLB.bit.CAD = AQ_CLEAR;
    
    EPwm3Regs.CMPA.half.CMPA = c;
    
    EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR; //将 PWM1A 设置为零
    EPwm3Regs.AQCTLA.bit.CAD = AQ_SET;
    
    EPwm3Regs.AQCTLB.bit.CAU = AQ_SET; //将 PWM1A 设置为零
    EPwm3Regs.AQCTLB.bit.CAD = AQ_CLEAR;
    
    
    EPwm1TimerIntCount++;
    
    
    Voltage1[ConversionCount]= AdcResult.ADCRESULT1;//将 ADCRESULT0作为针对 rev0
    Voltage2[ConversionCount]的第一个样本勘误表的权变措施的一部分;//如果
    
    已记录转换结果
    为 ADCRESULT2= ADCR20,则将其重新开始转换
    
    ConversionCount = 0;
    }
    否则
    {
    ConversionCount++;
    }
    
    AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 ADCINT1标志重新初始化下一个 SOC
    PieCtrlRegs.PIEACK.all = PIEACK_Group1;//确认中断到 PIE
    
    
    
    
    //清除此计时器
    的 INT 标志 EPwm1Regs.ETIEEP_Group.all
    
    
    
    
    = PIEACK_3;//确认中断到 PIEPIELT.PIEACK =更多中断
    
    中断空 epwm2_timer_ISR (空)
    {
    /* EPwm2Regs.CMPA.half.CMPA = b;
    
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; //在零
    EPwm2Regs.AQCTLA.bit.CAD = AQ_SET 上设置 PWM1A;
    
    EPwm2Regs.AQCTLB.bit.CAU = AQ_SET; //将 PWM1A 设置为零
    EPwm2Regs.AQCTLB.bit.CAD = AQ_CLEAR;*/
    
    EPwm2TimerIntCount++;
    
    //清除此计时器
    的 INT 标志 EPwm2Regs.ETCLR.bit.INT = 1;
    
    //确认此中断以接收来自组3的更多中断
    // PieRegs.pi_eCRA.3*
    
    
    
    = void EP_IeCLA.C=eCLA.P3*;// EEP_IeCR.IeCLA.P=p=p=p=p=eCR.IeCR.IeCR.IES.I=3;//确认此中断=
    
    void EP3_IeCLA.3*
    
    //在零
    EPwm3Regs.AQCTLA.bit.CAD = AQ_SET 上设置 PWM1A;
    
    EPwm3Regs.AQCTLB.bit.CAU = AQ_SET; //将 PWM1A 设置为零
    EPwm3Regs.AQCTLB.bit.CAD = AQ_CLEAR;*/
    
    
    EPwm3TimerIntCount++;
    
    //清除此计时器
    的 INT 标志 EPwm3Regs.ETCLR.bit.INT = 1;
    
    //确认此中断以接收来自组3的更多中断
    // PiePieRegs.pieGroup=3;
    
    //确认此中断= IE3 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    马哈拉什

    抱歉、我之前误解了您的问题...

    我强烈建议您在合并代码时逐步添加、编译和测试。 这将使调试变得容易得多。 这听起来像是 PWM 配置没有完成、或者在添加 ADC 代码后已经改变。

    1. 单步执行您的代码、确保正在执行的 PWM 初始化代码
      1. 同时、使用存储器浏览器验证配置是否正在写入寄存器、您可能会遇到 EALLOW 问题
    2. 正确配置所有配置后、允许代码自由运行。
      1. 几秒钟后暂停代码、并使用内存浏览器再次验证 PWM 配置。 (内存中可能有其他代码会影响您的配置。
    3. 检查 PWM ISR 是否正确配置
      1. 它们是否按预期执行? 是否有可能有一个高优先级中断取代您的代码?

    此致、
    Cody  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    根据您的建议、我检查了该程序、并开始根据示例构建新程序。 我从 C2000 ware 示例中的示例程序开始。 我已经修改了它的 ePWM 计时器中断程序。 该程序工作正常、直到它仅为 SPWM、然后我使用 ADC ISR 向它添加了 ADC 代码。 问题开始后,我有两个 ADC 通道在工作,但似乎 PWM 脉冲停留在一个实例,其占空比不变。

    我使用 EPWM4触发 ADC SOC、而 EPWM1到 EPWM3用于 SPWM 生成。

    下面是我修改的代码。

    此致、

    Maharshi

    //########################################################################################################################
    //
    ////文件:example_F2802xEPwmTimerInt.c
    //
    //标题:F2802x ePWM 计时器中断示例。
    //
    //! \addtogroup example_list
    //! 

    PWM 定时器中断

    //! //! 此示例配置 ePWM 计时器并递增 //! 每次发生中断时都需要一个计数器。 //! //! 随附: //! -所有 ePWM 都已初始化。 //! -所有计时器具有相同的周期。 //! -计时器启动同步 //! //! 每个 ePWM 计时器在发生零事件时产生中断。 //! - ePWM1:在每个事件\n //! - ePWM2:每2个事件获取一次中断\n //! - ePWM3:每三个事件中获取一次中断 //! //! 因此、ePWM1和 ePWM4的中断计数应该相等。 //! ePWM2的中断计数应该大约是 ePWM1的一半、 //! ePWM3的中断计数应该大约是 ePWM1的1/3 //! //! 观察变量: //! - EPwm1TimerIntCount //! - EPwm2TimerIntCount //! -EPwm3TimerIntCount // //################################################################################################## //$TI 发行版:F2802x 支持库 v3.02.00.00 $ //$发行 日期:Sun Mar 25 13:23:09 CDT 2018 $ //版权所有: //版权所有(C) 2009-2018 Texas Instruments Incorporated - http://www.ti.com/ // 只要 满足以下条件,就允许以源代码和二进制形式重新分发和使用//修改或不修改//: // //重新分发源代码必须保留上述版权 //声明、此条件列表和以下免责声明。 // //二进制形式的再发行必须复制上述版权 //声明、此条件列表和// 分发随附的//文档和/或其他材料中的以下免责声明。 //// 未经 事先书面许可,不能使用德州仪器公司的名称或//其贡献者的名称来认可或推广源自此软件的产品//。 //// 本软件由版权所有者和贡献者提供 //“按原样”,不 承认任何明示或暗示的保证,包括但不限于//适销性和对//特定用途适用性的暗示保证。 在任何情况下、版权 //所有者或贡献者都不对任何直接、间接、偶然、 //特殊、模范、 或相应的损害(包括但不 限于采购替代产品或服务;丧失使用、 //数据或利润; 或业务中断)、无论 出于何种原因使用 本软件(即使被告知可能会造成此类损坏)、还是出于任何原因而产生的任何//责任理论(无论是合同、严格责任还是侵权行为)//(包括疏忽或其他)。 //$ //######################################################################################################################## // //包含的文件 // #include "DSP28x_Project.h" //器件头文件和示例包括文件 #include "common/include/adc.h" #include "common/include/clk.h" #include "common/include/flash.h" #include "common/include/gpio.h" #include "common/include/pie.h" #include "math/ipe.h" #include "common/包含"IQmath/ina.math" ;包含"ina.math/index";IQmath/ina.math/ina.math./ina.math./ina./ina.math./index./ina.math./ina.iq./ina.math.dl";包含文件#include #include #include;IQmath/iq./ina.math/ina.math/ina.math./ina./ina. //零度正弦 uint16 index2=170; // 120度正弦差 uint16 index3=340; // 240度正弦扩散 // //定义配置哪些 ePWM 计时器中断在 PIE //级别启用:1 =启用, 0 =禁用 // #define PWM1_INT_ENABLE 1 #define PWM2_INT_ENABLE 1 #define PWM3_INT_ENABLE 1 // //定义为每个计时器配置周期 // #define PWM1_TIMER_TBPRD 0x1FFF #define PWM2_TIMER_TBPRD 0x1FFF #define PWM3_TIMER_TBPRD 0x1FFF/#define PWM1_TBPRD/ #define PWM1_TIMER_TBPRD 0x1FFF/#define PWM1FFF/#define PWM1FFF/#define PWM1/TBPRD 函数#define PWM1FFF/#define void ADC_ISR (void); __interrupt void epwm1_timer_ISR (void); __interrupt void epwm2_timer_ISR (void); __interrupt void epwm3_timer_ISR (void); void InitEPwmTimer (void); // 全局 // uint32_t EPwm1TimerIntCount; uint32_t EPwm2TimerIntCount; uint32_t EPwm3TimerIntCount; uint16_t LoopCount; uint16_t ConversionCount; uint16_t TempSensorVoltage[10]; uint16_t ADC0、ADC1、ADC2、ADC3、 SP、平均值; uint16死区时间_R=1000; //死区时间5usec uint16死区时间_F=1000; //死区时间5usec ADC_Handle myAdc; CLK_Handle myClk; Flash_Handle myFlash; GPIO_Handle myGpio; PIE_Handle myPie; PWM_Handle myPwm1、myPwm2、myPwm3、myPwm4; void GPIO_init () { //初始化 EPWM1A 和 EPWM1B 的 GPIO GPIO_setPullUp (myGpio、GPIO_Number_0、GPIO_PULLUP_Disable); GPIO_setPullUp (myGpio、GPIO_Number_1、GPIO_PULLUP_Disable); GPIO_setMode (myGpio、GPIO_Number_0、GPIO_0_Mode_EPWM1A); GPIO_setMode (myGpio、GPIO_Number_1、GPIO_1_Mode_EPWM1B); GPIO_setDirection (myGpio、GPIO_Number_0、GPIO_Direction_Output); GPIO_setDirection (myGpio、GPIO_Number_1、GPIO_Direction_Output); //初始化 EPWM2A 和 EPWM2B 的 GPIO GPIO_setPullUp (myGpio、GPIO_Number_2、GPIO_PULLUP_Disable); GPIO_setPullUp (myGpio、GPIO_Number_3、GPIO_PULLUP_Disable); GPIO_setMode (myGpio、GPIO_Number_2、GPIO_2_Mode_EPWM2A); GPIO_setMode (myGpio、GPIO_Number_3、GPIO_3_Mode_EPWM2B); GPIO_setDirection (myGpio、GPIO_Number_2、GPIO_Direction_Output); GPIO_setDirection (myGpio、GPIO_Number_3、GPIO_Direction_Output); //初始化 EPWM2A 和 EPWM2B 的 GPIO GPIO_setPullUp (myGpio、GPIO_Number_4、GPIO_PULLUP_Disable); GPIO_setPullUp (myGpio、GPIO_Number_5、GPIO_PULLUP_Disable); GPIO_setMode (myGpio、GPIO_Number_4、GPIO_4_Mode_EPWM3A); GPIO_setMode (myGpio、GPIO_Number_5、GPIO_5_Mode_EPWM3B); GPIO_setDirection (myGpio、GPIO_Number_4、GPIO_Direction_Output); GPIO_setDirection (myGpio、GPIO_Number_5、GPIO_Direction_Output); } // Main // void main (void) { int i; cpu_handle myCpu; pll_handle myPll; WDOG_Handle myWDog; // //初始化此应用程序所需的所有句柄 // myAdc = ADC_init ((void *) ADC_base_ADDR、sizeof (ADC_Obj)); myClk = CLK_init ((void *) CLK_base_ADDR、sizeof (CLK_Obj)); myCpu = cpu_init ((void *) NULL、sizeof (cpu_Obj)); myFlash = flash_init ((void *) flash_base_ADDR、sizeof (flash_Obj)); myGpio = GPIO_init ((void *) GPIO_base_ADDR、sizeof (GPIO_Obj)); myPie = PI_init ((void *) PIE_BASE_ADDR、sizeof (PIE_Obj)); myPll = PLL_init ((void *) PLL_base_ADDR、sizeof (PLL_Obj)); myPwm1 = PWM_init ((void *) PWM_ePWM1_base_ADDR、sizeof (PWM_Obj)); myPwm2 = PWM_init (((void *) PWM_ePWM2_base_ADDR、sizeof (PWM_Obj)); myPwm3 = PWM_init ((void *) PWM_ePWM3_base_ADDR、sizeof (PWM_Obj)); myPwm4 = PWM_init ((void *) PWM_ePWM4_base_ADDR、sizeof (PWM_Obj)); myWdDog = WDOG_INIT ((void *) WDOG_BASE_ADDR、sizeof (WDOG_Obj)); // //执行基本系统初始化 // WDOG_DISABLE (myWDog); CLK_enableAdcClock (myClk); (*Device_cal)(); // //选择内部振荡器1作为时钟源 // CLK_setOscSrc (myClk、CLK_OscSrc_Internal); // //将 PLL 设置为 x10/1、这样将产生120MHz = 10MHz * 12/1 // PLL_setup (myPll、PLL_Multiplier_12、PLL_DivideSelect_CLKIN_BY_1); // //禁用 PIE 和所有中断 // PIE_DISABLE (myPie); PI_DisableAllInts (myPie); CPU_disableGlobalInts (myCpu); CPU_clearIntFlags (myCpu); // //如果从闪存运行,则只将 RAM 复制到 RAM // #ifdef _flash memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize); #endif // //设置调试矢量表并启用 PIE // PI_setDebugIntVectorTable (myPie); PIE_ENABLE (myPie); // //在 PIE 矢量表中注册中断处理程序 // PI_registerPieIntHandler (myPie、PI_GroupNumber_3、PI_SubGroupNumber_1、 (intvec_t) epwm1_timer_ISR); PI_registerPieIntHandler (myPie、PI_GroupNumber_3、PI_SubGroupNumber_2、 (intvec_t) epwm2_timer_ISR); PI_registerPieIntHandler (myPie、PI_GroupNumber_3、PI_SubGroupNumber_3、 (intvec_t) epwm3_timer_ISR); PI_registerPieIntHandler (myPie、PI_GroupNumber_10、PI_SubGroupNumber_1、 (intVec_t)&ADC_ISR); // //对于此示例,只初始化 ePWM 计时器 // // //初始化 ADC // adc_enableBandGap (myAdc); ADC_enableRefBuffers (myAdc); ADC_POWERUP (myAdc); ADC_ENABLE (myAdc); ADC_setVoltRefSrc (myAdc、ADC_VoltageRefSrc_Int); ADC_DisableTempSensor (myAdc); ADC_setIntPulseGenMode (myAdc、ADC_IntPulseGenMode_Prior); ADC_enableInt (myAdc、ADC_IntNumber_1); ADC_setIntMode (myAdc、ADC_IntNumber_1、ADC_IntMode_ClearFlag); ADC_setIntSrc (myAdc、ADC_IntNumber_1、ADC_IntSrc_EOC1); ADC_setSockChanNumber (myAdc、ADC_SockNumber_0、ADC_SockChanNumber_A0); ADC_setSockChanNumber (myAdc、ADC_SockNumber_1、ADC_SockChanNumber_A4); ADC_setSockTrigSrc (myAdc、ADC_SockNumber_0、ADC_SockTrigSrc_EPWM4_ADCSOCA); ADC_setSockTrigSrc (myAdc、ADC_SockNumber_1、ADC_SockTrigSrc_EPWM4_ADCSOCA); ADC_setSockSampleWindow (myAdc、ADC_SockNumber_0、 ADC_SockSampleWindow_37_cycles); ADC_setSockSampleWindow (myAdc、ADC_SockNumber_1、 ADC_SockSampleWindow_37_cycles); PIE_enableAdcInt (myPie、ADC_IntNumber_1); CPU_enableInt (myCpu、CPU_IntNumber_10); cpu_enableGlobalInts (myCpu); CPU_enableDebugInt (myCpu); LoopCount = 0; ConversionCount = 0; CLK_enablePwmClock (myClk、PWM_NUMBER_4); PWM_enableSockpulse (myPwm4); PWM_setSockAPulseSrc (myPwm4、PWM_SockPulseSrc_CounterEqualCmpAcincr); PWM_setSockAPeriod (myPwm4、PWM_SockPeriod_FirstEvent); (((PWM_Obj *) myPwm4)->CMPA = 0x0800; PWM_setPeriod (myPwm4、0xFFFF); PWM_setCounterMode (myPwm4、PWM_CounterMode_Up); InitEPwmTimer(); // //初始化计数器 // EPwm1TimerIntCount = 0; EPwm2TimerIntCount = 0; EPwm3TimerIntCount = 0; GPIO_init(); // //启用连接到 EPWM1-6 INT 的 CPU INT3 // CPU_enableInt (myCpu、CPU_IntNumber_3); // //在 PIE 中启用 ePWM INTn:组3中断1-6 // PIE_enablePwmInt (myPie、PWM_NUMBER_1); PIE_enablePwmInt (myPie、PWM_NUMBER_2); PIE_enablePwmInt (myPie、PWM_NUMBER_3); // //启用全局中断和更高优先级的实时调试事件 // cpu_enableGlobalInts (myCpu); CPU_enableDebugInt (myCpu); CLK_enableTbClockSync (myClk); for (;;) { _asm (" NOP"); for (i=1;i<=10;i++) { } } // // InitEPwmTimer - // 空 InitEPwmTimer() { // //停止所有 TB 时钟 // clk_disableTbClockSync (myClk); CLK_enablePwmClock (myClk、PWM_NUMBER_1); CLK_enablePwmClock (myClk、PWM_NUMBER_2); CLK_enablePwmClock (myClk、PWM_NUMBER_3); CLK_enablePwmClock (myClk、PWM_NUMBER_4); // //设置同步 // PWM_setSyncMode (myPwm1、PWM_SyncMode_EPWMxSYNC); PWM_setSyncMode (myPwm2、PWM_SyncMode_EPWMxSYNC); PWM_setSyncMode (myPwm3、PWM_SyncMode_EPWMxSYNC); PWM_setSyncMode (myPwm4、PWM_SyncMode_EPWMxSYNC); // //允许同步每个计时器 // PWM_enableCounterLoad (myPwm1); PWM_enableCounterLoad (myPwm2); PWM_enableCounterLoad (myPwm3); PWM_enableCounterLoad (myPwm4); PWM_setPhase (myPwm1、0); PWM_setPhase (myPwm2、0); PWM_setPhase (myPwm3、0); PWM_setPeriod (myPwm1、PWM1_TIMER_TBPRD); PWM_setCounterMode (myPwm1、PWM_CounterMode_Up); //向上计数 // //选择“零时 INT”事件 // PWM_setIntMode (myPwm1、PWM_IntMode_CounterEqualZero); PWM_enableInt (myPwm1); //启用 INT // //在发生第一个事件时生成 INT // PWM_setIntPeriod (myPwm1、PWM_IntPeriod_FirstEvent); PWM_setPeriod (myPwm2、PWM2_TIMER_TBPRD); PWM_setCounterMode (myPwm2、PWM_CounterMode_Up); //向上计数 // //启用“零时 INT”事件 // PWM_setIntMode (myPwm2、PWM_IntMode_CounterEqualZero); PWM_enableInt (myPwm2); //启用 INT // //在发生第2个事件时生成 INT // PWM_setIntPeriod (myPwm2、PWM_IntPeriod_SecondEvent); PWM_setPeriod (myPwm3、PWM3_timer_TBPRD); PWM_setCounterMode (myPwm3、PWM_CounterMode_Up); //向上计数 // //启用“零时 INT”事件 // PWM_setIntMode (myPwm3、PWM_IntMode_CounterEqualZero); PWM_enableInt (myPwm3); //启用 INT // //在发生第三个事件时生成 INT // PWM_setIntPeriod (myPwm3、PWM_IntPeriod_ThirdEvent); //向上计数 PWM_setActionQual_CntUp_CmpA_PwmA (myPwm1、PWM_ActionQual_set); //在事件 A 上设置 PWM1A、递增计数 PWM_setActionQual_CntDown_CmpA_PwmA (myPwm1、PWM_ActionQual_clear);//在事件 A 上清除 PWM1A、递减计数 PWM_setActionQual_CntUp_CMPB_PwmB (myPwm1、PWM_ActionQual_clear); //在事件 B 上设置 PWM1B,向上计数 PWM_setActionQual_CntDown_CMPB_PwmB (myPwm1、PWM_ActionQual_set);//在事件 B 上清除 PWM1B、递减计数 //设置死区控制 PWM_setDeadBandOutputMode (myPwm1、PWM_DeadBandOutputMode_EPWMxA_Rising EPWMxB_Falling); PWM_setDeadBandPolarity (myPwm1、PWM_DeadBandPolarity _EPWMxB_Inverted); PWM_setDeadBandInputMode (myPwm1、PWM_DeadBandInputMode_EPWMxA_rising_and_Falling); PWM_setActionQual_CntUp_CmpA_PwmA (myPwm2、PWM_ActionQual_set); //在事件 A 上设置 PWM1A、递增计数 PWM_setActionQual_CntDown_CmpA_PwmA (myPwm2、PWM_ActionQual_clear);//在事件 A 上清除 PWM1A、递减计数 PWM_setActionQual_CntUp_CMPB_PwmB (myPwm2、PWM_ActionQual_clear); //在事件 B 上设置 PWM1B,向上计数 PWM_setActionQual_CntDown_CMPB_PwmB (myPwm2、PWM_ActionQual_set);//在事件 B 上清除 PWM1B、递减计数 //设置死区控制 PWM_setDeadBandOutputMode (myPwm2、PWM_DeadBandOutputMode_EPWMxA_Rising EPWMxB_Falling); PWM_setDeadBandPolarity (myPwm2、PWM_DeadBandPolarity _EPWMxB_Inverted); PWM_setDeadBandInputMode (myPwm2、PWM_DeadBandInputMode_EPWMxA_RISE_AND_FALLING); PWM_setActionQual_CntUp_CmpA_PwmA (myPwm3、PWM_ActionQual_set); //在事件 A 上设置 PWM1A、递增计数 PWM_setActionQual_CntDown_CmpA_PwmA (myPwm3、PWM_ActionQual_clear);//在事件 A 上清除 PWM1A、递减计数 PWM_setActionQual_CntUp_CMPB_PwmB (myPwm3、PWM_ActionQual_clear); //在事件 B 上设置 PWM1B,向上计数 PWM_setActionQual_CntDown_CMPB_PwmB (myPwm3、PWM_ActionQual_set);//在事件 B 上清除 PWM1B、递减计数 //设置死区控制 PWM_setDeadBandOutputMode (myPwm3、PWM_DeadBandOutputMode_EPWMxA_Rising EPWMxB_Falling); PWM_setDeadBandPolarity (myPwm3、PWM_DeadBandPolarity _EPWMxB_Inverted); PWM_setDeadBandInputMode (myPwm3、PWM_DeadBandInputMode_EPWMxA_RISE_AND_FALLING); PWM_setDeadBandRisingEdgeDelay (myPwm1、死区时间_R); PWM_setDeadBandFallingEdgeDelay (myPwm1、死区时间_F); PWM_setDeadBandRisingEdgeDelay (myPwm2、DeadTime_R); PWM_setDeadBandFallingEdgeDelay (myPwm2、死区时间_F); PWM_setDeadBandRisingEdgeDelay (myPwm3、死区时间_R); PWM_setDeadBandFallingEdgeDelay (myPwm3、死区时间_F); // //启动所有同步的计时器 // CLK_enableTbClockSync (myClk); } // //中断例程在此示例中使用 // // //// epwm1_timer_ISR - // __interrupt void epwm1_timer_ISR (void) { EPwm1TimerIntCount++; // //清除此计时器的 INT 标志 // // //确认此中断以接收来自组3的更多中断 // PI_clearInt (myPie、PI_GroupNumber_3); } // epwm2_timer_ISR - // _中断 void epwm2_timer_ISR (void) { EPwm2TimerIntCount++; // //清除此计时器的 INT 标志 // PWM_clearIntFlag (myPwm2); // //确认此中断以接收来自组3的更多中断 // PI_clearInt (myPie、PI_GroupNumber_3); } // epwm3_timer_ISR - // _中断 void epwm3_timer_ISR (void) { EPwm3TimerIntCount++; // //清除此计时器的 INT 标志 // PWM_clearIntFlag (myPwm3); // //确认此中断以接收来自组3的更多中断 // PI_clearInt (myPie、PI_GroupNumber_3); } _interrupt void ADC_ISR (void) { TempSensorVoltage[转换计数]= ADC_readResult (myAdc、 ADC_ResultNumber_1); PWM_setCmpA (myPwm1、_IQsat (_IQ30mpy ((sine_table[索引]+_IQ30 (0.9999)))/2、EPWM1_TIMER_TBPRD)、EPWM1_TIMER_TBPRD、0); PWM_setCmpB (myPwm1、_IQsat (_IQ30mpy ((sine_table[索引]+_IQ30 (0.9999)))/2、EPWM1_TIMER_TBPRD)、EPWM1_TIMER_TBPRD、0); PWM_setCmpA (myPwm2、_IQsat (_IQ30mpy ((sine_table[index2]+_IQ30 (0.9999)))/2、EPWM1_TIMER_TBPRD)、EPWM1_TIMER_TBPRD、0); PWM_setCmpB (myPwm2、_IQsat (_IQ30mpy ((sine_table[index2]+_IQ30 (0.9999)))/2、EPWM1_TIMER_TBPRD)、EPWM1_TIMER_TBPRD、0); PWM_setCmpA (myPwm3、_IQsat (_IQ30mpy ((sine_table[index3]+_IQ30 (0.9999)))/2、EPWM1_TIMER_TBPRD)、EPWM1_TIMER_TBPRD、0); PWM_setCmpB (myPwm3、_IQsat (_IQ30mpy ((sine_table[index3]+_IQ30 (0.9999)))/2、EPWM1_TIMER_TBPRD)、EPWM1_TIMER_TBPRD、0); 索引++; 索引2++; 索引3++; 如果(index++>511)索引=0; 如果(index2++>511)索引2=0; if (index3++>511) index3=0; // //如果记录了20次转换,则重新开始 // if (ConversionCount = 9) { ConversionCount = 0; } 其他 { ConversionCount++; } PWM_clearIntFlag (myPwm1); ADC_clearIntFlag (myAdc、ADC_IntNumber_1); PI_clearInt (myPie、PI_GroupNumber_10); 返回; } // //文件结束 //

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    马哈拉什
    您的 ISR 代码有多长时间? 您的 ISR 是否可能需要很长时间才能执行、以至于它在 ISR 返回之前已经接收到另一个中断?
    它可能会阻止您的其余代码执行。 添加到 ADC 部件时、PWM 初始化代码仍在运行。 使用内存浏览器读取 PWM 配置并确认正常。

    此致、
    Cody