TI C2000 Calibration Algorithm for AD Sampling Accuracy[Copy link]
In actual use, the conversion result of ADC has a large error. 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 conversion accuracy of F2812 ADC 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, A4) as reference input channels, and provide them with known DC reference voltages as inputs (RefHigh and RefLow) respectively. Obtain the conversion value by reading the corresponding result register, and use the two sets of input and output values to obtain the correction gain and correction offset of the ADC module. 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.