Skip to main content
Randy Nelson
Associate III
October 27, 2017
Solved

How to connect a ADCx_INx pinto the ADCx

  • October 27, 2017
  • 1 reply
  • 1165 views
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.

    This topic has been closed for replies.
    Best answer by Randy Nelson
    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

    }

    1 reply

    S.Ma
    Principal
    October 27, 2017
    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.

    Randy Nelson
    Associate III
    October 29, 2017
    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.

    S.Ma
    Principal
    October 30, 2017
    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.