工具/软件: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;
}