Some applications require periodic sampling of analog signals using an ADC (Analog to Digital Converter) for digital signal processing. The objective of this article is to explain how to configure an STM32 Timer to trigger ADC conversions at a configurable sampling frequency. A GPIO pin will be toggled with every ADC conversion to show that the sampling is at the expected frequency.
0. Introduction
Some applications require periodic sampling of analog signals using an ADC (Analog to Digital Converter) for digital signal processing. The objective of this article is to explain how to configure an STM32 Timer to trigger ADC conversions at a configurable sampling frequency. A GPIO pin will be toggled with every ADC conversion to show that the sampling is at the expected frequency.
1. Pre-requisites
- Micro USB Cable used to power the Nucleo board from a Host Machine. The same cable is used to load the code into the STM32 on the Nucleo board.
- Oscilloscope to check the frequency of the toggling GPIO pin.
2. Steps
- Open STM32CubeIDE and create a project using the board NUCLEO-H745ZI-Q
- GPIO configuration
STM32CubeIDE, by default, will initialize a GPIO for the on-board green LED (PB0).Please change “Pin Context Assignment” to ARM Cortex-M7 as shown in the screenshot below.Make sure the configuration of PB0, which is the GPIO being used is configured as follows:
- ADC configuration
In this section we will configure the ADC1 peripheral of the STM32H7 as follows:
- Single Conversion on channel 2
- Regular conversion mode
- Triggered by Timer 1 trigger output
- Enable interrupts for ADC1 so that the GPIO can be toggled at the end of the ADC conversion in the call back function.
- Clock Configuration: 480/240 MHz
We are running the STM32H7 at its maximum speed: 480 MHz for the system frequency and 240 MHz for the peripheral bus frequency.
- Timer Configuration
In this section we will configure the timer that will be used to trigger the ADC conversions per the following:
- PWM generation, no output needed since timer is triggering ADC internally
- Auto Reload Register (ARR) set to 24000 will yield 10kHz sampling frequency:
- TIMclk / ARR = SamplingFreq
- 240MHz / 24000 = 10KHz
- Trigger out set to Update Event i.e. trigger event every time the timer counter reaches ARR
- Generate the code
Save the STM32CubeIDE and that will generate the code.
- Code to be added in main.c for CM7 project
- Declare a variable to store the ADC conversion
/* USER CODE BEGIN PV */
uint32_t adc_val;
/* USER CODE END PV */
- Calibrate ADC for better accuracy and start the ADC with interrupts and Start the Timer
/* USER CODE BEGIN 2 */
// calibrate ADC for better accuracy and start it w/ interrupt
if(HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK)
Error_Handler();
if(HAL_ADC_Start_IT(&hadc1) != HAL_OK)
Error_Handler();
// start pwm generation
if(HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1) != HAL_OK)
Error_Handler();
/* USER CODE END 2 */
- Save the ADC conversion value and Toggle LED for every completed conversion
/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
adc_val = HAL_ADC_GetValue(&hadc1);
// Toggle the Green LED
HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);
}
/* USER CODE END 4 */
Now compile and flash the code to your Nucleo board, reset the board to run the code.
3. Results
The Green LED is toggling every 100 us indicating the ADC is sampling at the desired 10 KHz rate.Here is an oscilloscope capture that shows the Green LED GPIO toggling at the desired rate:
4. Links
5. Video
In this video we discuss the different steps that were covered in this article:Hands-On with STM32 Timers: Trigger Periodic ADC Conversions - YouTube