One common feature that is used in almost every embedded application is the ADC module (Analog to Digital Converter). These Analog to digital Converters can read voltage from analog sensors like Temperature sensor, Tilt sensor, Current sensor, Flex sensor and much more. So in this tutorial we will learn how to use ADC in STM32F103C8 to read Analog voltages using the Energia IDE. We will interface a small potentiometer to STM32 Blue Pill board and supply a varying voltage to an Analog pin, read the voltage and display it on the 16x2 LCD screen.

Comparing ADC in Arduino and STM32F103C8

In Arduino board, it contains a 6 channel (8 channels on the Mini and Nano, 16 on the Mega), 10-bit ADC with an input voltage range of 0V–5V. This means that it will map input voltages between 0 and 5 volts into integer values between 0 and 1023. Now in the case of STM32F103C8 we have 10 channels, 12-Bit ADC with an input range 0V -3.3V. It will map input voltages between 0 and 3.3 volts into integer values between 0 and 4095.

ADC in STM32

The ADC embedded in STM32 microcontrollers uses the SAR (successive approximation register) principle, by which the conversion is performed in several steps. The number of conversion steps is equal to the number of bits in the ADC converter. Each step is driven by the ADC clock. Each ADC clock produces one bit from result to output. The ADC internal design is based on the switched-capacitor technique. If you are new to STM32, then checkout our Getting started with STM32 tutorial.

12-bit Resolution

This ADC is a 10 channel 12 -bit ADC. Here the term 10 channel implies that there are 10 ADC pins using which we can measure analog voltage. The term 12-bit implies the resolution of the ADC. 12-bit means 2 to the power of ten (212) which is 4096. This is the number of sample steps for our ADC, so the range of our ADC values will be from 0 to 4095. The value will increase from 0 to 4095 based on the value of voltage per step, which can be calculated by formula

How an Analog Signal is converted into Digital Format

As computers store and process only binary/digital values (1’s and 0’s). So Analog signals like sensor’s output in volts has to be converted into digital values for processing and the conversion needs to be accurate .When a input analog voltage is given to STM32 at its Analog inputs, the analog value is read and stored in a integer variable. That stored Analog value(0-3.3V ) is converted into integers values (0-4096) using the formula below:

Components Required

Circuit Diagram and Explanations

The circuit diagram to interface 16*2 LCD and Analog Input to a STM32F103C8T6board is shown below.

The connections which are done for LCD are given below:

LCD Pin No

LCD Pin Name

STM32 Pin Name

1

Ground (Gnd)

Ground (G)

2

VCC

5V

3

VEE

Pin from Centre of Potentiometer

4

Register Select (RS)

PB11

5

Read/Write (RW)

Ground (G)

6

Enable (EN)

PB10

7

Data Bit 0 (DB0)

No Connection (NC)

8

Data Bit 1 (DB1)

No Connection (NC)

9

Data Bit 2 (DB2)

No Connection (NC)

10

Data Bit 3 (DB3)

No Connection (NC)

11

Data Bit 4 (DB4)

PB0

12

Data Bit 5 (DB5)

PB1

13

Data Bit 6 (DB6)

PC13

14

Data Bit 7 (DB7)

PC14

15

LED Positive

5V

16

LED Negative

Ground (G)

The connections are made according to the above given table. There are two Potentiometers present in the circuit, first one is used for voltage divider which can be used to vary voltage and provide analog input to STM32. Left pin of this potentiometer gets input positive voltage from STM32 (3.3V) and right pin is connected to ground, centre pin of potentiometer is connected to analog input pin (PA7) of STM32. The other potentiometer is used to vary the contrast of the LCD display. The power source for STM32 is provided by means of USB power supply from a PC or Laptop.

Next, we include the header file for the LCD display. This calls the library which contains the code for how the STM32 should communicate with the LCD. Also make sure the function Liquid Crystal is called with the pin names that we just defined above.

Finally, inside our infinite loop() function, we start reading the analog voltage supplied to the PA7 pin from potentiometer. As we discussed already, the microcontroller is a digital device and it cannot read voltages level directly. Using SAR technique the voltage level is mapped from 0 to 4096. These values are called the ADC values, to get this ADC value simply use the following line

int val = analogRead(A7); // read the ADC value from pin PA7

Here the function analogRead() is used to read the analog value of the pin. Finally we save this value in a variable called “val”. The type of this variable is integer because we will only get values ranging from 0 to 4096 to be stored in this variable.

The next step would be to calculate the voltage value from the ADC value. To do this we have the following formulae

Voltage = (ADC Value / ADC Resolution) * Reference Voltage

In our case we already know that the ADC resolution of our microcontroller is 4096. The ADC value is also found in the previous line and stored the variable called val. The reference voltage is equal to the voltage at which the microcontroller is operating. When the STM32 board is powered via USB cable then the operating voltage is 3.3V. You can also measure the operating voltage by using a multimeter across the Vcc and ground pin on the board. So the above formula fits into our case as shown below

You might be confused with the line float (val). This is used to convert the variable “val” from int data type to “float” data type. This conversion is needed because only if we get the result of val/4096 in float we can multiply it 3.3. If the value is received in integer it will always be 0 and the result will also be zero. Once we have calculated the ADC value and voltage, all that is left is to display the result on the LCD screen which can be done by using the following lines