cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L053R8 Problem trying to sample VREFINT

danq
Associate II
Posted on October 08, 2014 at 02:07

Hi All,

I have configured the ADC according to the initialization code below and then try to to a conversion to read the VREFINT voltage so as to calculated AVDD.  The initialization appears to work ok and the conversion succeeds, but the results returned are incorrect.  In fact, after a hardware reset, the first conversion is way off, the second is close, but the third and subsequent readings are close to the actual AVDD (3.31 as per volt meter and 3.40 as per return value).  I have searched through the datasheet extensively and I cannot explain what is happening.  I suspect something in either my initialization or conversion code is either missing or in the wrong order.

Here is the initialization code:

 

RCC

->

APB2ENR

|=

RCC_APB2ENR_SYSCFGEN

|

RCC_APB2ENR_ADC1EN

;

// Enable SYSCFG & ADC1 clocks

asm

(

''DSB''

)

;

// Errata 2.1.8 Work-around

SYSCFG

->

CFGR3

|=

SYSCFG_CFGR3_EN_BGAP

|

SYSCFG_CFGR3_ENBUF_BGAP_ADC

;

// Enable VREFINT for ADC

while

((

PWR

->

CSR

&

PWR_CSR_VREFINTRDYF

)

==

0

)

;

// Wait VREFINT ready

ADC1

->

CR

|=

ADC_CR_ADCAL

;

// Start calibration and enable regulator

while

((

ADC1

->

ISR

&

ADC_ISR_EOCAL

)

==

0

)

;

// Wait for calibration to be done

ADC1

->

CR

|=

ADC_CR_ADEN

;

// Enable ADC

while

((

ADC1

->

ISR

&

ADC_ISR_ADRDY

)

==

0

)

;

// wait for ADC to be ready

ADC

->

CCR

|=

ADC_CCR_VREFEN

|

(

9U

<<

18

)

;

// Enable vref internal and divide ADCCLK : 16 MHZ/64 = 250 KHz

ADC1

->

SMPR

=

2

;

// (13.5 + 12.5) ADC cycles/conversion = 9615.4 Ksps

while

((

SYSCFG

->

CFGR3

&

SYSCFG_VREFINT_ADC_RDYF

)

==

0

)

;

// Wait for ADC to be ready to read VREFINT

Here is the conversion code:

 

ADC1

->

CHSELR

=

ADC_CHSELR_CHSEL17

;

// V-Ref voltage

ADC1

->

CR

|=

ADC_CR_ADSTART

;

// Start conversion

while

((

ADC1

->

ISR

&

ADC_ISR_EOSMP

)

==

0

)

;

// Wait for conversion to finish

return

UInt16

(

ADC1

->

DR

)

;

// Clears ADC_ISR_EOSMP flag and returns sample

#adc-vrefint
2 REPLIES 2
Posted on October 08, 2014 at 09:26

> readings are close to the actual AVDD (3.31 as per volt meter and 3.40 as per return value).

How did you arrive to the volts value?

JW

danq
Associate II
Posted on October 08, 2014 at 14:47

I used the 16-bit VREFINT_CAL value at $ 

0x1FF80078

 along with the equation shown in the data sheet.  The data sheet states that the calibration value was determined for AVDD set at 3.3, but appnote #3964 indicates it was 3.0V.  When I use the 3.0V as the constant, I at least get close to the actual value.

Here is the code sequence:

 

UInt16

const

&

vref_intcal

=

*

(

UInt16

const

*

)

0x1FF80078

;

/// VDDA = (3.0V +- 0.01) * VREFINT_CAL / VREFINT_DATA ///

UInt16

const

vref_internal

=

adc_device

.

convert

()

;

float

const

vdda

=

3.0F

*

float

(

vref_intcal

)

/

vref_internal

;

printf

(

''ADC = %04X VDDA = %6.4f\r\n''

,

vref_internal

,

vdda

)

;

Here are the results captured from my terminal from this morning.  The first is after hardware reset, the second is the next attempt, followed by the remaining.  Notice that it looks a bit like some kind of under-damped response.  Also, the values read are a bit different from the one I originally posted.

ADC = 0043  VDDA = 74.8657

ADC = 0800  VDDA = 2.4492

ADC = 060D  VDDA = 3.2382

ADC = 060C  VDDA = 3.2403

ADC = 060C  VDDA = 3.2403

ADC = 060C  VDDA = 3.2403

The actual voltage on AVDD as measured is 3.317.

Cheers!

Dan