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.

[参考译文] TMS320F28055控制器中的 ADC

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1126839/adc-in-tms320f28055-controller

主题中讨论的其他器件:TMS320F28055

大家好、


我对 TMS320F28055控制器上的 ADC 有疑问。 我将一个100千欧姆电位器(3.3V)连接到 ADC。 出于测试目的、我采用了 TI 的示例。 我想在计时器中断时触发 ADC、因此我设置位 AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 1、1是计时器0如果我像示例中那样运行程序、我还可以在调试模式下看到 ADCRESULT0值发生变化。 是否有人知道为什么值在我尚未初始化 Timer0的情况下发生变化? 另一个问题是如何触发我的 ADC 中断? 我在调试模式中看到、完全不调用中断、但 ADCRESULT0值发生变化。 当我将电位计一直向上转动时、我只看到值3796、这是否意味着 ADC 校准不正确? 很抱歉有很多问题、但这是我第一次将 ADC 与 TI 控制器搭配使用。


感谢你的帮助

// Included Files
//
#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

//
// Function Prototypes
//
__interrupt void adc_isr(void);


//
// Global variables
//
Uint16 LoopCount;
Uint16 ConversionCount;
Uint16 Voltage1[10] = {0,0,0,0,0,0,0,0,0,0};
Uint16 Voltage2[10];

main()
{
    //
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2805x_SysCtrl.c file.
    //
    InitSysCtrl();

    //
    // Step 2. Initialize GPIO:
    // This example function is found in the F2805x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
    // InitGpio();  // Skipped for this example

    //
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
    DINT;

    //
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2805x_PieCtrl.c file.
    //
    InitPieCtrl();

    //
    // Disable CPU interrupts and clear all CPU interrupt flags
    //
    IER = 0x0000;
    IFR = 0x0000;

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the __interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2805x_DefaultIsr.c.
    // This function is found in F2805x_PieVect.c.
    //
    InitPieVectTable();


    //
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    //
    EALLOW;  // This is needed to write to EALLOW protected register
    PieVectTable.ADCINT1 = &adc_isr;
    EDIS;    // This is needed to disable write to EALLOW protected registers

    //
    // Step 4. Initialize all the Device Peripherals:
    //
    InitAdc();  // For this example, init the ADC
    AdcOffsetSelfCal();

    //
    // Step 5. User specific code, enable __interrupts:
    //
    // Enable ADCINT1 in PIE
    //
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;   // Enable INT 1.1 in the PIE
    IER |= M_INT1;                       // Enable CPU Interrupt 1
    EINT;                                // Enable Global __interrupt INTM
    ERTM;                            // Enable Global realtime __interrupt DBGM

    LoopCount = 0;
    ConversionCount = 0;

    //
    // Configure ADC
    // Notes:
    // Channel ADCINA4  will be double sampled to workaround the ADC 1st
    // sample issue for rev0 silicon errata.
    // Due to round-robin, SOC0 converts first, then SOC1, then SOC2
    //

    EALLOW;
    AdcRegs.ADCCTL1.bit.INTPULSEPOS= 1; //ADCINT1 trips after AdcResults latch
    AdcRegs.INTSEL1N2.bit.INT1E    = 1; //Enabled ADCINT1
    AdcRegs.INTSEL1N2.bit.INT1CONT = 0; //Disable ADCINT1 Continuous mode
    AdcRegs.INTSEL1N2.bit.INT1SEL  = 2; //setup EOC2 to trigger ADCINT1
    AdcRegs.ADCSOC0CTL.bit.CHSEL   = 4; //set SOC0 channel select to ADCINA4
//    AdcRegs.ADCSOC1CTL.bit.CHSEL   = 4; //set SOC1 channel select to ADCINA4
//    AdcRegs.ADCSOC2CTL.bit.CHSEL   = 2; //set SOC2 channel select to ADCINA2
    AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 1;  //TIMER0 //set SOC0 start trigger on EPWM1A
//    AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 5; //set SOC1 start trigger on EPWM1A
//    AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 5; //set SOC2 start trigger on EPWM1A
    AdcRegs.ADCSOC0CTL.bit.ACQPS   = 9; //SOC0 S/H Window = 10 (9+1) Clk Cycles     SAMPLE Size
//    AdcRegs.ADCSOC1CTL.bit.ACQPS   = 9; //SOC0 S/H Window = 10 (9+1) Clk Cycles
//    AdcRegs.ADCSOC2CTL.bit.ACQPS   = 9; //SOC0 S/H Window = 10 (9+1) Clk Cycles
    EDIS;


    //
    // Wait for ADC __interrupt
    //
    for(;;)
    {
      LoopCount++;
    }
}



__interrupt void  adc_isr(void)
{
    //
    //Discard ADCRESULT0 as part of the workaround to rev0's 1st sample errata
    //
    Voltage1[ConversionCount] = AdcResult.ADCRESULT0;
//    Voltage2[ConversionCount] = AdcResult.ADCRESULT2;

    //
    // If 10 conversions have been logged, start over
    //
    if(ConversionCount == 9)
    {
        ConversionCount = 0;
    }
    else
    {
        ConversionCount++;
    }

    //
    // Clear ADCINT1 flag reinitialize for next SOC
    //

    AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge __interrupt to PIE

    return;

}

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

    Markus、您好!

    我将把这个问题转交给 ADC 专家以获得支持。 您是否了解了 C2000 Academy 资源(https://dev.ti.com/tirex/global?id=c2000Academy)?)中的 ADC 培训我们还提供了 ADC 视频培训系列、可在此处(https://training.ti.com/analogue-digital-converter-adc-training-c2000-mcus)找到。

    此致、

    Peter

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

    Markus、您好!

    [~ userid="525350" URL"/support/microcontrollers/C2000-microcontrollers-group/C2000/f/C2000-microcontrollers-forum/1126839/ADC-in-tms320f28055-controller"]即使我尚未初始化 Timer0、是否有人知道值为何会发生变化? [/报价]

    您观察到的值在哪个范围内?

    [引用 userid="525350" URL"~/support/microcontrollers/C2000-microcontrollers-group/C2000/f/C2000-microcontrollers-forum/1126839/ADC-in-tms320f28055-controller"]当我一直打开电位器时、我只能看到值3796、这是否意味着 ADC 校准错误?

    您是否确认了 ADC 引脚上的实际电压?

    此致、

    Marlyn

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

    您好、Marlyn、

    在0伏时、我得到 ADCRESULT 0的值、大约为3.3V 3800。 我使用万用表测量了电压。 我仍然不理解的是我的 ADC 为什么会触发。 我已经将 Timer0设置为触发源、即使我根本没有初始化 Timer0。 这是怎么可能的? 以及如何调用 ADC 中断。

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

    谢谢您、我将介绍一下

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

    Markus、您好!

    [~ userid="525350" URL"/support/microcontrollers/C2000-microcontrollers-group/C2000/f/C2000-microcontrollers-forum/1126839/ADC-IN-tms320f28055-controller/4180505#4180505"]0伏时、我得到 ADCRESULT 0的值、电压大约为3.3V。 我使用万用表测量了电压。 我仍然不理解的是我的 ADC 为什么会触发。 我已经将 Timer0设置为触发源、即使我根本没有初始化 Timer0。 这是怎么可能的? 以及如何调用 ADC 中断。[/quot]

    在继续调试不同的触发器选项之前、我想澄清一下您是否可以使用"原样"示例获取正确的 ADC 读数。 如果您在导入示例时未进行任何软件更改、并且您将输入连接到 ADCINA4、您在电压1中看到正确的结果吗?

    此致、

    Marlyn

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

    您好、Marlyn、

    我导入了该示例、但没有进行任何软件更改。 我只将触发源更改为 TIMER0、因为我不使用 PWM 输出。 我可以看到 ADC 转换为 ADCRESULT0。 我不理解为什么不调用 ADC 中断。 据我所知、ADC 中断始终在 AD 转换后调用。 我看到它被转换、但由于 Voltage1未被填充、ADC 中断未被调用。

    我注意到我不需要 ADC 中断、因为我只想使用 Poti 设置一个设定点、但知道为什么不调用中断仍然很有趣。

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

    Markus、您好!

    [~ userid="525350" URL"/support/microcontrollers/C2000-microcontrollers-group/C2000/f/C2000-microcontrollers-forum/1126839/ADC-in-tms320f28055-controller/4180505#4180505"]我还不知道的是我的 ADC 触发原因。 我已经将 Timer0设置为触发源、即使我根本没有初始化 Timer0。 这是怎么可能的? 以及如何调用 ADC 中断。[/quot]

    TIMER0TCR 寄存器的 TSS (定时器停止状态)位默认设置为0 (CPU 定时器正在运行)、由于您没有配置 CPU 定时器、周期值为0。 这会导致计时器始终如一地触发 ADC。 如果使用周期值配置计时器、则应看到正确的触发频率。 此外、如果您将 TSS 位设置为1、则会注意到 ADC 转换停止。

    ADC 中断(ADCINT1)映射到 ADC ISR。 使用下面的代码行、SOC2的转换结束就是导致中断发生的原因。 由于该示例使用 SOC0、SOC1和 SOC2、因此在全部3个结果完成后希望存储结果是合乎逻辑的。  

    //
    //设置 EOC2以触发 ADCINT1触发
    //
    AdcRegs.INTSEL1N2.bit.INT1SEL = 2;

    此致、

    Marlyn