Working with STM32F7 and ADC part 3: Single channel Continuous Conversion with interrupt

In the previous guide (here), We took a look for how the continuous conversion working in polling mode, in this guide, we shall use interrupt for to update the value in the interrupt handler rather than manually.

In this guid will cover the following

  • Difference between polling mode and interrupt mode
  • Extra steps needed
  • Schematic
  • Code
  • Result

1. Difference between polling mode and interrupt mode 

In polling as we saw in previous two guides, we need to wait for end of conversion each time we want to read the adc value as illustrated in figure below. 

polling mode

On another hand, in interrupt mode, the adc value can be update in background (no need to wait for EOC) since in handled in the interrupt handler function as illustrated in figure below.

Interrupt mode

2. Extra steps needed to enable interrupt.

The extras steps needed from part 1 and part 2 of this guid as following

  • Declare the adc_data as volatile int variable as following:
volatile int adc_value;
  • Enable end of conversion interrupt from ADC_CR1 as shown bellow:
Enable end of conversion interrupt
ADC1->CR1|=ADC_CR1_EOCIE;
  • Handle the ADC interrupt as follow:
void ADC_IRQHandler(void)
{
	/*Check if end-of-conversion interrupt occurred*/
	
	if(ADC1->SR & ADC_SR_EOC)
	{
		/*Clear EOC flag*/
		ADC1->SR &=~ADC_SR_EOC;

		/*Do something*/
		adc_data=ADC1->DR;
	}

}

3. Schematic

The connection is as following:

  • Right leg of the pot to 3V3 
  • Middle leg to A0 of Arduino connection (PA3)
  • Left leg to GND

4. Code

#include "stm32f7xx.h"                  // Device header

#define CH3 0x03
volatile int adc_data;
int main(void)
		{
		
		RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN;
		RCC->APB2ENR|=RCC_APB2ENR_ADC1EN;

		GPIOA->MODER|=GPIO_MODER_MODER3_0|GPIO_MODER_MODER3_1;
		ADC1->SQR1=0;
		ADC1->SQR3=(CH3<<0);
		ADC1->CR1|=ADC_CR1_EOCIE;
		NVIC_EnableIRQ(ADC_IRQn);
		ADC1->CR2|=ADC_CR2_CONT;
		ADC1->CR2|=ADC_CR2_ADON;
		ADC1->CR2|=ADC_CR2_SWSTART;
		
		
		while(1){}
		
		}
		
		void ADC_IRQHandler(void)
{
	/*Check if end-of-conversion interrupt occurred*/
	
	if(ADC1->SR & ADC_SR_EOC)
	{
		/*Clear EOC flag*/
		ADC1->SR &=~ADC_SR_EOC;

		/*Do something*/
		adc_data=ADC1->DR;
	}

}

5. Results

After compile, upload, start a debug session and adding adcValue to watch window.

Rotate the pot left and right and the value shall be updated without being called each time

Add Comment

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