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/TMS320F28377S:PWM 频率不是根据计算得出的

Guru**** 2487425 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/680038/ccs-tms320f28377s-pwm-frequency-is-not-as-per-calculation

器件型号:TMS320F28377S

工具/软件:Code Composer Studio

主席先生,

我的频率接近1kHz。 频率、我需要至少20kHz 的频率。 我不想更改 ePWM 2的 TBPRD 寄存器、因为它将影响占空比的分辨率 w.r.t PWM 周期。 这是 ADC 到 PWM 转换的代码、Im 正在处理。

请说明如何更改 PWM 的频率。 我使用了技术参考手册第页上提供的代码 110个 TMS320F2837xS Delfino 微控制器来更改 imult、fmult、PLL、epwmclkdiv、但频率没有增加到我希望得到的太多值。

//######################################################################################################################
//文件:  adc_soc_ePWM_cpu01.c
//标题: 针对 F2837xS 通过 ePWM 触发 ADC。
//
//! addtogroup cpu01_example_list
//!

ADC ePWM 触发(ADC_SoC_ePWM)


//!ADC 引脚27 PWM 输出80
//! 此示例设置 EPWM 以定期触发 ADC。
//!
//! 程序运行后,内存将包含:\n
//! -\b 结果:一系列的模数转换样本
//! 引脚 A0。 采样之间的时间根据周期确定
//! PWM 计时器的功能。
//
//######################################################################################################################
//$TI 发行版:F2837xS 支持库 v190美元
//$Release Date:Mon Feb1 16:59:09 CST 2016 $
//版权所有:版权所有(C) 2014-2016 Texas Instruments Incorporated -
//            http://www.ti.com/ 保留所有权利$
//######################################################################################################################

#include "F28x_Project.h"    //设备头文件和示例 include 文件

void ConfigureADC (void);
void ConfigureEPWM (void);
void InitEPwm2Examples(void);
_interrupt void epwm2_tzint_ISR (void);
void InitEPwmGpio_TZ (void);

void InitTzGpio (void);

void SetupADCepwm (uint16通道);
中断 void adca1_ISR (void);

用于存储转换结果的//缓冲区
#define results_buffer_size 256
uint16 AdcaResults[results_buffer_size];
uint16结果索引;
uint32 EPwm2TZIntCount;
uint16伏特;
易失性 uint16 bufferFull;

void main (void)

//步骤1. 初始化系统控制:
// PLL、安全装置、启用外设时钟
//此示例函数位于 F2837xS_SYSCTRL.c 文件中。
   InitSysCtrl();

//步骤2. 初始化 GPIO:
//此示例函数位于 F2837xS_GPIO.c 文件和中
//说明了如何将 GPIO 设置为其默认状态。
   InitGpio();//针对此示例跳过
   CpuSysRegs.PCLKCR2.bit.EPWM2=1;
   InitTzGpio();
   InitEPwmGpio_TZ ();

//步骤3. 清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
   Dint;

//将 PIE 控制寄存器初始化为默认状态。
//默认状态为禁用所有 PIE 中断和标志
//被清除。
//此函数位于 F2837xS_PIECTRL.c 文件中。
   InitPieCtrl();

//禁用 CPU 中断并清除所有 CPU 中断标志:
   IER = 0x0000;
   IFR = 0x0000;

//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使是中断也是如此
//在本例中未使用。  这对于调试很有用。
//可以在 F2837xS_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 F2837xS_PieVect.c 中找到
   InitPieVectTable();

//映射 ISR 函数
   EALLOW;
   PieVectTable.ADCA1_INT =&adca1_ISR;//针对 ADCA 中断1的函数
   PieVectTable.EPWM2_TZ_INT =&epwm2_tzint_ISR;
   EDIS;
       EALLOW;
          ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL=0x1;
          ClkCfgRegs.SYSPLLMULT.bit.IMULT=50;
          ClkCfgRegs.SYSPLLMULT.bit.FULT=0x2;
          ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV=1;
          ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1;
          ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV=1;
      //   ClkCfgRegs.PERCLKDIVSEL.bit.PERCLKDIVSEL=68;

       CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =0;
       EDIS;
       InitEPwm2Examples();
       EALLOW;
       CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1;
       EDIS;
       EPwm2TZIntCount = 0;


//配置 ADC 并为其加电
   ConfigureADC();

//配置 ePWM
   ConfigureEPWM();

//Setup the ADC for ePWM triggered Conversions on channel 0
   SetupADCepwm (0);

//启用全局中断和更高优先级的实时调试事件:
   IER |= M_INT1;//启用组1中断
   IER |= M_INT2;

   EINT; //启用全局中断 INTM
   ERTM; //启用全局实时中断 DBGM

//初始化结果缓冲区
   for (resultsIndex = 0;resultsIndex < results_buffer_size;resultsIndex++)
   {
       AdcaResults[resultsIndex]=0;
   }
   resultsIndex = 0;
   bufferFull = 0;

//启用 PIE 中断
   PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
   PieCtrlRegs.PIEIER2.bit.INTx2 = 1;

//SYNC ePWM
   EALLOW;
   CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1;

//循环无限地进行转换
   操作
   {
       //启动 ePWM
       EPwm1Regs.ETSEL.bit.SOCAEN = 1; //启用 SOCA
       EPwm1Regs.TBCTL.bit.CTRMODE = 0;//取消冻结、并进入递增计数模式

       //等待、而 ePWM 导致 ADC 转换、然后导致中断、
       //填充结果缓冲区,最终设置 bufferFull
       //flag
       while (!bufferFull);
       bufferFull = 0;//清除缓冲区已满标志

       //停止 ePWM
       EPwm1Regs.ETSEL.bit.SOCAEN = 0; //禁用 SOCA
       EPwm1Regs.TBCTL.bit.CTRMODE = 3;//冻结计数器

       //此时,AdcaResults[]包含一系列转换
       //从所选通道

       //软件断点,再次点击运行以获取更新的转换
       //asm ("  ESTOP0");
       EINT; //启用全局中断 INTM
       ERTM; //启用全局实时中断
   } while (1);


//写入 ADC 配置并为 ADC A 和 ADC B 加电
空配置 ADC (空)

   EALLOW;

   //写入配置
   AdcaRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4
   AdcSetMode (ADC_ADCA、ADC_resolution_12位、ADC_SIGNALMODE_SINGLE);

   //将脉冲位置设置为晚期
   AdcaRegs.ADCCTL1.bit.INTPULSEPOS=1;

   //为 ADC 加电
   AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;

   //延迟1ms 以允许 ADC 加电时间
   DELAY_US (1000);

   EDIS;


空配置 EPWM (空)

   EALLOW;
   //假设 ePWM 时钟已启用
   EPwm1Regs.ETSEL.bit.SOCAEN = 0;           //禁用组上的 SOC
   EPwm1Regs.ETSEL.bit.SOCASEL = 4;           //在递增计数时选择 SOC
   EPwm1Regs.ETPS.bit.SOCAPRD = 1;            //在发生第一个事件时生成脉冲
   EPwm1Regs.CMPA.bit.CMPA = 0x0800;         //将比较 A 值设置为2048个计数
   EPwm1Regs.TBPRD = 0x1000;                  //将周期设置为4096个计数
   EPwm1Regs.TBCTL.bit.CTRMODE = 3;           //冻结计数器
   EDIS;


void SetupADCepwm (uint16通道)

   uint16 acqps;

   //根据分辨率确定最小采集窗口(在 SYSCLKS 中)
   if (adc_resolution_12bit = AdcaRegs.ADCCTL2.bit.resolution){
       acqps = 14;//75ns
   }
   否则{//分辨率为16位
       acqps = 63;//320ns
   }

   //选择要转换的通道和转换结束标志
   EALLOW;
   AdcaRegs.ADCSOC0CTL.bit.CHSEL =通道; //SOC0将转换引脚 A0
   AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps;//采样窗口为100个 SYSCLK 周期
   AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;// ePWM1 SOCA/C 上的触发
   AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;// SOC0结束将设置 INT1标志
   AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;  //启用 INT1标志
   AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//确保 INT1标志被清除


中断 void adca1_ISR (void)

   AdcaResults[resultsIndex++]= AdcaResultRegs.ADCRESULT0;
   if (results_buffer_size <= resultsIndex)
   {
       resultsIndex = 0;
       bufferFull = 1;
   }
   VOLT= AdcaResultRegs.ADCRESULT0;
   SET_DUTY (伏特);
   AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 INT1标志
   PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;



void set_duty (int a)

   EPwm2Regs.CMPA.bit.CMPA = A;


空 InitEPwm2Examples()

   //启用 TZ1作为一个逐周期触发源
   EALLOW;
   EPwm2Regs.TZSEL.bit.CBC1 = 1;

   //我们希望 TZ1执行什么操作?
   EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_HI;

   //启用 TZ 中断
   EPwm2Regs.TZEINT.BIT.CBC = 1;
   EDIS;

   EPwm2Regs.TBPRD = 4096;                      //设置定时器周期
   EPwm2Regs.TBPHS.bit.TBPHS = 0x0000;          //相位为0
   EPwm2Regs.TBCTR = 0x0000;                    //清除计数器

   //设置 TBCLK
   EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;//向上计数
   EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;       //禁用相位加载
   EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4;      //时钟与 SYSCLKOUT 的比率
   EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV4;         //慢、只在示波器上观察

   //设置比较
 // EPwm2Regs.CMPA.bit.CMPA = 3000;

   //设置操作
   EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;            //在 CAU 上设置 PWM2A
   EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;          //清除 CAD 上的 PWM2A


_interrupt void epwm2_tzint_ISR (void)

   GpioDataRegs.GPATOGGLE.bit.GPIO11=1;

   EPwm2TZIntCount++;

   //清除标记-我们将继续执行
   //此中断直到 TZ 引脚变为高电平
   EALLOW;
   EPwm2Regs.TZCLR.bit.CBC = 1;
   EPwm2Regs.TZCLR.bit.INT = 1;
   EDIS;

   //确认此中断以接收来自组2的更多中断
   PieCtrlRegs.PIEACX.ALL = PIEACK_group2;


空 InitTzGpio (空)

   //对于外部触发器,GPIO12作为 TripZone 的触发器
   GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0;   //启用 GPIO12上的上拉电阻(TZ1)

   GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 3; //异步输入 GPIO12 (TZ1)

   EALLOW;
   InputXbarRegs.INPUT1SELECT = 12;
   EDIS;

   //用于监视何时进入 TZ 中断
   EALLOW;
   GpioCtrlRegs.GPAPUD.bit.GPIO11 = 1;   //禁用 GPIO0上的上拉电阻(EPWM1A)
   GpioCtrlRegs.GPAMUX1.bit.GPIO11 = 0;  //将 GPIO0配置为 EPWM1A
   GpioCtrlRegs.GPADIR.bit.GPIO11=1;
   EDIS;


空 InitEPwmGpio_TZ (空)

   EALLOW;
 // GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1;   //禁用 GPIO0 (EPWM1A)上的上拉电阻
 // GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;  //将 GPIO0配置为 EPWM1A
   GpioCtrlRegs.GPAPUD.bit.GPIO2 = 1;   //禁用 GPIO2上的上拉电阻(EPWM2A)
   GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;  //将 GPIO2配置为 EPWM2A
   EDIS;


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

    Deepak Kumar98、您好!

    您能否显示用于计算 ePWM TBPRD 的公式(及其输入的值)?

    您的 SYSCLK 和 EPWMCLK 频率是多少?

    此致、

    Kris