# SAR ADC of Nucleo board changes conversion result to a wrong one randomly

I am using a NUCLEO-L432KC board DATASHEET I am trying to configure the ADC conversion with a 10k potentiometer However the ADC seems to give a wrong results

I set the pot to output 5v (asserted with a multimeter) and used the result to control PWM duty cylcle on an LED However the glowing of the led seemed constant (no changes in the duty cycle by varying the pot)

The gdb output of the ADC_DR register shows the result of the ADC conversion changes to a wrong value immediately after reading it and stays that way

(gdb) x/d &ADC_DR
0x50040040:     4095
0x50040040:     1703
(gdb)



The 4095 is the intended result for me as the multimeter shows 5v however the result goes back to arbitarly value under 2k without no instructions executed in between tried to raise the Sampling time to 24.5 clock cycles with no luck

The ADC_init function is as shown:

main:
bl      clockInit80
bl      TIM2_PWM_Init
1:
ldr     r0, [r1]
orr     r0, #(1 << 2)       @ADCSTART = 1
str     r0, [r1]
@wait for the conversion to complete
mov     r0, #30
delay:
subs    r0, #1
bne     delay

ldr     r0, [r1]
ldr     r2, =5000
mul     r0, r2
ldr     r2, =4096
sdiv    r0, r2

@store the result in TIM2_CCR1
ldr     r1, =TIM2_CCR1
str     r0, [r1]

ldr     r1, =TIM2_EGR
ldr     r0, [r1]
orr     r0, #(1 << 0)
str     r0, [r1]

b       1b

@Select clock source for the ADC (Mandatory) else no clock
ldr     r1, =RCC_CCIPR
ldr     r0, [r1]
orr     r0, #(3 << 28)  @ADCSEL Bits [29:28]
str     r0, [r1]

ldr     r1, =RCC_AHB2ENR
ldr     r0, [r1]
orr     r0, #(1 << 13)  @ADCEN Bit 13
str     r0, [r1]

@Disable deep down power mode Bit 29
ldr     r0, [r1]
mvn     r2, #(1 << 29)
and     r0, r2
str     r0, [r1]

ldr     r0, [r1]
orr     r0, #(1 << 28)
str     r0, [r1]
@ADC voltage regulator average wake up time is 20us wait for 50us
@waitStart
ldr     r0, =4000
1:
subs    r0, #1
bne     1b
@waitEnd

@set the number of ADC conversion to be single conversion
ldr     r0, [r1]
orr     r0, #(1 << 0)   @L (sequence legnth) Bits [3:0]
str     r0, [r1]

@set the first (and only channel to be channel 5 (ADC_IN5 = PA0)
ldr     r0, [r1]
orr     r0, #(5 << 6)   @SQ1[10:6]
str     r0, [r1]

@set channel 5 adc sampling time to be 24.5 clock cycles
ldr     r0, [r1]
orr     r0, #(3 << 15)
str     r0, [r1]

ldr     r0, [r1]
orr     r0, #(1 << 0)
str     r0, [r1]

ldr     r0, [r1]
orr     r0, #(1 << 0)
str     r0, [r1]

@wait for ADRDY bit to be set
1:
ldr     r0, [r1]
tst     r0, #(1 << 0)
beq     1b

@return
bx      lr



EDIT1: The PA0 is connected directly to the 5v output from the 10k pot (PA0 is 5v tolerant as indicated in the datasheet)

AGAIN it actually shows the correct value for the conversion for a sec but it changes immediately to a wrong one so I don't think the problem has anything to do with the connection and it's varying by hunderds of digits as shown above

EDIT2: The 5V is changed to 3.3V as suggested and the ADC is asserted to be working fine using cubeMX and HAL code (No damage from the 5V the ADC_DR in the HAL code is constant with the correct value) The clock is configured to be the system clock at 80Mhz I suspect the problem is in my initialization code but I am already following the reference manual init sequence maybe there's some detail I am missing

Connection Schematic

• what is your specific question? Mar 5 at 3:02
• @jsotola The ADC gives the wrong output which is the second one in the gdb it immediately changes to a wrong value and stays that way the question is why and how to fix that Mar 5 at 3:44
• @MahmoudSalah - Hi, Please add a schematic of your design (and, to add further clarity, a photo of your hardware would help too). You twice mention 5 V and a pot producing that voltage, but AFAIK that Nucleo-L432KC board does not have a pot onboard, so you seem to be adding some external components - is that correct? Are you connecting the 5 V from the pot directly to the STM32 ADC input? If so, why do you believe that is a valid configuration? If you are not connecting 5 V directly to the ADC, then the question is unclear. Either way, please edit & elaborate with more details. Thanks. Mar 5 at 5:33
• @SamGibson Yes it's connected directly PA0 is 5v tolerant and the gdb shows the correct output of "4095" for a sec but by the time it's read it's changed to a wrong value and the problem is I don't know what caused the change the OVR flag isn't set no other conversion is going in between even tried to use interrupt and disable any exception till the value is read still no luck Mar 5 at 6:38
• @MahmoudSalah - Thanks for the reply. While I have been offline, Justme has written an answer quite similar to what I would have written. Read that answer and I recommend you to repeat your tests with the voltage on PA0 not exceeding $V_{REF+} = V_{DDA} = V_{DD}$ i.e. 3.3 V. See what the behaviour is for that test, and update the question with the results. Mar 5 at 18:49

Don't feed the ADC pin with 5V, it is wrong.

The ADC cannot read voltages beyond the Vref, which is most likely same as Vdd, which is most likely 3.3V.

The GPIO pin as digital input can tolerate 5V, but as and ADC input it is not 5V tolerant, and even if it were, it will still read 4095 when voltage is above 3.3V because that is what the analog circuitry can handle.

Please note that setting the pot to the 5V extreme end migh have already damaged the MCU.

• But The correct conversion value is placed in the ADC_DR register for some time it means the conversion channel is working just fine Mar 5 at 18:52
• tried to use different pin with 3.3V same problem Mar 5 at 18:52
• Justme - Hi, All agreed. In case it helps to give a reference, I think this is the datasheet for the OP's MCU and page 114 specifies exactly what you said that $V_{AIN}$ should not exceed $V_{REF+}$ for the ADC. Mar 5 at 18:54
• @MahmoudSalah - I'm not replying on behalf of Justme, but I respectfully disagree with your comment that: "The correct conversion value is placed in the ADC_DR register for some time it means the conversion channel is working just fine". Applying 5 V to the ADC input exceeds the specification (see my link in the comment above). Therefore after that, anything is possible. I deliberately didn't try this on my STM32-based designs exactly because of that reason. If you still get strange results with your own code, I suggest trying with known-good code sample & update the question with results. Mar 5 at 19:03
• @MahmoudSalah - Unfortunately I don't have time to get deeply involved here, which is why I said before, please edit the question to add new results / updates. Leaving new (important!) updates in a comment, which most people will not see, does not help you much. Please read the first paragraph here. Thanks. Mar 5 at 21:02

After you've fed 5V to that ADC input pin, consider the MCU chip junk and replace it. It seems that the chip "works fine": you don't know that. After exceeding the absolute maximum ratings, the chip may misbehave in interesting ways, and you'll never be able to fully trust it. Just replace it.

Don't feed more than the ADC reference voltage, e.g. 3.3V. It should work fine then, assuming you've made no other mistakes. In many cases some initialization code, such as clock selection for the ADC, may have "interesting" side effects.

The ADC needs a clock signal, since it's a SAR, and that clock cannot be too fast or you'll be getting funky results. You also need to check in the datasheet whether the ADC data register allows multiple reads without starting another conversion, and make sure that you've set it for continuous conversion.

And most importantly: read the errata sheet for your chip. Datasheets document the wishes of the designers in ideal circumstances. Due to human mistakes, the actual chip you're using may not behave exactly as the datasheet would imply. On most complex MCUs I've seen, the A/D converter always has some errata.

I don't know what to say the problem was that the SQR1 register uses the Sequence 0000 for 1 conversion and I somehow saw and used it as 0001 after modification the Code works fine now and luckily the MCU isn't damaged from the earlier 5V mistake anyway thanks for your help..!!