AD sampling accuracy techniques in DSP TMS320F2812 programming[Copy link]
The F2812 has an internal integrated ADC conversion module. This module is a 12-bit, pipelined analog-to-digital converter with a built-in dual sample-and-hold (S/H) and can select 16-channel inputs in multiple ways. The fast conversion time runs at 25 MHz, ADC clock or 12.5 Msps, and the 16 conversion result registers can work in continuous automatic sequencing mode or start/stop mode. In actual use, the ADC conversion result error is large. If this conversion result is directly used in the control loop, the control accuracy will inevitably be reduced. (The maximum conversion error can reach about 9%) The main reason for the poor ADC conversion accuracy of the F2812 is the existence of gain error and offset error. To improve the conversion accuracy, the two errors must be compensated. The following method is adopted to calibrate the ADC module: Select any two channels of ADC (such as A3 and A4) as reference input channels, and provide them with known DC reference voltages as inputs (RefHigh and RefLow), obtain the conversion values by reading the corresponding result registers, and use the two sets of input and output values to obtain the correction gain and correction offset of the ADC module, and then use these two values to compensate the conversion data of other channels, thereby improving the conversion accuracy of the ADC module. The hardware circuit for implementing calibration is not described in this article, but can be found in relevant materials. The following is the C language implementation of the algorithm: //First calculate the ideal results after the reference voltage conversion of the two channels // A4 = RefHigh = 2.5V ( 2.5*4095/3.0 = 3413 ideal count) // A3 = RefLow = 0.5V ( 0.5*4095/3.0 = 683 ideal count) #define REF_HIGH_IDEAL_COUNT 3413 #define REF_LOW_IDEAL_COUNT 683 #define SAMPLES 63 //Define the required variables Uint16 Avg_RefHighActualCount; Uint16 Avg_RefLowActualCount; / Uint16 CalGain; // Calibration Gain Uint16 CalOffset; // Calibration Offset Uint16 SampleCount; Uint16 RefHighActualCount; Uint16 RefLowActualCount; // Initialize each variable void InitCalib() { Avg_RefLowActualCount = 0; Avg_RefLowActualCount = 0; Avg_RefHighActualCount = 0; RefHighActualCount = 0; RefLowActualCount = 0; CalGain = 0; CalOffset = 0; SampleCount = 0; } // Get calibration gain and calibration offset // Algorithm: Calibration formula used is: // // ch(n) = ADCRESULTn*CalGain - CalOffset // n = 0 to 15 channels // CalGain = (RefHighIdealCount - RefLowIdealCount) // ----------------------------------------- // (Avg_RefHighActualCount - Avg_RefLowActualCount) // // CalOffset = Avg_RefLowActualCount*CalGain - RefLowIdealCount // // A running weighted average is calculated for the reference inputs: // // Avg_RefHighActualCount = (Avg_RefHighActualCount*SAMPLES // + RefHighActualCount) / (SAMPLES+1) // // Avg_RefLowActualCount = (Avg_RefLowActualCount*SAMPLES // + RefLowActualCount) / (SAMPLES+1) // void GetCalibParam() { RefHighActualCount = AdcRegs.ADCRESULT4 >>4; RefLowActualCount = AdcRegs.ADCRESULT3 >>4; if(SampleCount > SAMPLES) SampleCount = SAMPLES; Avg_RefHighActualCount = (Avg_RefHighActualCount * SampleCount + RefHighActualCount) / (SampleCount+1); Avg_RefLowActualCount = (Avg_RefLowActualCount * SampleCount + RefLowActualCount) / (SampleCount+1); CalGain = (REF_HIGH_IDEAL_COUNT - REF_LOW_IDEAL_COUNT) / (Avg_RefHighActualCount - Avg_RefLowActualCount); CalOffset = Avg_RefLowActualCount*CalGain - RefLowIdealCount; SampleCount++; } //In ADC_ISR, correct the results of other channels: interrupt void adc_isr(void) { GetCalibParam(); ...... newResult n= AdcRegs.ADCRESULTn*CalGain - CalOffset; ...... } Copy code Through the above code, combined with hardware circuit changes, the accuracy of ADC sampling can be greatly improved, and more sensitive and precise control can be achieved.