10 ADC DMA TIM HAL Lab
10 ADC DMA TIM HAL Lab
• Using ADC collect data from selected analog channel (i.e. internal
temperature sensor),
• When buffer is full, TIM2 should be stopped and interrupt should be raised
to allow ADC data postprocessing
Start a new workspace
• Run STM32CubeIDE
• To start a new
project we need to
double click on the
part number
Enter project name
• Specify project name, optionally its
location (if different from workspace
one)
• System is working on default clock settings (HSI 16MHz, no PLL) and we use
ADC clock as system clock / 2 => 8MHz
• We have Timer2 input clock 16 MHz (default system clock settings using HSI
without PLL)
• We can set prescaler (PSC) to 15999 (actual divide is PSC+1) to have 1kHz on
Timer2 counter input
• Then we need to set Timer2 period to 999 (as we are counting from 0) to have
overflow (update event) each 1 second
TIM2 configuration
• Select Timers->TIM2
• Set clock source to Internal Clock
• Configure:
• Prescaler to 15999
• Counter period to 999
• MSM bit: Enable
• TRGO selection: Update Event
Generate the code
• Save the design settings to trigger code generation
Coding time – defines and variables
main.c file
• Define data buffer size and ADC reference voltage (in mV) used for temperature calculation
/* USER CODE BEGIN PD */
#define ADC_BUF_SIZE 8
#define __VREFANALOG_VOLTAGE__ 3300//ADC reference voltage in mV
• Perform ADC calibration, start ADC and start TIM2 which would trigger ADC conversion each 1second
/* USER CODE BEGIN 2 */
if(HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK)
Error_Handler();
if(HAL_TIM_Base_Start(&htim2) != HAL_OK)
Error_Handler();
• In all cases we are monitoring proper function execution by checking return value
Coding time – ADC data collection and ADC stop
main.c file
• As we have configured DMA in Normal mode, it would be stopped once the buffer
will be filled with the data
• Additionally a DMA transfer complete interrupt will be triggered which could be used
to stop ADC or simply TIM2 which is triggering ADC.
• DMA transfer complete interrupt is linked with HAL_ADC_ConvCpltCallback(),
so we can use the same callback in case we are using ADC in IRQ or in DMA mode
/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if(HAL_ADC_Stop_DMA(&hadc1) != HAL_OK)
Error_Handler();
}
/* USER CODE END 4 */
… Let’s check it
• After all code processing we can build the project, start debug session and run the
application
• Adding it to watch (left mouse button click on its name and select Add Watch Expression and
then fill then name of the variable into “Add Watch Expression” window
Monitoring of variables in debug mode
• We can set a breakpoint within HAL_ADC_ConvCpltCallback() which would be
called once complete buffer is filled with data.
• Now we need to recalculate measured values into deg C values. We can use
macro __LL_ADC_CALC_TEMPERATURE()
Thank you
www.st.com/stm32g0, www.st.com/stm32cubeide