The Analog-to-Digital Converter (ADC) in [STM32](https://www.ampheo.com/search/STM32) [microcontrollers](https://www.ampheo.com/c/microcontrollers) requires calibration to ensure accurate measurements. Here's a detailed explanation of the calibration process:  **1. Why ADC Calibration is Necessary** * Compensates for internal capacitor charge/discharge variations * Corrects offset and linearity errors * Improves measurement accuracy (typically ±1 LSB after calibration) * Required after power-up or long idle periods **2. Calibration Process Steps** **2.1 Basic Calibration (All STM32 Series)** ``` c void ADC_Calibrate(ADC_HandleTypeDef* hadc) { // 1. Ensure ADC is disabled HAL_ADC_Stop(hadc); // 2. Start calibration HAL_ADCEx_Calibration_Start(hadc); // 3. Wait for completion while(HAL_ADCEx_Calibration_GetValue(hadc) != HAL_OK); } ``` **2.2 STM32H7 Specific Calibration** The H7 series has additional calibration registers: ``` c void ADC_H7_Calibrate(ADC_HandleTypeDef* hadc) { // 1. Disable ADC ADC1->CR &= ~ADC_CR_ADEN; // 2. Calibrate single-ended mode ADC1->CR |= ADC_CR_ADCALLIN; ADC1->CR |= ADC_CR_ADCAL; while((ADC1->CR & ADC_CR_ADCAL) != 0); // 3. For differential mode (if used) ADC1->CR |= ADC_CR_ADCALDIF; ADC1->CR |= ADC_CR_ADCAL; while((ADC1->CR & ADC_CR_ADCAL) != 0); } ``` **3. Important Considerations** **3.1 Timing Requirements** * Must be performed when ADC is disabled * Takes ~10-100 clock cycles depending on [STM32](https://www.onzuu.com/search/STM32) family * Should be done: * After power-up * After temperature changes >10°C * Periodically in critical applications **3.2 Multi-ADC Systems** For STM32 devices with multiple ADCs: 1. Calibrate each ADC separately 2. Maintain consistent timing between calibrations 3. Use same reference voltage for all ADCs **3.3 Voltage Reference** * Calibration assumes stable reference voltage * For VREFINT (internal reference): ``` c // Enable internal reference buffer (STM32H7) HAL_SYSCFG_VREFBUF_VoltageScalingConfig(SYSCFG_VREFBUF_VOLTAGE_SCALE0); HAL_SYSCFG_EnableVREFBUF(); ``` **4. Post-Calibration Verification** ``` c uint32_t Verify_Calibration() { // Read known voltage (e.g., internal reference) HAL_ADC_Start(&hadc); HAL_ADC_PollForConversion(&hadc, 10); uint32_t adcValue = HAL_ADC_GetValue(&hadc); // Compare with expected value const uint32_t expected = 1234; // Device-specific return (abs(adcValue - expected) <= 2); // Within 2 LSB } ``` **5. Advanced Techniques** **5.1 Background Calibration ([STM32L4](https://www.ampheo.com/search/STM32L4)/L5)** ``` c // Enable background calibration ADC1->CFGR |= ADC_CFGR_CONT; ADC1->CR |= ADC_CR_ADCAL; ``` **5.2 Temperature Compensation** ``` c // Read temperature sensor (TS_CAL1/2 values from flash) float Get_Temperature() { uint16_t *TS_CAL1 = (uint16_t*)0x1FFF75A8; uint16_t *TS_CAL2 = (uint16_t*)0x1FFF75CA; HAL_ADC_Start(&hadc_temp); uint32_t temp_raw = HAL_ADC_GetValue(&hadc_temp); return ((temp_raw - TS_CAL1) * (85.0 - 30.0)) / (TS_CAL2 - TS_CAL1) + 30.0; } ``` **6. Troubleshooting**  **7. Recommended Practice** 1. Calibrate at startup 2. Store calibration factors in flash/EEPROM 3. Implement periodic recalibration in mission-critical apps 4. Use hardware averaging ([STM32G4](https://www.ampheo.com/search/STM32G4)/H7) for better noise immunity For specific [STM32](https://www.ampheoelec.de/search/STM32) families (F4, G0, U5, etc.), check the reference manual for family-specific calibration procedures. The process is similar but may have minor register differences.
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.