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.

在LAUNCHXL-F280049C LaunchPad Kit 設定ADC

Other Parts Discussed in Thread: LAUNCHXL-F280049C, C2000WARE

硬體使用的是 LAUNCHXL-F280049C LaunchPad Kit

目前參考的文件為SPRUI33C

參考的程式範例為

"C2000ware_2_00_00_02/driverlib/f28004x/examples/adc/adc_ex1_soc_software"

"C2000ware_2_00_00_02/driverlib/f28004x/examples/adc/adc_ex2_soc_epwm"

"C2000ware_2_00_00_02/driverlib/f28004x/examples/adc/adc_ex3_temp_sensor"

讀取的值會有亂跳的現象,以及當我同時使用ADCA, ADCB, ADCC BASE 會有一些通道並沒有辦法讀取資料

可否請教有人可以教教我讀取ADC

程式碼如下:

void initADCs(void)

{

    //

    // Setup VREF as internal

    //

    ADC_setVREF(ADCA_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);

    ADC_setVREF(ADCB_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);

    ADC_setVREF(ADCC_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);

    //

    // Set ADCCLK divider to /4

    //

    ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_1_0);

    ADC_setPrescaler(ADCB_BASE, ADC_CLK_DIV_1_0);

    ADC_setPrescaler(ADCC_BASE, ADC_CLK_DIV_1_0);

    //

    // Set pulse positions to late

    //

    ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV);

    ADC_setInterruptPulseMode(ADCB_BASE, ADC_PULSE_END_OF_CONV);

    ADC_setInterruptPulseMode(ADCC_BASE, ADC_PULSE_END_OF_CONV);

    //

    // Power up the ADC and then delay for 1 ms

    //

    ADC_enableConverter(ADCA_BASE);

    ADC_enableConverter(ADCB_BASE);

    ADC_enableConverter(ADCC_BASE);

    DEVICE_DELAY_US(1000);

}

void initADCSOCs(void)

{

    //

    // Configure SOC0 of ADCA to convert pin A0 with a sample window of 10

    // SYSCLK cycles. The EPWM1SOCA signal will be the trigger.

    //

    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA,

                 ADC_CH_ADCIN0, 10);

    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA,

                 ADC_CH_ADCIN2, 10);

    //

    // Set SOC1 to set the interrupt 1 flag. Enable the interrupt and make

    // sure its flag is cleared.

    //

    ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER1);

    ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);

    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

    ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA,

                 ADC_CH_ADCIN2, 10);

    ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA,

                 ADC_CH_ADCIN3, 10);

    //

    // Set SOC1 to set the interrupt 1 flag. Enable the interrupt and make

    // sure its flag is cleared.

    //

    ADC_setInterruptSource(ADCB_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER1);

    ADC_enableInterrupt(ADCB_BASE, ADC_INT_NUMBER1);

    ADC_clearInterruptStatus(ADCB_BASE, ADC_INT_NUMBER1);

}

    ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER0);

    ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER2);

    ADC_forceSOC(ADCB_BASE, ADC_SOC_NUMBER2);

    ADC_forceSOC(ADCB_BASE, ADC_SOC_NUMBER3);

    ADC_forceSOC(ADCC_BASE, ADC_SOC_NUMBER4);

    adcBResult3 = (AdcbResultRegs.ADCRESULT3);

    for(Delay_FOR_ANY=0; Delay_FOR_ANY<1; Delay_FOR_ANY++){}

    adcAResult0 = (AdcaResultRegs.ADCRESULT0);

   for(Delay_FOR_ANY=0; Delay_FOR_ANY<1; Delay_FOR_ANY++){}

    adcAResult2 = (AdcaResultRegs.ADCRESULT2);

    for(Delay_FOR_ANY=0; Delay_FOR_ANY<1; Delay_FOR_ANY++){}

    adcAResult6 = (AdcaResultRegs.ADCRESULT6);

    for(Delay_FOR_ANY=0; Delay_FOR_ANY<1; Delay_FOR_ANY++){}

    adcBResult2 = (AdcbResultRegs.ADCRESULT2);

    for(Delay_FOR_ANY=0; Delay_FOR_ANY<1; Delay_FOR_ANY++){}

    adcCResult0 = (AdccResultRegs.ADCRESULT0);

    for(Delay_FOR_ANY=0; Delay_FOR_ANY<1; Delay_FOR_ANY++){}

    adcCResult2 = (AdccResultRegs.ADCRESULT2);

   for(Delay_FOR_ANY=0; Delay_FOR_ANY<1; Delay_FOR_ANY++){}

    //AdcbRegs.ADCOFFTRIM.bit.OFFTRIM = addoffset;

    adcAResult0 = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);

    adcAResult2 = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER2);

    adcAResult6 = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER6);

    adcBResult2 = ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER2);

    adcBResult3 = ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER3);

    adcCResult0 = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER0);

    adcCResult2 = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER2);

 PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

  • “讀取的值會有亂跳的現象,以及當我同時使用ADCA, ADCB, ADCC BASE 會有一些通道並沒有辦法讀取資料”

    能否详细说明一下?

    另外若是可以的话,请上传或者私信给我您的整个工程?我明天拿板子测试一下,谢谢
  • 請問我該私信到哪個信箱呢?
    在線等~
  • 点击我的头像到我的个人页面,而后点击右面的 连接 按钮
  • 已經在信了,是否有收到呢?
    在線等~
  • 刚刚收到了,我会在下载后测试
  • 我测试了一下,结果如下

    不知道您的结果是否也是这样?

    我现在的输入信号是0-2V的正弦波,当不加任何信号input时,也是这样的结果

    根据现象看的话,应该是您现在的程序中存在问题,导致了没有实际采集到input

  • 要是测量A0 内部温度传感器的话,例程内是需要加外部参考电压 3.3V的

    能否告知下您现在的测试结果?
  • 對,其結果並沒有實際採集到輸入源
  • A0的通道是否也可以把其當作一般的ADC通道?我並沒有要測量內部溫度傳感器
  • 可以的,在例程adc_ex1_soc_software中就是使用的A0
  • 不過我設定的是範例的程式。
    是不是有哪些功能沒有始能?
  • 这个需要调试后了解,我会稍后回复

    请问您现在是要实现什么功能呢? 您的实验结果是和我的一样吗?
  • 我的實驗結果是Adcaregs維持在4095,Adcbregs, adccregs維持在0
    我要的功能是各通道都可以讀取輸入源。
  • void initADCs(void)
    {
    ADC_setInterruptPulseMode(ADCA_BASE,
    ADC_PULSE_END_OF_CONV);
    ADC_enableConverter(ADCA_BASE);
    ADC_isBusy(ADCA_BASE);
    ADC_setPrescaler(ADCA_BASE,
    ADC_CLK_DIV_4_0);
    ADC_disableBurstMode(ADCA_BASE);
    //ADC_setBurstModeConfig(ADCA_BASE,ADC_TRIGGER_EPWM1_SOCA,0xF);
    ADC_getInterruptStatus(ADCA_BASE,
    ADC_INT_NUMBER1);
    ADC_getInterruptOverflowStatus(ADCA_BASE,
    ADC_INT_NUMBER1);
    ADC_enableInterrupt(ADCA_BASE,
    ADC_INT_NUMBER1);
    ADC_setInterruptSource(ADCA_BASE,
    ADC_INT_NUMBER1,
    ADC_SOC_NUMBER0);
    ADC_enableContinuousMode(ADCA_BASE,
    ADC_INT_NUMBER1);

    ADC_setVREF(ADCA_BASE,
    ADC_REFERENCE_INTERNAL,
    ADC_REFERENCE_3_3V);
    //ADC_setInterruptCycleOffset();

    AdcaRegs.ADCINTSEL1N2.bit.INT2CONT = 0;
    AdcaRegs.ADCINTSEL1N2.bit.INT2E = 0; // 0:disable, 1:enable
    AdcaRegs.ADCINTSEL1N2.bit.INT2SEL = 0x0; // ADCINT2 EOC source select
    AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 1;
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; // 0:disable, 1:enable
    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0x0;

    ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER0);

    ADC_setInterruptSOCTrigger(ADCA_BASE,
    ADC_SOC_NUMBER0,
    ADC_INT_SOC_TRIGGER_ADCINT1);


    ADC_setupSOC(ADCA_BASE,
    ADC_SOC_NUMBER0,
    ADC_TRIGGER_EPWM1_SOCA,
    ADC_CH_ADCIN0,
    9);

    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 0x5;
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0x0;
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0x2;

    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 0x1FF;
    }

    我更改ADC暫存器的設定,但是一樣無法讀取。
    請問您可以幫助我嗎?
  • 您现在是同时测量吗?建议您单个通道一个个的试一下是否可以正常采样

    另外建议您对照下面的代码

    //###########################################################################
    //
    // FILE:   adc_ex1_soc_software.c
    //
    // TITLE:  ADC software triggering for f2838x.
    //
    //! \addtogroup cpu01_example_list
    //! <h1> ADC SOC Software Force (adc_soc_software)</h1>
    //!
    //! This example converts some voltages on ADCA and ADCB  based on a software
    //! trigger.
    //!
    //! After the program runs, the memory will contain:
    //!
    //! - \b AdcaResult0 \b: a digital representation of the voltage on pin A2\n
    //! - \b AdcaResult1 \b: a digital representation of the voltage on pin A3\n
    //! - \b AdcbResult0 \b: a digital representation of the voltage on pin B2\n
    //! - \b AdcbResult1 \b: a digital representation of the voltage on pin B3\n
    //!
    //! Note: The software triggers for the two ADCs happen sequentially, so the
    //! two ADCs will run asynchronously.
    //!
    //
    //###########################################################################
    // $TI Release: F2838x Support Library v3.01.00.00 $
    // $Release Date: Thu Mar 19 07:48:04 IST 2020 $
    // $Copyright:
    // Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //###########################################################################
    
    //
    // Included Files
    //
    #include "f28x_project.h"
    
    //
    // Function Prototypes
    //
    void ConfigureADC(void);
    void SetupADCSoftware(void);
    
    //
    // Globals
    //
    Uint16 AdcaResult0;
    Uint16 AdcaResult1;
    Uint16 AdcbResult0;
    Uint16 AdcbResult1;
    
    void main(void)
    {
    //
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the f2838x_sysctrl.c file.
    //
        InitSysCtrl();
    
    //
    // Step 2. Initialize GPIO:
    // This example function is found in the f2838x_gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
        InitGpio();
    
    //
    // 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 f2838x_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 f2838x_defaultisr.c.
    // This function is found in f2838x_pievect.c.
    //
        InitPieVectTable();
    
    //
    // Enable global Interrupts and higher priority real-time debug events:
    //
        EINT;  // Enable Global interrupt INTM
        ERTM;  // Enable Global realtime interrupt DBGM
    
    //
    // Configure the ADCs and power them up
    //
        ConfigureADC();
    
    //
    // Setup the ADCs for software conversions
    //
        SetupADCSoftware();
    
    //
    // Take conversions indefinitely in loop
    //
        do
        {
            //
            // Convert, wait for completion, and store results
            // start conversions immediately via software, ADCA
            //
            AdcaRegs.ADCSOCFRC1.all = 0x0003; //SOC0 and SOC1
    
            //
            // Start conversions immediately via software, ADCB
            //
            AdcbRegs.ADCSOCFRC1.all = 0x0003; //SOC0 and SOC1
    
            //
            // Wait for ADCA to complete, then acknowledge flag
            //
            while(AdcaRegs.ADCINTFLG.bit.ADCINT1 == 0);
            AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
    
            //
            // Wait for ADCB to complete, then acknowledge flag
            //
            while(AdcbRegs.ADCINTFLG.bit.ADCINT1 == 0);
            AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
    
            //
            // Store results
            //
            AdcaResult0 = AdcaResultRegs.ADCRESULT0;
            AdcaResult1 = AdcaResultRegs.ADCRESULT1;
            AdcbResult0 = AdcbResultRegs.ADCRESULT0;
            AdcbResult1 = AdcbResultRegs.ADCRESULT1;
    
            //
            // At this point, conversion results are stored in
            // AdcaResult0, AdcaResult1, AdcbResult0, and AdcbResult1
            //
    
            //
            // Software breakpoint, hit run again to get updated conversions
            //
            asm("   ESTOP0");
    
        }while(1);
    }
    
    //
    // ConfigureADC - Write ADC configurations and power up the ADC for both
    //                ADC A and ADC B
    //
    void ConfigureADC(void)
    {
        EALLOW;
    
        //
        // Write configurations
        //
        AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
        AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
        AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
        AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
    
        //
        // Set pulse positions to late
        //
        AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
        AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    
        //
        // Power up the ADCs
        //
        AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
        AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    
        //
        // Delay for 1ms to allow ADC time to power up
        //
        DELAY_US(1000);
    
        EDIS;
    }
    
    //
    // SetupADCSoftware - Setup ADC channels and acquisition window
    //
    void SetupADCSoftware(void)
    {
        Uint16 acqps;
    
        //
        // Determine minimum acquisition window (in SYSCLKS) based on resolution
        //
        if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION)
        {
            acqps = 14; //75ns
        }
        else //resolution is 16-bit
        {
            acqps = 63; //320ns
        }
    
        //
        // Select the channels to convert and end of conversion flag
        // ADCA
        //
        EALLOW;
        AdcaRegs.ADCSOC0CTL.bit.CHSEL = 2;  //SOC0 will convert pin A2
        AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps +
                                               //1 SYSCLK cycles
        AdcaRegs.ADCSOC1CTL.bit.CHSEL = 3;  //SOC1 will convert pin A3
        AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps +
                                               //1 SYSCLK cycles
        AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 1; //end of SOC1 will set INT1 flag
        AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
        AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
        //ADCB
        AdcbRegs.ADCSOC0CTL.bit.CHSEL = 2;  //SOC0 will convert pin B2
        AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is acqps +
                                               //1 SYSCLK cycles
        AdcbRegs.ADCSOC1CTL.bit.CHSEL = 3;  //SOC1 will convert pin B3
        AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is acqps +
                                               //1 SYSCLK cycles
        AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 1; //end of SOC1 will set INT1 flag
        AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
        AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
        EDIS;
    }
    
    //
    // End of file
    //
    

  • 變更ADC設定

        //

        // Configure SOC0 of ADCA to convert pin A0 with a sample window of 10

        // SYSCLK cycles. The EPWM1SOCA signal will be the trigger.

        //

        ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA,

                     ADC_CH_ADCIN0, 39);

        ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM1_SOCA,

                     ADC_CH_ADCIN2, 39);

        ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER6, ADC_TRIGGER_EPWM1_SOCA,

                     ADC_CH_ADCIN6, 39);

        ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM1_SOCA,

                     ADC_CH_ADCIN2, 39);

        ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_EPWM1_SOCA,

                     ADC_CH_ADCIN3, 39);

        ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA,

                     ADC_CH_ADCIN0, 39);

        ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM1_SOCA,

                     ADC_CH_ADCIN2, 39);

    每個通道皆可以讀取資料,不過資料有誤,通道A0輸入3.3V時並沒有回傳4095而是21XX,且會浮動。

  • Susan Yang 您好,也測試過您提供的代碼,四個通道皆可以回傳數值,不過回傳的數值是錯的
  • 我给出的是官方例程,您需要根据实际情况进行修改的

  • 我測試的方式是將3.3V送入I/O所以讀取的數值應該要4095才對。
  • 我是可以得到4095的,输入信号是3.3V的正弦信号,配合上面的例程得到的