Skip to main content
Graduate II
November 2, 2024
Solved

High AD noise on STM32F103 (bluepill)

  • November 2, 2024
  • 2 replies
  • 947 views

This is on STM32F103C8 (bluepill)
The A0 is connected to a voltage divider between bluepill's 3v3 and GND,
And the output is very noisy. adding a delay did't do not much good

```
void setup()
{
Serial.begin(9600);

// Enable ADC1 and configure it
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // Enable ADC1 clock
ADC1->CR2 |= ADC_CR2_ADON; // Turn on ADC1

// Configure ADC1 to use the internal reference voltage (1.2V)
ADC1->CR2 |= ADC_CR2_TSVREFE; // Enable internal reference voltage
ADC1->SMPR2 |= ADC_SMPR2_SMP0; // Set sample time for channel 0 (PA0)

// Calibrate ADC1
ADC1->CR2 |= ADC_CR2_CAL; // Start calibration
while (ADC1->CR2 & ADC_CR2_CAL); // Wait for calibration to complete
pinMode(PC13, OUTPUT);
pinMode(A0, INPUT_ANALOG);

// configure I2C 2 for Switching controller communication
Wire.setSDA(PB11);
Wire.setSCL(PB10);
Wire.begin();
delay(1000);
}

void loop()
{
static uint32_t last_time = 0;

if (millis() - last_time > 500)
{
// Start ADC conversion
ADC1->SQR3 = 0; // Select channel 0 (PA0)
delay(3); // Wait for ADC to stabilize
ADC1->CR2 |= ADC_CR2_ADON; // Start conversion
while (!(ADC1->SR & ADC_SR_EOC)); // Wait for conversion to complete
int T1 = ADC1->DR; // Read the ADC value (12-bit)
Serial.println(T1);
last_time = millis();
}

delay(10);
}

```


output:
1964
1963
1964
1960
1985
1968
1976
1963
1985
1976
1972


What can be done to make it better?

    This topic has been closed for replies.
    Best answer by gbm

    Increase sampling time, add external 100n capacitor, maybe provide cleaner Vdda.

    2 replies

    gbmAnswer
    Graduate
    November 2, 2024

    Increase sampling time, add external 100n capacitor, maybe provide cleaner Vdda.

    pilotAuthor
    Graduate II
    November 2, 2024

    dumb me, it was the capacitor - thank you.  This was a quick thrown together test.

    What I really am trying to understand is the devices 1.2v Vref ,  if the AD range is actually 1.2v or 3.3v , while the internal vref is in use ... and whatever I actually need any code to "make it work" or if it is active all the time.