我正在使用 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`
我在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
模式,它给了我类似的结果(这个可能用于修复线性问题)。