How to change stm32 m4 adc channel?

Does anyone know how to do it in register level?

I see many code examples using:

ADC_ChannelConfTypeDef sConfig = {ADC_CHANNEL_0, 1, ADC_SAMPLETIME_28CYCLES}; HAL_ADC_ConfigChannel(&hadc1, &sConfig); or ADC_RegularChannelConfig(ADC1, ADC_channel_0, 1, ADC_SampleTime_480Cycles);

but i don't have access to these routines from arm-gcc.

By the way, i am using this to read the adc data:

#include "stm32f407xx.h" ADC1->CR2 |= ADC_CR2_SWSTART; // Start A2D while (!(ADC1->SR & ADC_SR_EOC)); // ready wait data = ADC1->DR;

Reply to
Ed Lee
Loading thread data ...

That last statement shows you perhaps don't have a full understanding of what you are doing here.

However, the most likely cause of your troubles is that the examples you have are using an SDK from ST, and you either don't have the SDK installed and set up correctly, or you aren't using it in your project, or you have simply forgotten to include the appropriate headers at the start of your C file.

I have not used ST's tools myself, but I would expect that their SDK comes with complete working example projects for some evaluation boards. Start with one of these, and adapt it to suit your required changes.

Reply to
David Brown

If you download and install ST's Cube etc you will end up with (amongst a LOT of other stuff) the library code that you could use if you want functions like:


I don't use these - they try to be universal but end up being hard to understand and slow.

To drive the ADC directly you will need to study the reference manual and register descriptions and it may well help to look at some ST examples (from the Cube again).

To address your specific problem:

Assuming a single conversion of one channel and starting after a hardware reset:

write the channel to be converted into the SQ1 field of ADC_SQR3

make sure the L field of ADC_SQR1 = 0 so the ADC does just one conversion

set the SMP field for the channel in question to the sampling time you want (ADC_SMPR1 or ADC_SMPR2)

enable the ADC by setting bit 0 in ADC_CR1

start the conversion by setting bit 30 in ADC_CR2

(All the above based on Ref manual for STM446xx - check details for your own processor.)

You will need to enable the ADC clock but you must have got there already.


Reply to
Michael Kellett

OK, i think this is getting close, but also need to select the Alt-Funct Reg for the port pin. I was hoping to find a complete example of such.

Reply to
Ed Lee

You don't use the GPIO port Alt Function Register for making a pin an analogue input. You do it by setting the mode bits for that pin in the GPIO Mode register. There are two bits for each pin, coded like this:

Bits 2y:2y+1 MODERy[1:0]: Port x configuration bits (y = 0..15) These bits are written by software to configure the I/O direction mode.

00: Input (reset state) 01: General purpose output mode 10: Alternate function mode 11: Analog mode

I don't have any shareable examples that don't use DMA with scan and usually continuous mode for the ADC which I think might be distracting.


Reply to
Michael Kellett

So, reading from PA0 or PA1 like this?

RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // Enable ADC clock ADC1->CR2 |= ADC_CR2_ADON; // Enable ADC ADC1->SQR1 = 0; // bit 23-20 single coversion ADC->SMPR2 = 2; // 28 cycles

#if PA0 GPIOA->MODER |= 3; // bit 1-0 Analog mode ADC1->SQR3 = 0; // bit 3-0,0 channel 0 #endif

#if PA1 GPIOA->MODER |= 0xc; // bit 3-2 Analog mode ADC1->SQR3 = 1; // bit 3-0,0 channel 1 #endif

ADC1->CR2 |= ADC_CR2_SWSTART; // Start ADC while (!(ADC1->SR & ADC_SR_EOC)); // ready wait DATA = ADC1->DR; // read data

Reply to
Ed Lee

Not quite, entries in SMPR1/2 are for each ADC channel, not each entry in the sequencer. So for PA1 you need to set SMP1 bit field to 2, ADC->SMPR2 = (uint32_t)2

Reply to
Michael Kellett

I guess i can measure the average conversion time from a sampling loop. For 100MHz clock, even 480 cycles are more than enough.

One question remain. How does it ties PA0 with channel 0? If it's hard coded, does it mean only port A can be analog?

Reply to
Ed Lee

Each analog channel is hard tied internally to a given pin. (They are all port A from my memory, but scattered about a bit). Read the device reference manual for a listing of the capability of each pin.

Reply to
Richard Damon











r your


Funct Reg for the port pin. I was hoping to find a complete example of such .






For 100MHz clock, even 480 cycles are more than enough.

coded, does it mean only port A can be analog?

OK, i will have dig a bit deeper in the reference manual.

This info is critical for someone like me new to the STM chip.

For the (microchip/Atmel) ?A SAM world, we have to set them explicitly .

PORT->Group[1].DIRCLR.reg = PORT_PB09; // Enable the peripheral multiplexer for PB09 PORT->Group[1].PINCFG[9].reg |= PORT_PINCFG_PMUXEN; // Set PB09 to function B which is analog input. PORT->Group[1].PMUX[4].reg = PORT_PMUX_PMUXO_B;

Reply to
Ed Lee

The STM pins also have config registers to configure which special function (if any) they are set for. There generally is a table listing every pin and what functions it can connect to.

Reply to
Richard Damon

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.