STM32F042マイクロコントローラでVDDAを読み込もうとしています。 3.29VのVDDで予期しない結果が得られます。私は基本的なものが足りないに違いない。
VREFINT=1917; VREFINT_CAL=1524; VDDA=2623 mV
VREFINT=1885; VREFINT_CAL=1524; VDDA=2668 mV
VREFINT=1913; VREFINT_CAL=1524; VDDA=2628 mV
VREFINT=1917; VREFINT_CAL=1524; VDDA=2623 mV
VREFINT=1917; VREFINT_CAL=1524; VDDA=2623 mV
_
#include <stdio.h>
#include "stm32f0xx.h"
#define VREFINT_CAL_ADDR 0x1FFFF7BA /* datasheet p. 19 */
#define VREFINT_CAL ((uint16_t*) VREFINT_CAL_ADDR)
extern void initialise_monitor_handles(void);
int main(void)
{
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; /* enable ADC peripheral clock */
RCC->CR2 |= RCC_CR2_HSI14ON; /* start ADC HSI */
while (!(RCC->CR2 & RCC_CR2_HSI14RDY)); /* wait for completion */
/* calibration */
ADC1->CR |= ADC_CR_ADCAL; /* start ADc CALibration */
while (ADC1->CR & ADC_CR_ADCAL); /* wait for completion */
ADC1->CR |= ADC_CR_ADEN; /* ADc ENable */
while (!(ADC1->ISR & ADC_ISR_ADRDY)); /* wait for completion */
ADC1->SMPR |= ADC_SMPR1_SMPR_0 | /* sampling mode: longest */
ADC_SMPR1_SMPR_1 |
ADC_SMPR1_SMPR_2;
/* VDD reference */
ADC->CCR |= ADC_CCR_VREFEN; /* VREF Enable */
ADC1->CHSELR = ADC_CHSELR_CHSEL17; /* CH17 = VREFINT */
initialise_monitor_handles(); /* enable semihosting */
while (1) {
ADC1->CR |= ADC_CR_ADSTART; /* start ADC conversion */
while (!(ADC1->ISR & ADC_ISR_EOC)); /* wait for completion */
uint32_t vdda = 3300UL * *VREFINT_CAL / ADC1->DR; /* ref. manual p. 252; constant and result in millivolts */
printf("VREFINT=%lu; VREFINT_CAL=%lu; VDDA=%lu mV\n",
(unsigned long)ADC1->DR,
(unsigned long)*VREFINT_CAL,
(unsigned long)vdda);
}
}
_
私は現在STM32L4のためのADCドライバを開発しています。実装中に、ほとんど同じ問題が発生します。私の意見では、最初の式
vDDAを計算していませんが、VREF +です。 ADCがADC-INチャネルを評価している電圧です。さらに、VREFINT_DATAはVREF +電圧ではなく、コントローラに依存する内部基準電圧ではありません。私の場合はコントローラデータシートで定義されています:
いくつかのコメント:ln 102:VREF +ではなくVDDAの計算
lN 105-110:すべてのランク/設定順序を計算します
lN 108:ADCPIN_Xで測定された電圧を計算します
lN 109:実際の値を取得するためのゲインで乗算する
私の意見では、各変換シーケンスのVREF +を計算することで、VREF +のいくつかの波紋が補正されるため、最適な結果が得られます。