By default, the ADC scans the channels starting with the least significant number. For example, in the given series, channel 8 is converted first, followed by channel 9. However, a custom scan sequence can be configured, such as converting channel 9 first, followed by channel 8. This can be achieved by enabling the ScanConvMode
and assigning each channel a rank. The channel with the lowest rank value will be the first to be scanned. The NbrOfConversion
parameter must be set to the number of channels to be converted, based on the assigned ranks.
#include "app_bsp.h"
#include <stdio.h>
ADC_HandleTypeDef AdcHandler; /*adc handler estructure*/
ADC_ChannelConfTypeDef sChanConfig; /*adc channel configuration structure*/
extern void initialise_monitor_handles(void);
int main(void)
{
uint32_t pot1, pot2;
HAL_Init(); /*init HAL library*/
/*Enable semihosting only to display adc lecture*/
initialise_monitor_handles();
printf("Hola semihosting\n\r");
/* Conversion time is given by::
Tcon = ( Tsampling + Tconv ) / ADC clock
Tcon = ( AdcHandler.Init.SamplingTimeCommon1 + AdcHandler.Init.Resolution ) / ( APB Clock / AdcHandler.Init.ClockPrescaler )
Tcon = ( 1.5 + 8.5 ) / 8MHz = 1.25us */
AdcHandler.Instance = ADC1;
AdcHandler.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; /*APB clock divided by two*/
AdcHandler.Init.Resolution = ADC_RESOLUTION8b; /*8 bit resolution with a Tconv of 8.5*/
AdcHandler.Init.ScanConvMode = ADC_SCAN_ENABLE; /*scan adc channels according to custom sequence*/
AdcHandler.Init.NbrOfConversion = 2; /*specify we gonna use up to 2 ranks*/
AdcHandler.Init.DataAlign = ADC_DATAALIGN_RIGHT; /*data converter is right alightned*/
AdcHandler.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5; /*sampling time of 1.5*/
AdcHandler.Init.ExternalTrigConv = ADC_SOFTWARE_START; /*software trigger*/
AdcHandler.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /*only applicable on ISR*/
AdcHandler.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /*data will be overwriten in case is not read it*/
AdcHandler.Init.DiscontinuousConvMode = ENABLE; /*Discontinuos mode, one channel convertion at a time*/
/*apply ADC configuration*/
HAL_ADC_Init( &AdcHandler );
/*config adc channel number 0 with a rank of 2*/
sChanConfig.Channel = ADC_CHANNEL_0;
sChanConfig.Rank = ADC_REGULAR_RANK_2;
sChanConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
/*apply channel configuration*/
HAL_ADC_ConfigChannel( &AdcHandler, &sChanConfig );
/*config adc channel number 1 with a rank of 1 to be the first channel to be scanned*/
sChanConfig.Channel = ADC_CHANNEL_1;
sChanConfig.Rank = ADC_REGULAR_RANK_1;
sChanConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
/*apply channel configuration*/
HAL_ADC_ConfigChannel( &AdcHandler, &sChanConfig );
/*Apply internal calibration*/
HAL_ADCEx_Calibration_Start( &AdcHandler );
while (1)
{
HAL_ADC_Start( &AdcHandler ); /*trigger conversion on channel 0*/
HAL_ADC_PollForConversion( &AdcHandler, 1u );/*wait untill conversion is performed, around 1.25us*/
pot1 = HAL_ADC_GetValue( &AdcHandler ); /*read the digital value*/
HAL_ADC_Start( &AdcHandler ); /*trigger conversion on channel 1*/
HAL_ADC_PollForConversion( &AdcHandler, 1u );/*wait untill conversion is performed, around 1.25us*/
pot2 = HAL_ADC_GetValue( &AdcHandler ); /*read the digital value*/
printf( "pot 1: %lu, pot 2: %lu\r\n", pot1, pot2 ); /*print the adc values*/
HAL_Delay( 1000u ); /*retardo de 100ms*/
}
}
msps.c
/*This function is called in HAL_ADC_Init*/
void HAL_ADC_MspInit( ADC_HandleTypeDef* hadc )
{
GPIO_InitTypeDef GPIO_InitStruct;
__ADC_CLK_ENABLE(); /*enable adc clock*/
__GPIOA_CLK_ENABLE(); /*enable clock port where the adc 0 is connected*/
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; /*pin in analog mode*/
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}