STM32 ADC Multiple Channels Updated method


Today in this tutorial, I will show you how to read multiple channels in ADC in STM32 using new CubeMx. For this demonstration, I am using STM32F104C8 controller and True-Studio IDE. For the ADC purpose, I am using 3 channels as mentioned below:-

  • CHANNEL 0 –> IR sensor
  • CHANNEL 1 –> Potentiometer
  • CHANNEL 16 –> Internal Temp sensor


So in order to read the multiple channels, we need to use DMA. The benefit of it is the conversion will take place in the background and we can perform some other operation with the controller and when we need the values, we can just read them easily.

Before proceeding further, Let’s see How we have to get the value from the internal temperature sensor of the STM32. According to the reference manual (Pg- 236), The temp is given as follows

V25, Avg_Slope are given in the datasheet (Pg-79)

Also note that the ADC sampling time, while reading the temperature, needs to be 17.1 us.

CubeMx Setting

Above is the clock section from the CubeMx. Note that I have selected the ADC clock as 14 MHz. The reason behind this is that the Temp sensor sampling time needs to be 17.1 us. While in the ADC setting, we have maximum sampling time as 239.5 cycles. So (239.5/14) gives us 17.1 us sampling time.

Note that 3 channels are selected and the Continuous conversion mode is enabled. Also in the new CubeMx, you don’t need to worry about scan conversion mode. It will enable and disable by it’s own based on if you are using multi channels or only one channel.

Above is the DMA setting for the ADC. MAke sure that the DMA is circular and data width is selected as ‘Word‘. This is because the CubeMx uses ADC in 12 bits resolution by default and in order to store 12 bits we need the ‘Word‘ size.

Some Insight into the Code

You can Download the full code from the link in the description below
uint32_t value[3];

HAL_ADC_Start_DMA(&hadc1, value, 3);  // start adc in DMA mode

Starts the ADC in DMA mode and the converted data is stored in ‘value‘ buffer.
‘3’ is the length of data to be transferred from ADC peripheral to memory.

float temp;

#define V25 1.43  // from datasheet
#define VSENSE 3.3/4096  // VSENSE value
#define Avg_Slope .0043  // 4.3mV from datasheet

float get_temp (uint32_t variable)
	return (((V25 - (variable*VSENSE)) / Avg_Slope) + 25);  // formula from datasheet

The above code gets the temperature of the sensor in °C. You can change the values of V25 and Avg_Slope according to your controller’s datasheet.


uint32_t value[3];

float temp;

#define V25 1.43  // from datasheet
#define VSENSE 3.3/4096  // VSENSE value
#define Avg_Slope .0043  // 4.3mV from datasheet

float get_temp (uint32_t variable)
	return (((V25 - (variable*VSENSE)) / Avg_Slope) + 25);  // formula from datasheet

int main(void)



  lcd_init ();

  HAL_ADC_Start_DMA(&hadc1, value, 3);
  while (1)
	  lcd_send_cmd (0x80);
	  lcd_send_string ("CH0- ");
	  lcd_send_data((value[0]/1000)+48);  // print 1000th digit
	  lcd_send_data(((value[0]%1000)/100)+48);  //print 100th digit
	  lcd_send_data(((value[0]%100)/10)+48);  //print 10th digit
	  lcd_send_data(((value[0]%10))+48);  //print 1st digit

	  lcd_send_cmd (0x8b);
	  lcd_send_string ("CH1- ");
	  lcd_send_cmd (0xc0);
	  lcd_send_data((value[1]/1000)+48);  // print 1000th digit
	  lcd_send_data(((value[1]%1000)/100)+48);  //print 100th digit
	  lcd_send_data(((value[1]%100)/10)+48);  //print 10th digit
	  lcd_send_data(((value[1]%10))+48);  //print 1st digit

	  temp = get_temp(value[2]);
	  lcd_send_string (" TEMP- ");
	  lcd_send_data ((temp/10)+48);
	  lcd_send_data (((int )temp%10)+48);
	  lcd_send_data ('.');
	  lcd_send_data (((int )(temp*10)%10)+48);





You can buy me a coffee sensor 🙂

Or just Download the code below

Share this POST

, , , , , , , , ,

Leave a Reply

1 Comment threads
1 Thread replies
Most reacted comment
Hottest comment thread
2 Comment authors
adminFalah Recent comment authors
newest oldest most voted
Notify of

Hi, thank you very much from your site
I want to do sampling at 10 kHz ADC and DMA
Maybe guide me ?