cancel
Showing results for 
Search instead for 
Did you mean: 

How to connect a ADCx_INx pinto the ADCx

Randy Nelson
Associate III
Posted on October 27, 2017 at 17:44

I'm trying to do a bare metal setup for a STM32F303K8 and am trying to understand how STM ADCx_INx pins are connected/routed to an ADC. Is there a multiplexer that is setup to 'gate' one of the the many ADC INx pins to a ADC?

In particular which registers do I manually configure, for example, to connect ADC2_IN4  to the ADC2. I'm assuming I would first set the pin to analog using the MODER register. But what register should I do next? My goal is to do a reading on one pin one time.

Thanks for any direction.

1 ACCEPTED SOLUTION

Accepted Solutions
Posted on October 30, 2017 at 14:33

I was able to get a reading on ADC2_IN4 using the STM32F303K8 on a STM32F303 Nucleo-32 evaluation/development board. I had found an example using ADC1_IN1 and was attempting to modify for

mailto:ADC@_IN4

. My issue was understanding the ADCx_SQR register. My read on this register it that it is a list of channels (IN1,IN2,...) pins, in a regular group, that will be read/converted in a particular order. So for ADC2_IN4, setup as the first (and only) pin,  I had to set  

ADC2_SQR1's SQ1 as a 0x4. The ADC2_SQR1's 'L' field describes the length or number of channels to convert and defaults to 0x00 or 1 conversion.  

My converted the sample code from ADC1_IN1 to ADC2_IN4 and it now works. The code is listed below.

Thanks to all that read and thought about my question.

Randy

//

// clocks are already setup

//

GPIOA_MODER |= BIT15+BIT14;  //make PA7, ADC2_IN4, analog

RCC_AHBENR |= BIT28; // turn on ADC clock

ADC12_CCR |= BIT17; // Set ADC clock = HCLK / 2=32MHz

ADC2_CR &= ~BIT0; // disable the ADC

// enable the ADC voltage regulator

ADC2_CR &= ~BIT29;

ADC2_CR |= BIT28;

// start ADC calibration cycle

ADC2_CR |= BIT31;

while (ADC2_CR & BIT31); // wait for calibration to complete

ADC2_CR |= BIT0; // enable the ADC

ADC2_SQR1 = (1 << 8); // Select ADC Channel 4, This is important and what I was missing

while(1) {

     ADC2_CR |= BIT2; // start conversion

     while (ADC2_CR & BIT2); // wait for end of conversion

     int_var_V1 = ADC2_DR;   //also a break point for debug

}

View solution in original post

4 REPLIES 4
S.Ma
Principal
Posted on October 27, 2017 at 19:01

If available use the Injected channel. Each channel has its own DR, no need to use DMA to unmux the shared DR on normal channel. You can also use a trigger pin to launch a conversion so it can be done manually.

You might even have fun in debug mode by manually changing the ADC registers and see how to get a valid conversion, otherwise, use HAL or LL to get there from a Nucleo or Discovery example.

Posted on October 29, 2017 at 19:51

Thanks for the info but I do not understand 'use the Injected' channel. I do not remember seeing this in the data sheet. Is 'DR' 'data register'? Do not understand this either. I understand setting up a GPIO pin manually. I also understand that certain GPIO pins are also ADCx pins such as ADC2_IN3. What I cannot find is what register to set to connect ADC2_IN3 to the ADC2. Do I use the SQR register? if yes then what is the value for the ADC2_IN3? Is it 0x3? I cannot find this mapping?

Thanks for any direction. I'm simply trying to read a voltage at ADC2_IN3 in the simplest fashion. No DMA.

Posted on October 30, 2017 at 05:00

Injected Channels are typically on STM32F4, maybe you are using an M0? Then you might need to use DMA as shown in some board example.

Posted on October 30, 2017 at 14:33

I was able to get a reading on ADC2_IN4 using the STM32F303K8 on a STM32F303 Nucleo-32 evaluation/development board. I had found an example using ADC1_IN1 and was attempting to modify for

mailto:ADC@_IN4

. My issue was understanding the ADCx_SQR register. My read on this register it that it is a list of channels (IN1,IN2,...) pins, in a regular group, that will be read/converted in a particular order. So for ADC2_IN4, setup as the first (and only) pin,  I had to set  

ADC2_SQR1's SQ1 as a 0x4. The ADC2_SQR1's 'L' field describes the length or number of channels to convert and defaults to 0x00 or 1 conversion.  

My converted the sample code from ADC1_IN1 to ADC2_IN4 and it now works. The code is listed below.

Thanks to all that read and thought about my question.

Randy

//

// clocks are already setup

//

GPIOA_MODER |= BIT15+BIT14;  //make PA7, ADC2_IN4, analog

RCC_AHBENR |= BIT28; // turn on ADC clock

ADC12_CCR |= BIT17; // Set ADC clock = HCLK / 2=32MHz

ADC2_CR &= ~BIT0; // disable the ADC

// enable the ADC voltage regulator

ADC2_CR &= ~BIT29;

ADC2_CR |= BIT28;

// start ADC calibration cycle

ADC2_CR |= BIT31;

while (ADC2_CR & BIT31); // wait for calibration to complete

ADC2_CR |= BIT0; // enable the ADC

ADC2_SQR1 = (1 << 8); // Select ADC Channel 4, This is important and what I was missing

while(1) {

     ADC2_CR |= BIT2; // start conversion

     while (ADC2_CR & BIT2); // wait for end of conversion

     int_var_V1 = ADC2_DR;   //also a break point for debug

}