web-dev-qa-db-ja.com

STM32 ADCの校正(VREFINT)

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
 _

aDC_TEST.c:

#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);
    }
}
 _

データシートからのスクリーンショット:

enter image description here

リファレンスマグラウントのスクリーンショット

注意事項.3Vは、上記のデータシートが3.3V、.3Vがこの部分の最小動作電圧を下回っているため、これがタイプミスであると思います。

enter image description here

4
iter

私は現在STM32L4のためのADCドライバを開発しています。実装中に、ほとんど同じ問題が発生します。私の意見では、最初の式 enter image description here

vDDAを計算していませんが、VREF +です。 ADCがADC-INチャネルを評価している電圧です。さらに、VREFINT_DATAはVREF +電圧ではなく、コントローラに依存する内部基準電圧ではありません。私の場合はコントローラデータシートで定義されています: enter image description here

ここに私が投稿された式を使っている方法: enter image description here

いくつかのコメント:ln 102:VREF +ではなくVDDAの計算

lN 105-110:すべてのランク/設定順序を計算します

lN 108:ADCPIN_Xで測定された電圧を計算します

lN 109:実際の値を取得するためのゲインで乗算する

私の意見では、各変換シーケンスのVREF +を計算することで、VREF +のいくつかの波紋が補正されるため、最適な結果が得られます。

1