STM32 ADC 失调电压问题。 ADC从0.05V开始,而不是0V

问题描述 投票:0回答:1

我正在使用 STM32H743ZI 来实现 GPIO、I2C、SPI、ADC。我想从 ADC1 的 8 个不同通道读取模拟电压。我的代码工作正常,但存在我不想要的偏移电压。

我通过将直流电源提供的电压连接到STM32H743ZI的ADC引脚来读取ADC值。

下面可以看到电源电压并读取ADC值。

直流电源 ADC 0V 0.04 0.5V 0.54V 1.5V 1.55V 3V 3.05V ……

这是我的代码...

HAL_ADC_Start(&hadc1);

ADC_ChannelConfTypeDef sConfig = {0};


                sConfig.Channel = ADC_CHANNEL_2;
                HAL_ADC_ConfigChannel(&hadc1, &sConfig);
                HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
                raw_2 = HAL_ADC_GetValue(&hadc1);



                sConfig.Channel = ADC_CHANNEL_3;
                HAL_ADC_ConfigChannel(&hadc1, &sConfig);
                HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
                raw_3 = HAL_ADC_GetValue(&hadc1);



                sConfig.Channel = ADC_CHANNEL_4;
                HAL_ADC_ConfigChannel(&hadc1, &sConfig);
                HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
                raw_4 = HAL_ADC_GetValue(&hadc1);


                sConfig.Channel = ADC_CHANNEL_5;
                HAL_ADC_ConfigChannel(&hadc1, &sConfig);
                HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
                raw_5 = HAL_ADC_GetValue(&hadc1);

                sConfig.Channel = ADC_CHANNEL_6;
                HAL_ADC_ConfigChannel(&hadc1, &sConfig);
                HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
                raw_6 = HAL_ADC_GetValue(&hadc1);


                sConfig.Channel = ADC_CHANNEL_7;
                HAL_ADC_ConfigChannel(&hadc1, &sConfig);
                HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
                raw_7 = HAL_ADC_GetValue(&hadc1);


                sConfig.Channel = ADC_CHANNEL_8;
                HAL_ADC_ConfigChannel(&hadc1, &sConfig);
                HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
                raw_8 = HAL_ADC_GetValue(&hadc1);


                sConfig.Channel = ADC_CHANNEL_9;
                HAL_ADC_ConfigChannel(&hadc1, &sConfig);
                HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
                raw_9 = HAL_ADC_GetValue(&hadc1);


                HAL_ADC_Stop(&hadc1);


                  ADC_2[0] = (int)(raw_2 / 256);
                  ADC_2[1] = (int)(raw_2 % 256);

                  ADC_3[0] = (int)(raw_3 / 256);
                  ADC_3[1] = (int)(raw_3 % 256);

                  ADC_4[0] = (int)(raw_4 / 256);
                  ADC_4[1] = (int)(raw_4 % 256);

                  ADC_5[0] = (int)(raw_5 / 256);
                  ADC_5[1] = (int)(raw_5 % 256);

                  ADC_6[0] = (int)(raw_6 / 256);
                  ADC_6[1] = (int)(raw_6 % 256);

                  ADC_7[0] = (int)(raw_7 / 256);
                  ADC_7[1] = (int)(raw_7 % 256);

                  ADC_8[0] = (int)(raw_8 / 256);
                  ADC_8[1] = (int)(raw_8 % 256);

                  ADC_9[0] = (int)(raw_9 / 256);
                  ADC_9[1] = (int)(raw_9 % 256);

我通过从读取值中减去估计的偏移值找到了解决方案,但我相信有更好的解决方案。


                if(raw_2 < 4045 && raw_2 >= 993) raw_2 -= 50;
                else if(raw_2 <= 993 && raw_2 >= 0) raw_2 -= 62;

                if(raw_3 < 4045 && raw_3 >= 993) raw_3 -= 50;
                else if(raw_3 <= 993 && raw_3 >= 0) raw_3 -= 62;

                if(raw_4 < 4045 && raw_4 >= 993) raw_4 -= 50;
                else if(raw_4 <= 993 && raw_4 >= 0) raw_4 -= 62;

                if(raw_5 < 4045 && raw_5 >= 993) raw_5 -= 50;
                else if(raw_5 <= 993 && raw_5 >= 0) raw_5 -= 62;

                if(raw_6 < 4045 && raw_6 >= 993) raw_6 -= 50;
                else if(raw_6 <= 993 && raw_6 >= 0) raw_6 -= 62;

                if(raw_7 < 4045 && raw_7 >= 993) raw_7 -= 50;
                else if(raw_7 <= 993 && raw_7 >= 0) raw_7 -= 62;

                if(raw_8 < 4045 && raw_8 >= 993) raw_8 -= 50;
                else if(raw_8 <= 993 && raw_8 >= 0) raw_8 -= 62;

                if(raw_9 < 4045 && raw_9 >= 993) raw_9 -= 50;
                else if(raw_9 <= 993 && raw_9 >= 0) raw_9 -= 62;`your text` 
stm32 offset adc mcu
1个回答
0
投票

我在STM32H7上遇到了完全相同的问题。当将 ADC 引脚连接到 GND 时,我会收到 900 左右的(16 位)值,等于 0.05V。

按照 pmacfarlane 的建议,我尝试校准 ADC。在初始化 ADC 之后、开始 ADC 转换之前,我将以下行放入代码中。

  HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);

经过此更改后,当连接到 GND 时,我的 ADC 现在将读取大约 90 (~0.005) 的值。不是 0,但考虑到该 ADC 实际上是 14 位而不是 16 位,这相当不错。

请注意,我使用

ADC_SINGLE_ENDED
参数,因为我在单端配置中使用 ADC。除了
ADC_CALIB_OFFSET
模式之外,还有另一种
ADC_CALIB_OFFSET_LINEARITY
模式,它给了我类似的结果(这个可能用于修复线性问题)。

© www.soinside.com 2019 - 2024. All rights reserved.