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/TMS320F2.8335万:为什么ADC模块每2个周期采样一次?

Guru**** 2558250 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/634398/ccs-tms320f28335-why-the-adc-module-sample-every-2-cycle

部件号:TMS320F2.8335万
主题中讨论的其他部件:CSD9.7396万Q4M

工具/软件:Code Composer Studio

你(们)好

问题1:  

 程序 正在运行,我 可以看到GPIO32 每 隔1个Us更改级别。  

但是   

EPwm2Regs.ETSEL.bit.SOCASEL = 4;//在显示计数时从CPMA中选择SOC

// 在计时器递增时启用等于CMPA的事件时基计数器


EPwm2Regs.TBPRD =75;//为ePWM2设置期间

GPIO32  改变 每 位0.5 Us的级别的结果是否正确?

   

#include "DSP28x_Project.h"//设备头文件和示例包括文件
包含"math.h"

typedef结构

易失性结构ePWM_regs *EPwmRegHandle;

} ePWM_INFO;

#define ADC_USDELAY 5000L

void InitEPwm1示例(void);

void gPIO_SELECT (void);
void update_compare(ePWM_info*);
void InitEPwm1Gpio(void);
中断无效ADC_ISR(void);

ePWM_INFO epwm1_info;


#define CPU_FRQ_150MHz 1.

浮点KP=30;
浮子套件=25;

UINT16 EPwmMaxCMPA;
UINT16环计数;
UINT16转换计数;
浮点电流0[10];

float current_mathet[10];
浮点max_current;
浮子u[2];
浮点e[2];
浮动u_change;
浮子N=10;


Void主(void)

UINT16 I;


InitSysCtrl();
gPIO_SELECT();

EALLOW;
//默认值- 150 MHz SYSCLKOUT
#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)= 25.0 MHz
EDIS;


EALLOW;
SysCtrlRegs.HISPPCP.ALL = ADC_MODCLK;
EDIS;


Initepwm1gpio();


色调;


InitPieCtrl();

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


InitPieVectorTable();

EALLOW;//这是写入EALLOW保护寄存器所必需的
PieVectorTable.ADCINT =&ADC_ISR;
EDIS;//这是禁用写入EALLOW保护寄存器所必需的


InitAdc();

PieCtrlRegs.PIEIER1.bit.INTx6=1;
IER || M_INT1;//启用CPU中断1
EINT;//启用全局中断INTM
ERTM;//启用全局实时中断DBGM


LoopCount = 0;
ConversionCount = 0;
e[0]=0;
e[1]=0;
u[0]=0;
U[1]=0;
最大电流=0;
GpioDataRegs.GPBSET.ALL =0x0万;
GpioDataRegs.GPBCLEAR.ALL =0x0.0001万;

用于(i=0;i<N;i++)

当前0[i]=0;

}


EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
InitEPwm1Example();
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;


//配置ADC
AdcRegs.ADCMAXCONV.ALL = 0x0000;//在SEQ1上设置2个conv
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;//将ADCINA0设置为第一个SEQ1转换

AdcRegs.ADCTRL2.bit.ePWM_SOCA_SEQ1 = 1;//从ePWM启用SOCA以启动SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;//启用SEQ1中断(每个EOS)

//假定ePWM2时钟已在InitSysCtrl()中启用;
EPwm2Regs.ETSEL.bit.SOCAEN = 1;//在组上启用SOC
EPwm2Regs.ETSEL.bit.SOCASEL = 4;//在显示计数时从CPMA中选择SOC
EPwm2Regs.ETPS.bit.SOCAPRD = 1;//在第一个事件上生成脉冲
EPwm2Regs.CMPA.Halt.CMPA = 30;// set比较一个值
EPwm2Regs.TBPRD =75;//为ePWM2设置期间
EPwm2Regs.TBCTL.bit.CTRMODE =0;//开始计数


//步骤6。 空闲循环。 只需坐下来永远循环(可选):
对于(;;)

ASM (" NOP");
}

}

中断无效ADC_ISR(void)

current0[ConversionCount]= AdcRegs.ADCRESULT0 >>4;
GpioDataRegs.GPBTOGLE.ALL =0x0.0001万;


IF (ConversionCount == N-1)

ConversionCount = 0;
LoopCount++;
}
Else ConversionCount++;

IF (LoopCount==4)
{update_compare (&epwm1_info);}


//为下一个ADC序列重新初始化
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;//重置SEQ1
AdcRegs.ADCST.Bit.INT_SEQ1_CLR = 1;//清除INT SEQ1位
PIECtrlRegs.PIEACK/ALL = PIEACK_Group1;//确认中断到PIE

}

void InitEPwm1example()

//设置TBCLK
EPwm1Regs.TBPRD =750;
EPwm1Regs.TBPHS.Half.TBPHS = 0x0000;//相位为0
EPwm1Regs.TBCTR = 0x0000;//清除计数器

//设置比较值
EPwm1Regs.CMPA.Halp.CMPA =40;

EPwm1Regs.CMBB =710;

EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UDOWN;//对称
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLED;//禁用相加载
EPwm1Regs.TBCTL.bit.PRDLD = TB_shadow;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;


EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;// TBCLK = SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

//设置阴影
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHAME;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADO;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CBD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;

epwm1_info.epwmRegHandle =&EPwm1Regs;//将指针设置到ePWM模块

}

void update_compare (ePWM_INFO *ePWM_INFO)

int i;
最大电流=0;

用于(i=0;i<N;i++)
{ current_mathety[I]=(current0[I]-2274)/4096*3/ACL;<xmt-block0>4096   0.2 // 采样电阻为0.01Ω,Ω,放大20次,将其更改为 电流。  

max_current=max_current+fabs (current_mathet[i]);   

}
max_current=max_current/N; 1.1107    // 计算  平均值 并将其更改为有效值

e[1]=1-max_current;       // 使用PI算法, 但 电流的振幅为1 A 。为什么?   max_current是有效值。  

u_change=kP*(e[1]-e[0])+Kit*e[1];
u[1]=u[0]+u_change/180*750;
如果(u[1]>738){ u[1]=738;}
如果(u[1]<12){ u[1]=12;}
EPwmMaxCMPA=u[1]/2;
ePWM_INFO_>EPwmRegHandle->CMPA.Half.CMPA=EPwmMaxCMPA;
ePWM_INFO_>EPwmRegHandle->CMPB=750-EPwmMaxCMPA;
u[0]=u[1];
e[0]=e[1];
最大电流=0;
LoopCount=0;
//返回;
}


void gPIO_SELECT (void)


EALLOW;
gpioCtrlRegs.GPBMUX1.ALL = 0x0万000000;0万;//所有GPIO
gpioCtrlRegs.GPBMUX2.all = 0x0万;//所有GPIO
GpioCtrlRegs.GPBDIR.ALL = 0x0万F;//所有输出
EDIS;

}

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

    TIANQING LI
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    ADC模块是否可以使用FIFO程序?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    天清

    检查您的TBCTL寄存器值,尤其是HSPCLKDIV字段:

    ADC使用SOC序列发生器,可配置为按FIFO的方式运行:

    有关 详细信息,请参阅ePWM和ADC用户指南。

    汤米

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Tommy,
    感谢你的帮助。 我添加了一些代码:


    EPwm2Regs.TBPHS.Half.TBPHS = 0x0000; //相位为0
    EPwm2Regs.TBCTR = 0x0000; //清除计数器
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;//开始计数
    EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLED;//禁用相加载
    EPwm2Regs.TBCTL.bit.PRDLD = TB_shadow;
    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
    EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;


    而且效果很好。 但由于中断,采样频率最大为1 MHz。 我想使用FIFO功能来帮助我。 但结果寄存器的数目是16。 只有16个数据太少。 所以我把"ADC_ISR()"放到"main()"。


    对于(;;)

    while (AdcRegs.ADCST.bit.INT_SEQ1= 0){}
    current0[ConversionCount]= AdcRegs.ADCRESULT0 >>4;
    GpioDataRegs.GPBTOGLE.ALL =0x0.0001万;

    //如果记录了40个转换,请重新开始
    IF (ConversionCount == N-1)

    ConversionCount = 0;
    LoopCount++;
    }
    Else ConversionCount++;

    IF (LoopCount==4)
    {update_compare (&epwm1_info);}


    //为下一个ADC序列重新初始化
    // AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; //重置SEQ1
    AdcRegs.ADCST.Bit.INT_SEQ1_CLR = 1; //清除INT SEQ1位
    PIECtrlRegs.PIEACK/ALL = PIEACK_Group1;//确认中断到PIE
    }

    采样频率最大为2MHz。

    您对如何提高采样频率有什么建议吗?
    感谢你的帮助。

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

    天清

    您能否描述您想要的使用行为?  例如,您需要多少MSPS?  ADC转换是应在特定频率持续触发还是需要在隔离时间采集一组样本?  您是否正在尝试重建交流信号或只是为了获得更好的精度而进行过采样?

    汤米

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    汤米
    1.我要测量100kHz时的电流有效值。 所以我每隔1微秒抽样一次数据,然后抽样40次。 然后我计算平均值并将其更改为有效值,然后更改PWM的参数。 计算过程可能需要10微秒。 它的成本为50微秒。

    2.我希望至少每隔0.5 微秒获得一次数据,但不成功。

    3.错误:“我将“ADC_ISR()"放在“main()"中。 采样频率最大为2MHz。 "
    事实上,采样频率最大为1MHz。

    4.我计算平均值并将其更改为有效值,但它不成功。 我想将有效值更改为1A,但电流的振幅为1A


    TIANQING LI
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我想通过测量RLC电路中的采样电阻的电压来测量电流。 我连接了10uH电感,5.6Ω Ω 电阻和0.247uF电容。 采样电阻为0.01 Ω Ω。
    然后提供DH1718D-4的10V电源。 PWM1和PWM2发送100kHz信号,占空比为50 %。
    使用两个CSD9.7396万Q4M
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    汤米
    问题4在我更改仿真器后得到解决。 数据也很好,虽然采样频率为1MHz。 感谢你的帮助。
    e2e.ti.com/.../63.3388万
    TIANQING LI
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    天清

    您可以尝试在双序列发生器模式下使用CPU轮询和脉冲缓冲来增加ADC吞吐量。

    例如:

    1. 将SEQ1和SEQ2配置为使用所有八个可用的SOC转换ADC信道
    2. 软件触发器SEQ1
    3. 轮询SEQ1_BSY标志以确定SEQ1何时完成
    4. 软件触发器SEQ2
    5. 对SEQ1结果执行计算或将结果复制到缓冲区
    6. 轮询SEQ2_BSY标志以确定SEQ2何时完成
    7. 软件触发器SEQ1
    8. 对SEQ2结果执行计算或将结果复制到缓冲区
    9. 返回步骤3

    汤米