Posted on August 6, 2018 at 9:00 PM
This guide will illustrate using the difference ADC conversion triggers on the NUCLEO-L476RG. CubeMX is used to generate the project files. It aims to fill the gap between the manuals on the HAL drivers, the STM32L4 referece manual and the CubeMX configuration boxes.
The document will follow the steps for configuring the NUCLEO-L476RG and setting up the project to read IN1 on ADC1 using the following triggers:
I have found working out the relationship between the Registers and the CubeMX check boxes to be a little confusing at times so this document is wrttien as a guide mainly for myself in the hope that later it will jog my memory but hopfully others might find it useful too.
Choose which channels which will be sampled, for the example I use only single channel IN1. This is the only Pin Configuratin needed for Softare Converison. Dont be fooled by Conversion Trigger this is for Pinout configuration that is if you want to trigger on a pin input.
In ADC configuration need to select External conversion trigger source and also ensure Continious Conversion Mode is DISABLED, if it is enabled the trigger will not matter and the ADC will sample continiously.
I want to generate an interupt at the end of conversion (EOC) so I will enable the interupt in NVIC tab. If instread you want to POLL for the end of conversion this is not needed.
Generate the code and make the software chages
With Software trigger the ADC can start with
int main(void)
{
...
/* USER CODE BEGIN 2 */
HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)
{
/* End Of Conversion flag not set on time */
Error_Handler();
}
/* Check if the continous conversion of regular channel is finished */
if ((HAL_ADC_GetState(&hadc1) & HAL_ADC_STATE_REG_EOC) == HAL_ADC_STATE_REG_EOC)
{
/* Get the converted value of regular channel*/
uint32_t value = HAL_ADC_GetValue(&hadc1);
}
OR start the ADC using IT and then configure the interupt handler
int main(void)
{
...
/* USER CODE BEGIN 2 */
HAL_ADC_Start_IT(&hadc1);
Setup the ADC conversion complete callback, good practise to check that the interupt handler has been generated in stm32l4xx_it.c.
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
uint32_t value = HAL_ADC_GetValue(&hadc1);
}
That is it, you have a conversion triggered by software, although not doing anything with the value.
As per above for the ADC, but here I add a timer. Timer1, not that I am not setting an output.
In ADC configuration need to select External conversion trigger source and also ensure Continious Conversion Mode is DISABLED, if it is enabled the trigger will not matter and the ADC will sample continiously.
I want to generate an interupt at the end of conversion (EOC) so I will enable the interupt in NVIC tab. If instread you want to POLL for the end of conversion this is not needed.
In the timer configuration need to select when at pulse will be sent to TRGO. Here I have selected Update Event, counter overflow. The frequecny of the pulse configured by PSC and ARR.
Generate the code and make the software chages
int main(void)
{
...
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start(&htim1);
if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK)
{
/* ADC Calibration Error */
Error_Handler();
}
HAL_ADC_Start_IT(&hadc1);
Setup the ADC conversion complete callback, good practise to check that the interupt handler has been generated in stm32l4xx_it.c.
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
uint32_t value = HAL_ADC_GetValue(&hadc1);
}
That is it, you have a conversion triggered by the Update Event of Timer1 through TRGO, although not doing anything with the value. Using TRGO2 is exactl the same process, just selection TRGO2:
As per above for the ADC, but changes to Timer are need. Again note that no output is being generated but I am using a Channel for a Compare Capture event generation. The channel setup needs to match that set it the ADC configuratio we are using Capture Compare 1 so need to set up Channel1.
In ADC configuration need to select External conversion trigger source and also ensure Continious Conversion Mode is DISABLED, if it is enabled the trigger will not matter and the ADC will sample continiously.
I want to generate an interupt at the end of conversion (EOC) so I will enable the interupt in NVIC tab. If instread you want to POLL for the end of conversion this is not needed.
Here we setup the Comapre Match settings. Remeber to set pulse to be less that the AutoReload setting, else it will ever be reached and will not set a trigger.
Generate the code and make the software chages
int main(void)
{
...
/* USER CODE BEGIN 2 */
HAL_TIM_OC_Start(&htim1);
if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK)
{
/* ADC Calibration Error */
Error_Handler();
}
HAL_ADC_Start_IT(&hadc1);
NOTE: I don't start the TIM with _IT as I am not using the interupt handler.
Setup the ADC conversion complete callback, good practise to check that the interupt handler has been generated in stm32l4xx_it.c.
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
uint32_t value = HAL_ADC_GetValue(&hadc1);
}
That is it, you have a conversion triggered the output compare event on Timer 1. Set a break point on the ADC callback, or toggle the led inside the callback oand or change the timer to provide an output to a change to see the covnersion timing.
The guide has stepped throguh process of setting the various triggers for ADC conversion. These features of the low cost Nucleo baords have proven to be are very powerful and convenient for a number of my projects and hope this guide will help you to realse the same.
Any questions or suggestions feel free use the contact me.
The following are the documents referenced in this guide and the key documents for any project using this STM32L476 microprocessor.