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.

[参考译文] TMS320F28335:F28335:ADC 中断/SOCA / ISR 执行时间/ GPIO 频率不匹配

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/565365/tms320f28335-f28335-adc-interrupt-soca-isr-execution-time-gpio-frequency-mismatch

器件型号:TMS320F28335

尊敬的所有人:

我分别使用同步模式在 ADCINA5和 ADCINB5上执行电压和电流测量。 SOCA 位由 ePWM1模块生成、该模块处于占空比为50%的递增计数模式。 此外、当 COMPA 和时基计数器(递增时)匹配时、会生成 SOCA 位。  PWM 波形符合预期。

我还在 ADC ISR 内获得适当的 ADC 读数、因此我现在尝试测量 ISR 执行时间。 为此、我在 ISR 开始处设置 GPIO、在 ISR 结束时清除 GPIO。 但是、我的测量结果显示、进入 ISR 的频率要比生成 EPWM 的频率高得多。 我在 ISR 内连接了 PWM 波形(品红色、50%占空比、死区时间约为600ns)和 GPIO 波形(蓝色)。

我还根据在阅读 SPRU812A 和  SPRAAP6A 文档时的理解附加了我的理论波形。

有什么关于我做错的事情的想法吗? 非常感谢。

/*
* 23. 2016年11月:现在的开环-仅 PWM 生成-未实现相移
* 13. 2016年12月:将程序添加到闪存功能
* 16. 2016年12月:添加了*
04的开环 PWM 生成相移。 2017年1月:添加了 ADC 测量值-待续
*/

#include "DSP28x_Project.h"

void InitialADC();
void InitePWM1();
void InitePWM2();
void InitePWM5();
void InitePWM6();
_interrupt void ADC_ISR ();

//闪存功能
extern UINT16 RamfuncsLoadStart;
extern UINT16 RamfuncsLoadEnd;


//变量
#define DT 100 // Dead time calc:DT = value/CLKfreq -> 100/150MHz = 66ns UINT16








(Uint16);//初始化当前的看门狗计数(Uint16);void int16) Uint16 (Uint16);t int16)

//用于编程到闪存
Memcopy (&RamfuncsLoadStart、&RamfuncsLoadEnd、&RamfuncsRunStart);

//初始化 ePWM
InitEPwmGpio();

//初始化 PIE 控制寄存
器 InitPieCtrl();

IER = 0x0000;
IFR = 0x0000;

//初始化 ePIE 矢量表到默认 ISR InitPieCtrl()
;EPIE

矢量

表;/ADVectPIE = 0x0000.EPIE 矢量表


//设置 ADC 采样率
EALLOW 的第一步;
SysCtrlRegs.HISPCP。all = 3;// HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)= 25.0MHz
EDIS;

// InitSysCtrl()函数中已完成同步->要求 SYCLKCLK


= 150/(2*3)位来验证 InsteCLKCLKCLKCLK;//要求 InstaSPCLKCLKCLK = 2* SYCLKCLKCLKCLKCLKCLKCLK = 0;//要求支持 InstaSPCLKCLKCLKCLKCLKCLK =//启用时基时钟与来自 DSP
EDIS 的 SYSCLKOUT 同步;
*/

InitFlash();
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;//组1、位6用于 ADC
IER |= M_INT1;//设置组1
EINT 的中断使能位;//启用全局中断 INTM

转换计数= 0;//初始化计数

//初


始化 ADC 初始化阶段(= 102);/临时转换

InitePWM1();
InitePWM2();
InitePWM5();
InitePWM6();

/*
*将 GPIO4设置为输出以测量 ISR 内的执行时间
*/
EALLOW;
//将 GPIO10设置为 GPIO -已在 InitGpio()
GpioCtrlRegs.GPAMUX1.bit.GPIO4=0;
//将 GPIO10设置为输出
GpioDataRegs.GPADIR =









1;void
= GPIO4 = 1;GPIO.GPIO4 = 1;GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIO.GPIOR.GPIOR.GPIOR.GPIOR.GPIO

Voltage1[ConversionCount]= AdcRegs.ADCRESULT0 >>4;//从 ADCINA5读取值
Current[ConversionCount]= AdcRegs.ADCRESULT1 >>4;//从 ADCINB5读取值

//如果已记录128次转换,则从
if (ConversionCount = 127)开始

ConversionCount = 0;
}
否则
{
ConversionCount++;
}

//
*计算两个桥之间的临时位置
*/
EPwm5Regs.TBPHS.half.TBPHS =临时位置;
EPwm6Regs.TBPHS.half.TBPHS =临时位置;

//重新初始化下一个 ADC
AdcRegs.ADCTRL2.bit.RCLR.1




;GPWMP1.Q1 =中断位/GPIORET.Q1 = GPIORET.Q1 =中断1;// GPIORET.Q1 =中断1 = GPIORET.SEQ1.GPIORET.Q1 =中断1;// GPIORET.Q1 = GPIORET.USTRS.P1/中断1 =中断1 =中断1;GPACT.SEQ1.POR = GPIOREQ =中断1 =中断1

void InitialADC (void)
{
//配置 ADC
AdcRegs.ADCTRL3.bit.ADCCLKPS= 12;//设置 ADC 采样率:25MHz/(2*12+1)= 1MHz
AdcRegs.ADCTRL1.bit.SEQ_CASC=0;//设置级联模式 AdcRegs.ADCL1.ADCMT.1/ ADCL1.ADCMT.R1.ADCMT.R1.ADCMT.R1.ADCMT.R1.ADCMT.CONT_ADR1.ADCMT.R1.ADCMT.R1.ADCMT.R1.ADCMT.R1.ADCMT.R1.ADCMT.R1.ADR1.ADCMT.R1.ADCMP1.ADCMP1.ADCMP1.ADCMP1.ADCMP1.ADCMP1.ADCMP1.ADCMT.CONT_ADR1.ADCMP1.ADCMP1.ADCMP1.ADCMP1.ADCMP1.ADCMP1.



//一个转换
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 5;// ADCINA5和 ADCINB5
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;//中断请求被启用
}

void InitePWM1 (void)
{
//为 ADC 测量启用 SOCA
EPwm1Regs.ETSEL.bit.SOCAEN = 1;//启用 SOCA
EPwm1Regs.ETSEL.bit.SOCASEL = 4; //生成占空比为50%的 SOCA 脉冲
EPwm1Regs.ETPS.bit.SOCAPRD = 1; //在第一个事件

EPwm1Regs.TBPRD = 1499;//设置 PWM 周期时间
EPwm1Regs.CMPA.Half.CMPA =(1499+1)/2;
EPwm1Regs.TBPHS.Half.TBPHHS = 0;//将相位寄存器设置为零 EPwm1Regs.TBR
=


0;EPwtbtb.CTL = 0;EPwtb.tb.tb.tb.tb.tb.tb.tb.tb.tb.tb.tb.tb.tb.tb = 0 //同步下行模块
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;//将时基时钟设置为 SYSCLKOUT
EPwm1Regs.CMPCTL.bit.SHHDWAMOPRD = CC_SHADDLOW;
EPwm1Regs.bit.SHDCMOCTL.R=0=AMWCLT.AMOCRD.0
;EPwCMOCTR

= 0;EPwCMOCTL.R=ADDR.OD=ADRd_0;EPwCMOCTR = ADRd.Rd.Rd.Rd.Rd=OCT.Rd_0;EPwCMOD=0;EPwCMOCT.Rd=ADRd.Rd.Rd.Rd_ODCMODCMOCT.Rd=ADRd.Rd.Rd.//设置引脚当 CTR=PRD
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR 时;//清除引脚当 CTR=COMPA


EPwm1Regs.DBCTL.bit.IN_MODE = 0时;// ePWMxA 源用于下降沿和上升沿 EPwm1Regs.DBCTL.bit.IN_MODE = 0;





//启用 EPwdb.DP.DP.DP.EEPwdB=FREDP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.=满;}EPwmREF_DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.

void InitePWM2 (void)
{
EPwm2Regs.TBPRD = 1499;//设置 PWM 周期时间
EPwm2Regs.CMPA.Half.CMPA =(1499+1)/2;
EPwm2Regs.TBPHS.Half.TBPHPHS = 0;//将相位寄存器设置为零
EPwm2Regs.TBRtb.CTL



= 0;EPwtb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb = 0//将时基时钟设置为 SYSCLKOUT
EPwm2Regs.CMPCTL.bit.SHHDWAMODE = CC_SHADDADE;
EPwm2Regs.CMPCTL.bit.SHHDWBMODE = CC_SHADDADDOR.CMPCTL.BIT.ODE
= 0;// EPwm2REQTR.CLA.0=AMR

= EPmCTR = 0;当 EPwCLA.R
= EP_ADRD.CMPO.RP.0= EPmRT.AMODCMPO.R = 0或 EPmRT.AMODCMODCMPO.RC.0= EPmRC.0= EPmRDP=AMRT.AMR = EPmRDP.RC.0=AMRDP=AMRDP.RDP=AMRDP.RC.0/ RDP=AMRDP=AMRDP//设置引脚当 CTR=COMPA


EPwm2Regs.DBCTL.bit.IN_MODE = 0时;// EPwm2Regs.DBCTL.bit.OUT_MODE
= DB_FULL_ENABLE;// DB FULL ENABLE
EPwm2Regs.DBCTL.bit.EPwdT





= void EPwd5

;= EPwd2 = void EPwd2;// EPwd2 EPwd2 = void EPwd2 EPwd5 REDP.EPwdT = void EPwdT = void EPwd2;// EPwd2//设置 PWM 周期时间
EPwm5Regs.CMPA.half.CMPA =(1499+1)/2;
EPwm5Regs.TBPHS.half.TBPHS = 0;//将相位寄存器设置为零
EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;// EPwtbT.TBR
= EPwtb.Tb.TbT.TbT.CTL = EPwt.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tb.Tp = 0

。
EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;//同步下行模块
EPwm5Regs.TBCTL.bit.HSPCLKDIV = 0;//将时基时钟设置为 SYSCLKOUT EPwm5Regs.SHDWCTL.bit.HSPCLA.RDC=0
;EPwCMDR.OCRD=0=OCC.ODR.ODR.OCTR
=


0;EPwCMDR.OCR.OCTR = 0;EPwCMDR.OCR.OCR.OCR.OCR.ODR.ODR.ODR.OCR.OCR.ODR.ODR.ODR.OCR.OCR.ODR.OCR.O= 0;OCR.OCTR = 0;EPwCMOCR.OCR.OCR.OCR.OCR.OCR.OCR.OCR.OCR.OCR.OST.OCR.//当 CTR=PRD
EPwm5Regs.AQCTLA.bit.CAU = AQ_SET 时清除引脚;//当 CTR=COMPA


EPwm5Regs.DBCTL.bit.IN_MODE = 0时设置引脚;// EPwm5Regs.DBCTL.bit.IN_MODE = 0;// EPwmDP.DP.DP.DP.EEPwDP.DP.=
FULL




;// EPwdBLD.DP.DP.DP.DP.EPT.DP.DP.DP.DP.DP.EEPwDP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.

void InitePWM6 (void)
{
EPwm6Regs.TBPRD = 1499;//设置 PWM 周期时间
EPwm6Regs.CMPA.half.CMPA =(1499-1)/2;
EPwm6Regs.TBPHS.Half.TBPHPS= 0;//将相位寄存器设置为零 EPwmCR.TBR2.TBR2.TBIT.TBIT.TBIT.TCMRTE.TBR2.TBIT.TBIT.TBIT.TCMP=

0;EP6TBIT.TBIT.TBIT.TBIT.TBIT.TAM.TAM.TCCT.TL.TL.TBIT.TBIT.TBIT.TBIT.TBIT.TL.TBIT.TBIT.TBIT.TCMPSN = UCTS/ TBIT.TBIT.TBIT.TBIT.TBIT.TAM.TAM.TAM.TAM.TAM.TAM.TAM.TAM.TCMP= EP6位 EP6位 EP


//将时基时钟设置为 SYSCLKOUT
EPwm6Regs.CMPCTL.bit.SHHDWAMODE = CC_SHADDADE;
EPwm6Regs.CMPCTL.bit.SHHDWBMODE = CC_SHADDADDOR.CMPCTL.BIT.ODE
= 0;// EPwmCTR


= 0=AMRD.0=AMR = EPwCLA.Rd/ PO.RT.AMRP.0= EPmCTR = EPmRP.0=BIT.AMRC.0= EPmCTR = EPmRdRP.0/ PO.R = EPmRT.AMODA.RT.AMODCMODCMOD=BIT.AMRC.0= 0;//在位= EPmRC.0=AMRT.AMRT.AMR = EPwCMPO.RT.AMRT.AMR//在 CTR=COMPA


EPwm6Regs.DBCTL.bit.IN_MODE = 0时清除引脚;// EPwm6Regs.DBCTL.bit.OUT_MODE
= DB_FUL_ENABLE;// DB FULL ENABLE EPwm6Regs.DBCTL.bit.EPwDP.DP.DP.DP.DP.DP.EEPwSEL
=高电平;



// EPwDP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.DP.

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

    您好、Alexander、

    我认为您不希望设置 CONT_RUN 位。  我认为这会导致 ADC 在启动后持续运行、而不是在每个 ePWM 事件发生后触发。

    与您的问题不直接相关、但您可能还希望将 ADCCLK 从1MHz 增加到12.5MHz 或25MHz 等更标称值。  我们有一个勘误表、说明以低时钟频率运行 ADC 可能会导致性能问题:

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

    亚历山大

    不确定。  您能否通过将这些行移动到 for ()循环之前的位置开始:

    PieCtrlRegs.PIEIER1.bit.INTx6=1;//组1,ADC 的位6 
    IER |= M_INT1;//设置组1
    EINT 的中断使能位;//启用全局中断 INTM 

    按照您现在的方式、中断处于活动状态并在您初始化这些外设之前修改 PWM 寄存器。  我想知道初始化是否因某种原因而损坏。

    此致、

    Richard

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Devin 和 Richard、您好!
    感谢您的回复、这有助于我解决问题。 现在、我将根据我的第一篇文章中的理论图获得波形。 非常感谢您的参与。

    不过、为了更好地理解 ADC 模块、我有几个关于此问题的问题。
    1.我将 Cont_Run 位设置为0、以便在启动/停止模式下操作 ADC、从而降低进入 ISR 的频率。 但是、根据我的理解、我认为进入 ISR 将取决于 ePWM 寄存器中的 SOC 位。 尽管 ADC 将持续运行、但当 ePWM 寄存器设置 SOCA 位时、将进入 ISR、该位设置为当 COMPA 和时基计数器匹配时发生。 这种特定场景发生在 PWM 频率下、因此我希望 ISR 频率在设置 CONT_RUN 时独立于 PWM 相同。 很明显、我的理解并不完全正确、所以请您详细说明我的想法吗?

    2.我将 ADCCLK 增加到8.33MHz (而最初为1MHz)、这进一步提高了我的 ADC 性能。 我不会猜测查看 ADCCLK、因此感谢您的提示。 但是、我选择1MHz 是有原因的。 我正在使用您的 controlCARD、其原理图显示了一个56 Ω 和3.3nF 的 RC 滤波器。 这将产生184ns 的时间常数、因此 DSP 上的 ADC 引脚在5*Tau = 5*184ns=924ns 时看到完整的测量电压。 据我了解、我需要将 ADC 频率设置得足够低、以满足这些924ns 的要求。 大约为1MHz、除非我的理解和计算完全关闭。 实际上、我的想法得到了证实、因为将 ADCCLK 增加到25MHz 会在 ADC 测量中产生错误的值。 因此、考虑到 RC 滤波器、我想我需要尽可能低。 我对这个特定问题的理解是否正确? 如果您也可以详细说明这一点、那将会很有帮助。

    祝你一切顺利、
    亚历山大
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我认为 CONT_RUN 设置发生的情况是、第一个 ePWM 触发器启动 ADC 运行、然后它会尽可能快地在序列发生器周围循环、因此与 ePWM 频率无关的更快中断。 清除该位后、每个触发器启动一组转换、ADC 在完成一个序列时停止。 然后、在 ISR 结束时发出一些指令来重置序列发生器。

    2、这里正确的做法是、您需要考虑 ADC 输入稳定时间、ADCCLK 是控制它的一种方法。

    此处的计算如下:

    如果外部电容器大于4096*4*Cadc,则所有外部电荷都来自外部电容器,以将输入稳定在1/4LSB 以内,我们可以忽略外部 RC 时间常数,只需使用最小 S+H 窗口持续时间。 (我们可以使用最小 S+H 时间、但需要限制采样率、以防止外部电容器从每个采样事件中缓慢耗尽。) 这至少为4096*4*11.64pF = 191nF。 (有关内部 ADC C 值、请参阅 DS 图5-38。 ADC 模拟输入阻抗模型)。 该电容太小、因此我们使用替代计算...

    系统的 RC 时间常数可近似为(Rs+Ron)*Ch + Rs*CP,其中
    RS = 56
    CP = 3.3nF + 10pF = 3.3nF
    CH = 1.64pF
    Ron = 1k Ω
    因此、τ= 187ns (几乎是您拥有的、由于内部 RC 效应、略高)

    我们通常需要1/4 LSB 趋稳、分辨率为12位、因此我们需要-ln (0.25*(1/4096)= 9.7 TAMUS

    因此、S+H 时间应为1.814us

    要控制 S+H 时间、您可以调整 ADCCLK 和 ACQ_PS 值。 ACQ_PS 仅调整 S+H 时间、而不调整其余转换时间、因此这是更好的方法。 ACQ_PS 的最大值为15、因此 S+H 时间为16个 ADCCLK。 这意味着 ADCCLK 最多需要(1/1.814ns)*16=8.8MHz。 因此、您应该在8.333MHz ADCCLK 上运行良好、只需确保将 ACQ_PS 设置为最大值(如果尚未设置)。
x 出现错误。请重试或与管理员联系。