Saturday, 12 August 2017

ADC in STM32 using HAL

Most of us know the importance of ADC and the fact that simpler it is to use the ADC in any device, the more easier it is to make any project. Most of the sensors use ADC for data transmission to the microcontroller and that's why ADC plays an important role in any embedded system design.
Earlier microcontrollers, such as 8051, didn't had ADC built in to the microcontroller and so there were external ADC connectors, making design more complex. But with the introduction of AVR and PIC, things changed and users started using these instead of 8051. ADC in STM32 is very advanced and very complex. But we will start from basics and take one step at a time. First let's look into some features of ADC:

  • 12-bit, 10-bit, 8-bit or 6-bit configurable resolution  
  • Interrupt generation at the end of conversion, end of injected conversion, and in case of analog watchdog or overrun events
  • Single and continuous conversion modes
  • Scan mode for automatic conversion of channel 0 to channel ‘n’
  • Data alignment with in-built data coherency
  • Channel-wise programmable sampling time
  • External trigger option with configurable polarity for both regular and injected conversions
  • Discontinuous mode
  • ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at slower speed
  • ADC input range from Vref- to Vref+.
  • DMA request generation during regular channel conversion


SOME Basics:-

A/D conversions are as follows:-

  • Continuous Conversion mode. If enabled, ADC will Continuously sample and convert. If disabled, only one sampling and conversion will be performed and than A/D will stop.
  • Scan Conversion mode. Configures the sequencer of groups. If it is disabled, conversion is performed in a single conversion mode (the one defined in rank 1). If enabled, conversions are performed in sequence mode up the rank.
  • Discontinuous Conversion mode. Specifies whether the conversions sequence of regular group is performed in Complete-sequence/Discontinuous-sequence (main sequence subdivided in successive parts).Discontinuous mode is used only if sequencer is enabled (parameter 'ScanConvMode'). If sequencer is disabled, this parameter is discarded.


ADC needs the trigger in order to start conversion. Trigger signal are of two types:-

  • Software Trigger. This will start A/D conversion from the code.
  • Hardware Trigger. This will start A/D conversion in case of any hardware events eg- timer event.


HOW TO:

1.) In the STM32CubeMx, select Adc and channel


2.) Leave the clock untouched and go to the configure tab and select ADC. Now make sure your configuration is as in the picture below


Here Resolution of adc is selected as 12 bit
          Scan conversion mode is disabled because only one channel is selected and sequence is not needed at this time.
           Continuous conversion mode is enabled as we want adc to work continuously.
           DMA continuous request is disabled as we are not using DMA here.

3.) generate the project and open it.


As mentioned above, we will take one step at a time, starting with the most basic one. Also I will be using HAL libraries to write the code. 

So let's start with PollForConversion method. This will Poll the ADC and wait for the conversion to end. We can specify timeout in case of errors.

HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)

here ADC_HandleTpeDef is the handler for current ADC
        Timeout is the timeout in case of errors.


FIRST we need to define a variable to store the value of ADC.
uint32_t value;

Now start ADC
HAL_ADC_Start (&hadc1);

Inside while loop write a function to poll ADC for the conversion.
HAL_ADC_PollForConversion (&hadc1, 1000);

Get the value of ADC and store it in variable, created above
value = HAL_ADC_GetValue (&hadc1);

The CODE is as follows:

uint32_t value;

int main ()

{
   HAL_ADC_Start (&hadc1);
    while (1)
    {
      HAL_ADC_PollForConversion (&hadc1, 1000);
      value = HAL_ADC_GetValue (&hadc1);
    }
}

To test this I am using a IR motion sensor, which works with ADC. I am not going to go in depth of how this sensor works. You can consider it as a potentiometer or a variable resistor to test ADC.

So if the sensor does not detect any obstacle, it's resistance will be 100%, which is 4095 in our 12 bit ADC mode. Upon detection, it's resistance will decrease. I am not using any LCD here so in order to see the value change, we have to either use debugger or Stm studio. I will show the results in both of them.

Compile the code and load it to the board. Now, switch to debugging mode.

Add variable (value) to watch list. It is recommended to create this variable as global.


Run debugger, also just have a look at watch list. I have changed display from hexadecimal to decimal.


With no obstacle, The value of the ADC is 4095 (12 bit resolution). 



With something in front of it, the second LED glows and the value in the debugger decreases. 



 NOTE:- As the pollforconversion function is in the while loop, this procedure will continue forever and microcontroller can not perform any other function. To avoid this, we will use interrupt in the upcoming tutorial.

To Download full code, visit HERE

Blink LED with PIC16f microcontroller

PIC16 is a microcontroller series from Microchip. It is not difficult for a beginner to learn but powerful enough to be used in high level ...

Popular