STM32-Peripheral’s-ADC: Timer interrupt mode

STM32-Peripheral’s-ADC: Timer interrupt mode

An analog to digital converter is a circuit that converts a continuous voltage value (analog) to a binary value (digital) that can be understood by a digital device which could then be used for digital computation. These ADC circuits can be found as an individual ADC ICs by themselves or embedded into a microcontroller. They’re called ADCs for short.

ADC Peripheral features: (STM32F429XX)


1. 12-bit, 10-bit, 8-bit or 6-bit configurable resolution.
2. Interrupt generation at the end of conversion, end of injected conversion, and in case of analog watchdog or
overrun events
3. Single and continuous conversion modes.
4. Scan mode for automatic conversion of channel 0 to channel x.
5. Data alignment with in-built data coherency.
6. Channel-wise programmable sampling time.
7. External trigger option with configurable polarity for both regular and injected conversion.
8. Dual/Triple mode (on devices with 2 ADCs or more).
9. Configurable DMA data storage in Dual/Triple ADC mode.
10. Configurable delay between conversions in Dual/Triple interleaved mode.
11. ADC conversion type (refer to the datasheets).
12. ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at slower speed.
13. ADC input range: VREF(minus) = VIN = VREF(plus).
14. DMA request generation during regular channel conversion.

How to use this driver

Initialize the ADC low level resources by implementing the HAL_ADC_MspInit():
a. Enable the ADC interface clock using __HAL_RCC_ADC_CLK_ENABLE()
b. ADC pins configuration
◦ Enable the clock for the ADC GPIOs using the following function:
__HAL_RCC_GPIOx_CLK_ENABLE()
◦ Configure these ADC pins in analog mode using HAL_GPIO_Init()
c. In case of using interrupts (e.g. HAL_ADC_Start_IT())
◦ Configure the ADC interrupt priority using HAL_NVIC_SetPriority()
◦ Enable the ADC IRQ handler using HAL_NVIC_EnableIRQ()
◦ In ADC IRQ handler, call HAL_ADC_IRQHandler()
d. In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA())
◦ Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE()
◦ Configure and enable two DMA streams stream for managing data transfer from peripheral to
memory (output stream)
◦ Associate the initialized DMA handle to the CRYP DMA handle using __HAL_LINKDMA()
◦ Configure the priority and enable the NVIC for the transfer complete interrupt on the two DMA
Streams. The output stream should have higher priority than the input stream.

Execution of ADC conversions


1. ADC driver can be used among three modes: polling, interruption, transfer by DMA.
Polling mode IO operation
• Start the ADC peripheral using HAL_ADC_Start()
• To read the ADC converted values, use the HAL_ADC_GetValue() function.

For this blog we are going to use ADC in trigger mode (Single Channel) , for demonstration purpose we will configure neo DAC, output of DAC will be Input of ADC channel & Timer 2 is used to trigger adc conversion.

Creating STM32 executable projects steps are available on this link , please follow steps 1 to 10 as per blog, here we will start from step 11. PA9 & PA10 Pin used for debugging purpose as UART Tx & UART Rx respectively. to learn more about ADC in scan mode click here.

11. Enable ADC Functionality

Go to System mode > Analog > ADC > Enable IN0

Figure 1: Enable ADC

12. Enable external trigger conversion mode

Go to System mode > Analog > ADC > Parameter settings > External Trigger Conversion Source > Timer 2 Trigger Out Event

Go to System mode > Analog > ADC > Parameter settings > External Trigger Conversion Edge > Trigger detection on the rising edge

Figure 2: Enable external conversion mode

13. Enable adc Interrupt

Go to System mode > Analog > ADC > NVIC settings > ADC Interrupt enable

Figure 3: Enable ADC Interrupt

14. Enable timer 2 for internal ADC trigger

Go to System mode > Timers > Tim2 > Clock Source > Enable Internal Clock

Go to System Mode > timers > Tim2 > Parameter Settings > Set timer according to your requirement

Go to System Mode > timers > Tim2 > Parameter Settings > Trigger Event Selection > select Update Event

Figure 4: Enable Timer 2 for internal ADC Interrupt

15. Press below icon for code generation

Figure 5: Cube IDE Code Generation

16. Sample Code

static volatile U8 endOfConversion = 0;
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	endOfConversion = 1;
}

  HAL_ADC_Start_IT(&hadc1);	//Enable ADC in interrupt mode 
  HAL_TIM_Base_Start(&htim2);//Enable timer 2 for adc internal trigger.

while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	HAL_Delay(1000);	//1000 ms delay
	RTC_CalendarShow(aShowTime, aShowDate);
	uart1_printf_debug(YEL"time = %s\n",aShowTime);
	HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, dac_data);
	HAL_Delay(500);	//500 ms delay
	uart1_printf_debug(GRN"DAC Value = %d  === ",dac_data);

	if (endOfConversion == 1)
	{
		adcvalue = HAL_ADC_GetValue(&hadc1);
		uart1_printf_debug(GRN"ADC Value 0 = %d\n",adcvalue);
		endOfCOnversion = 0;
	}

	dac_data++;
	if (dac_data > 2100)
		dac_data = 2048;
  }

16. Debug Output

Figure 5: Debug Output
Software Tools:
  1. STM32CubeIDE
  2. STM32CubeMx
  3. Teraterm
Hardware Setup:
  1. STM32F429IDISCOVERY board
  2. Mini USB Cable
  3. Jumper wire
Conclusion:

Successfully demonstrated ADC functionality in trigger mode (Single Channel), for testing purpose we have used DAC to connect its output to ADC & UART for debug.

References:
  1. STM32 HAL Library
  2. STM32 UM1718 document
Similar topics:
  1. https://kalapiinfotech.in/stm32-cube-ide-freertos-code-generation-using-cubemx/
  2. https://kalapiinfotech.in/stm32-peripherals-gpio-output-input/
  3. https://kalapiinfotech.in/stm32-peripherals-dac/
  4. https://kalapiinfotech.in/stm32-peripherals-adc-polling-method/

Leave a Reply

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

%d bloggers like this: