// TI File $Revision: /main/5 $ // Checkin $Date: December 16, 2009 [Link] $ //########################################################################### // // FILE: DSP2802x_Adc.
c // // TITLE: DSP2802x ADC Initialization & Support Functions. // //########################################################################### // $TI Release: 2802x C/C++ Header Files and Peripheral Examples V1.28 $ // $Release Date: October 15, 2010 $ //########################################################################### #include "DSP2802x_Device.h" #include "DSP2802x_Examples.h" #define ADC_usDELAY 1000L //--------------------------------------------------------------------------// InitAdc: //--------------------------------------------------------------------------// This function initializes ADC to a known state. // // NOTE: ADC INIT IS DIFFERENT ON 2802x DEVICES COMPARED TO OTHER 28X DEVICES // void InitAdc(void) { extern void DSP28x_usDelay(Uint32 Count); // *IMPORTANT* // The Device_cal function, which copies the ADC calibration values from TI reserved // OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the // Boot ROM. If the boot ROM code is bypassed during the debug process, the // following function MUST be called for the ADC to function according // to specification. The clocks to the ADC MUST be enabled before calling th is // function. // See the device data manual and/or the ADC Reference // Manual for more information. EALLOW; [Link] = 1; (*Device_cal)(); EDIS; // // core. // // To powerup the ADC the ADCENCLK bit should be set first to enable clocks, followed by powering up the bandgap, reference circuitry, and ADC Before the first conversion is performed a 5ms delay must be observed after power up to give all analog circuits time to power up and settle // DSP2802x Headerfile Include File // DSP2802x Examples Include File
// Please note that for the delay function below to operate correctly the // CPU_RATE define statement in the DSP2802x_Examples.h file must // contain the correct CPU clock period in nanoseconds. EALLOW; [Link] = 1; // Power ADC BG [Link] = 1; // Power reference
[Link] = 1; [Link] = 1; [Link] = 0; EDIS; DELAY_US(ADC_usDELAY); } void InitAdcAio() { EALLOW; /* // // //
// Power ADC // Enable ADC // Select interal BG
// Delay before converting ADC channels
Configure ADC pins using AIO regs*/ This specifies which of the possible AIO pins will be Analog input pins. NOTE: AIO1,3,5,7-9,11,13,15 are analog inputs in all AIOMUX1 configurations. Comment out other unwanted lines. // Configure AIO2 for A2 (analog input // Configure AIO4 for A4 (analog input // Configure AIO6 for A6 (analog input // Configure AIO10 for B2 (analog inpu // Configure AIO12 for B4 (analog inpu // Configure AIO14 for B6 (analog inpu
[Link].AIO2 = 2; ) operation [Link].AIO4 = 2; ) operation [Link].AIO6 = 2; ) operation [Link].AIO10 = 2; t) operation [Link].AIO12 = 2; t) operation [Link].AIO14 = 2; t) operation EDIS; }
/* AdcoffsetSelfCalThis function re-calibrates the ADC zero offset error by converting the VREFL O reference with the ADC and modifying the ADCOFFTRIM register. VREFLO is sampled by the ADC u sing an internal MUX select which connects VREFLO to A5 without sacrificing an external ADC pi n. This function calls two other functions: - AdcChanSelect(channel) selects the ADC channel to convert - AdcConversion() initiates several ADC conversions and returns the average */ void AdcOffsetSelfCal() { Uint16 AdcConvMean; EALLOW; [Link] = 0; //Select internal refere nce mode [Link] = 1; //Select VREFLO internal connection on B5 AdcChanSelect(13); //Select channel B5 for all SOC [Link] = 80; //Apply artificial offse t (+80) to account for a negative offset that may reside in the ADC core AdcConvMean = AdcConversion(); //Capture ADC conversion on VREFLO [Link] = 80 - AdcConvMean; //Set offtrim register w
ith new value (i.e remove artical offset (+80) and create a two's compliment of the offset error) [Link] = 0; //Select external ADCIN5 input pin on B5 EDIS; } /* AdcChanSelectThis function selects the ADC channel to convert by setting all SOC channel selects to a single channel. * IMPORTANT * This function will overwrite previous SOC channel select sett ings. Recommend saving the previous settings. */ void AdcChanSelect(Uint16 ch_no) { [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; [Link]= ch_no; } //end AdcChanSelect /* AdcConversion This function initiates several ADC conversions and returns the average. It u ses ADCINT1 and ADCINT2 to "ping-pong" between SOC0-7 and SOC8-15 and is referred to as "ping-pong" s ampling. * IMPORTANT * This function will overwrite previous ADC settings. Recommend saving previous settings. */ Uint16 AdcConversion(void) { Uint16 index, SampleSize, Mean, ACQPS_Value; Uint32 Sum; index SampleSize st be multiples Sum Mean = 0; //initialize index to 0 = 256; //set sample size to 256 (**NOTE: Sample size mu of 2^x where is an integer >= 4) = 0; //set sum to 0 = 999; //initialize mean to known value
//Set the ADC sample window to the desired value (Sample window = ACQPS + 1) ACQPS_Value = 6; [Link] = ACQPS_Value; [Link] = ACQPS_Value; [Link] = ACQPS_Value;
[Link] [Link] [Link] [Link] [Link] [Link] [Link] [Link] [Link] [Link] [Link] [Link] [Link] //Enable ping-pong sampling
= = = = = = = = = = = = =
ACQPS_Value; ACQPS_Value; ACQPS_Value; ACQPS_Value; ACQPS_Value; ACQPS_Value; ACQPS_Value; ACQPS_Value; ACQPS_Value; ACQPS_Value; ACQPS_Value; ACQPS_Value; ACQPS_Value;
// Enabled ADCINT1 and ADCINT2 [Link].INT1E = 1; [Link].INT2E = 1; // Disable continuous sampling for ADCINT1 and ADCINT2 [Link].INT1CONT = 0; [Link].INT2CONT = 0; [Link] = 1; on // Setup ADCINT1 and ADCINT2 trigger source [Link].INT1SEL = 6; //EOC6 triggers ADCINT1 [Link].INT2SEL = 14; //EOC14 triggers ADCINT2 // Setup each SOC's ADCINT trigger source [Link].SOC0 = 2; //ADCINT2 starts SOC0-7 [Link].SOC1 = 2; [Link].SOC2 = 2; [Link].SOC3 = 2; [Link].SOC4 = 2; [Link].SOC5 = 2; [Link].SOC6 = 2; [Link].SOC7 = 2; [Link].SOC8 = 1; //ADCINT1 starts SOC8-15 [Link].SOC9 = 1; [Link].SOC10 = 1; [Link].SOC11 = 1; [Link].SOC12 = 1; [Link].SOC13 = 1; [Link].SOC14 = 1; [Link].SOC15 = 1; DELAY_US(ADC_usDELAY); els //ADC Conversion [Link] = 0x00FF; // Force Start SOC0-7 to begin ping-pong s ampling while( index < SampleSize ){ // Delay before converting ADC chann //ADCINTs trigger at end of conversi
//Wait for ADCINT1 to trigger, then add ADCRESULT0-7 registers to sum while ([Link].ADCINT1 == 0){} [Link].ADCINT1 = 1; //Must clear ADCINT1 flag since INT1CONT = 0 Sum += AdcResult.ADCRESULT0; Sum += AdcResult.ADCRESULT1; Sum += AdcResult.ADCRESULT2; Sum += AdcResult.ADCRESULT3; Sum += AdcResult.ADCRESULT4; Sum += AdcResult.ADCRESULT5; Sum += AdcResult.ADCRESULT6; Sum += AdcResult.ADCRESULT7; //Wait for ADCINT2 to trigger, then add ADCRESULT8-15 registers to sum while ([Link].ADCINT2 == 0){} [Link].ADCINT2 = 1; //Must clear ADCINT2 flag since INT2CONT = 0 Sum += AdcResult.ADCRESULT8; Sum += AdcResult.ADCRESULT9; Sum += AdcResult.ADCRESULT10; Sum += AdcResult.ADCRESULT11; Sum += AdcResult.ADCRESULT12; Sum += AdcResult.ADCRESULT13; Sum += AdcResult.ADCRESULT14; Sum += AdcResult.ADCRESULT15; index+=16; } // end data collection //Disable ADCINT1 and ADCINT2 to STOP the ping-pong sampling [Link].INT1E = 0; [Link].INT2E = 0; Mean = Sum / SampleSize; return Mean; }//end AdcConversion //=========================================================================== // End of file. //=========================================================================== //Calculate average ADC sample value //return the average