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读取三个电压?

Guru**** 2540720 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/616553/ccs-tms320f28335-how-to-read-three-voltages-using-adc

部件号:TMS320F2.8335万

工具/软件:Code Composer Studio

你好  

我修改了ADC_SOC示例,使其能够读取三个电压值:

__interrupt void ADC_ISR(void);

UINT16 Voltage1;
UINT16 Voltage2;
UINT16 Voltage3;

void main(void){

InitSysCtrl();




EALLOW;
#define ADC_MODCLK 0x3;
EDIS;


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

色调;
InitPieCtrl();

IER = 0x0000;
IFR = 0x0000;

InitPieVectorTable();

InitCpuTimers();//在此示例中,仅初始化CPU计时器

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

InitAdc();//在此示例中,初始化ADC
PieCtrlRegs.PIEIER1.bit.INTx6=1;
IER |= M_INT1; //启用CPU中断1
EINT; //启用全局中断INTM
ERTM; //启用全局实时中断DBGM

//

LoopCount = 0;
ConversionCount = 0;

//
//配置ADC
//
AdcRegs.ADCMAXCONV.ALL = 0x0003; //在SEQ1上设置2个conv
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2;//将ADCINA2设置为第一个SEQ1转换
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3;//将ADCINA3设置为2nd SEQ1 Conv.
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x4;
//
//从ePWM启用SOCA以启动SEQ1
//
AdcRegs.ADCTRL2.bit.ePWM_SOCA_SEQ1 = 1;

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;//启用SEQ1中断(每个EOS)

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

__interrupt void
ADC_ISR(void)
{
Voltage1 = AdcRegs.ADCRESULT0 >>4;
Voltage2 = AdcRegs.ADCRESULT1 >>4;
Voltage3 = AdcRegs.ADCRESULT2 >>4;
电流=电压1-电压2;
电压=电压2-电压3;

//
//如果记录了40个转换,请重新开始
//

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

返回;
}

1.读取这些值后,我使用(voltage*3/4095)得到一个0-3V的值,但是我得到的值有一个小错误,而且不精确,请问我的代码是否有问题?

2.另外,当我们编写(#define ADC_MODCLK 0x3;)时,我知道我们将ADC时钟分配为25MHz,我的问题是如何更快地读取ADC值? (因为在数据表中它表示ADC SoC为80ns)

此致,

ATA

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

    您好,

    ATA Khiabani 说:
    1.读取这些值后,我使用(voltage*3/4095)得到一个介于0-3V之间的值,但是我得到的值有一个小错误并且不准确,请问我的代码是否有问题?[/QUOT]

    变化有多大? 请告诉我们一个想法。

    ATA Khiabani 说:
    2.另外,当我们编写(#define ADC_MODCLK 0x3;)时,我知道我们将ADC时钟分配为25MHz,我的问题是如何更快地读取ADC值? (因为在数据表中它表示ADC SoC为80ns)[/QUOT]

    采样率似乎最快。 这是最大速度!

    此致,

    Gautam

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    变化的顺序是0.1 电压,但当我使用电压分压器读取较高的电压时,变化的顺序是1V。

    如果这是最大速度,那么为什么在Lab6的车间中有一个示例,其中ePWM2触发ADC时使用周期20.833 Us (48kHz)?
    processors.wiki.ti.com/.../C2000_Archived_Workshops

    如何触发ADC以更快的速度读取值? 我需要能够每10次读取ADC。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果这是最大速度,那么在Lab6的WorkShop中,如何有一个示例,其中ePWM2使用Period 20.833 Us (48kHz)触发ADC?
    processors.wiki.ti.com/.../C2000_Archived_Workshops

    这完全取决于您的TBPRD值。 现在我可以看到您的TBPRD值是0xFFFF,这是最慢的。 您需要将其降低到一个非常低的值,即50/100。 请检查ePWM用户指南中的公式,以根据TBPRD值计算频率。

    如何触发ADC以更快的速度读取值? 我需要能够每10次读取ADC。[/QUOT]

    请计算TBPRD值,使Fpwm = 100kHz

    此致,

    Gautam

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

    分压器使用的电阻值是多少?

    您是否正在缓冲电压,以便ADC S/H CAP可以在ACQ_PS窗口中充电? 您也可以尝试使用更大的ACQ_PS窗口来查看读数是否有所改善。

    汤米
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢你。 假设我要每3秒读取一次ADC,因此根据公式:
    TBRD=(TBRD*150e6)/(30万)=250 0.5
    因此,如果我写:
    EPwm1Regs.TBPRD = 0x549;
    它应该正常工作,对吗?
    我是否还需要更改"EPwm1Regs.CMPA.Halp.CMPA"?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我没有缓冲电压,我使用放大器将电压缩放在0和3之间,然后将其馈入ADC。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    ATA,

    运算放大器充当信号缓冲器。  运算放大器和ADC之间是否有串联电阻器?  电阻越小越好。

    我不是在关注您如何将0x549编程到TBPRD注册表。  250十进制= 0xFA十六进制。

    设置触发频率时CMPA值无关紧要。  它只需要小于TBPRD。  当ADC在ePWM期间触发时,具有同步要求的应用程序可以更改CMPA值以进行微调。

    汤米

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    由于我要读取的电压将介于-3V和3V之间,因此我使用两个运算放大器,首先添加一个电压(例如 3.56 V),我使用三个100K电阻器,其次使用1.8K和4.7K将电压范围调整为0和3V。
    但是,当我使用反向过程(即放大电压减去附加电压)时,使用ADC读取电压后,我得到了不正确的结果。

    假设我要读取元件上的压降:

    __中断无效
    ADC_ISR (无效)

    Voltage1 = AdcRegs.ADCRESULT0 >>4;
    Voltage2 = AdcRegs.ADCRESULT1 >>4;
    电压=电压1-电压2;

    //
    //如果记录了40个转换,请重新开始
    //

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

    返回;
    }

    在我的主要环节中,我已经:
    Vol1 =(((VOLT*3)/4095)* 2.611)- 3.56 ;

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

    4.7kΩ Ω 是为ADC S/H盖充电的大阻抗。 如果您有另一个运算放大器可用,我建议缓冲分压器输出,以帮助更快地为ADC S/H CAP充电。 增加ACQ_PS也可以帮助一些人。

    我还建议您在ADC输入上使用示波器来验证信号是否能够在ACQ_PS窗口结束之前稳定。

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

    ADC参考指南中对此进行了说明

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果我想每隔1秒读取一次ADC,我应该选择:
    EPwm1Regs.TBPRD = 0x4B
    我的问题是,我能这么快地读取ADC吗? 我的意思是,它是否能够做到这一点?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    ATA,

    ADC将能够跟上1MSPS的速度。 CPU也应该能够跟上,但它将对处理带宽造成重大影响。 实现缓冲比在每个ADC结果就绪后立即对其执行操作更好。

    例如,如果定序器设置为连续运行,则ADC可以以1MSPS的速度累积多个采样,然后在序列完成时可以一次读取所有结果。 DMA也可配置为将样品移动到内存,无需CPU干预。

    汤米
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    请您详细解释一下我如何做到这一点吗?
    如何更改我的代码?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    ATA,

    研讨会的实验9有一个使用DMA进行ADC缓冲的示例。

    汤米