Working with ADC and STM32 part2: Single Channel Continuous Conversion

ADC Logo

In the part 1 of working with ADC and STM32 (link), we talked about the ADC and how it does work, configure it to read a potentiometer using single conversion method. In this guide we shall discuss the continuous ADC conversion polling mode (i.e. wait until end of conversion).

In this guide, we will cover the following:

  • Difference between Single Conversion and Continuous Conversion.
  • What extra steps needed to enable continuous mode.
  • Required parts and schematics
  • Code
  • Results

1. Difference between Single Conversion and Continuous Conversion

In the single conversion mode, the ADC does one conversion and stop as soon as the conversion ended. The process can’t started unless the start is triggered by software. This can be useful for certain application like monitor battery capacity like every 10 minutes.

In continuous conversion mode, the ADC starts a new conversion as soon as it finishes one. This mode has the advantage of keeping the ADC value up to date for control purposes such as temperature, flow rate etc.

2. What the extra steps needed to enable Continuous Conversion

As we saw from the previous guide, we enabled the adc manually every time we needed to get a new adc value. To enable continuous mode, we need to enable CONT_bit (Bit 1) in Control Register 2 (CR2)

Enabling Continuous mode of the ADC

Also, The SWSTART shall be set in the initialization function of the ADC

Hence, the new ADC initialize function looks like this:

RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN; //enable gpio a clock
RCC->APB2ENR|=RCC_APB2ENR_ADC1EN; //enable adc clock
GPIOA->MODER|=GPIO_MODER_MODER1;  //set the PA1 to analog mode
ADC1->CR2=0; //disable the adc
ADC1->CR2|=ADC_CR2_CONT; 	
ADC1->SQR3|=1; //we are converting only one channel
ADC1->CR2|=1; //enable the adc 
ADC1->CR2|=ADC_CR2_SWSTART; //start adc conversion	

3. Required parts and schematic

The required parts, schematics and connection is the same as part one of this guide (link).

4. Code

The final code shall be like this

//read the analog voltage on PA1

#include "stm32f4xx.h"                  // Device header
#include "stdint.h"
void ADC_init(void);
void delayMs(int delay);
uint16_t adcValue;

int main(void){
ADC_init();

	
while(1){

//wait for the end of conversion 
while(!((ADC1->SR)&ADC_SR_EOC)){;}
adcValue=ADC1->DR;
delayMs(10);
}

}
void ADC_init(void){
RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN; //enable gpio a clock
RCC->APB2ENR|=RCC_APB2ENR_ADC1EN; //enable adc clock
GPIOA->MODER|=GPIO_MODER_MODER1;  //set the PA1 to analog mode
ADC1->CR2=0; //disable the adc
ADC1->CR2|=ADC_CR2_CONT; 	
ADC1->SQR3|=1; //we are converting only one channel
ADC1->CR2|=1; //enable the adc 
ADC1->CR2|=ADC_CR2_SWSTART; //start adc conversion	
}

void delayMs(int delay)
{
int i;
for(; delay>0 ;delay--)
{
for(i =0; i<3195;i++);
}

}

5. Results

After compiling the code, uploading the code to mcu, opening a debug session in keil uVision 

Rotate the potentiometer and observe the adcValue in watch window

Potentiometer rotate Counter clockwise
Potentiometer rotate clockwise 

Add Comment

Your email address will not be published. Required fields are marked *