STM32F107VC Microcontroller Interfacing (ADC)

Learn it by examples – (ADC)

By David Kebo Houngninou

On this page, you will find some interfacing experiments using the ARM Cortex M3.
– The evaluation board we target is the MCBSTM32C running on the STM32F107VC microcontroller.
– The tutorial focuses on configuring the MCBSTM32C and interfacing.
– Datasheets and documentation for STMicroelectronics STM32F107VC core is available at: http://www.keil.com/dd/chip/4889.htm.
– The reference used for this tutorial is the RM0008 Reference manual for STM32F107xx advanced ARMĀ®-based 32-bit MCUs.

Tutorial 2: Setup and initialize the ADC

The Analog to Digital Converter (ADC) converts an analog input to a digital input for use by the microprocessor and the Digital to Analog (DAC) takes the microprocessor’s digital output and converts it to an analog signal.

ADC to STM32F107VC to DAC

We already enabled the APB2 clock in part 1 now let’s enable the clock for the ADC.

RCC->APB2ENR |=  1 <<  9;             /* Enable ADC1 clock                  */

APB2 peripheral clock enable register (RCC_APB2ENR)

GPIOC->CRL   &= 0xFFF0FFFF;           /* Configure PC4 as ADC.14 input      */

The potentiometer on the MCBSTM32C board connects to port pin PC4 (ADC12_IN14).
To use the potentiometer, pins must be configured as an analog input. By reading again Table 3 on the port bit configuration, you see that CNF4 and MODE4 must all be set to 0.
The line of code above is the same as:

GPIOC->CRL   = GPIOC->CRL & 0xFFF0FFFF;

So to configure PC4 we use the following mask:

1111 1111 1111 0000 1111 1111 1111 1111

The bitwise AND of the GPIOC->CRL register content with the mask above will clear bits CNF4 and MODE4.

The potentiometer

ADC Sequence registers

The STM32F107 has 18 analog input channels. Sequence registers configure the number of channels to sample.

ADC Sequence registers

Bits 23:20 L[3:0]: Regular channel sequence length. Number of conversions in the regular channel conversion sequence.
0000: 1 conversion, 0001: 2 conversions, … 1111: 16 conversions
Bits 19:15 SQ16[4:0]: 16th conversion in regular sequence. The channel number is assigned as the 16th in the conversion sequence.
Bits 14:10 SQ15[4:0]: 15th conversion in regular sequence

ADC sample time registers ADC_SMPR

The potentiometer is wired to channel 14
For a single conversion:

1
2
3
ADC1->SQR1 = 0x00000000; // Regular channel single conversion
ADC1->SQR2 = 0x00000000; // Clear register
ADC1->SQR3 = (14<<0);  // channel 14 as 1st conversion

ADC sample time registers ADC_SMPR

Bits 23:0 SMPx[2:0]: Channel x Sample time selection
Select the sample time individually for each channel.

000: 1.5 cycles 001: 7.5 cycles 010: 13.5 cycles 011: 28.5 cycles
100: 41.5 cycles 101: 55.5 cycles 110: 71.5 cycles 111: 239.5 cycles

Table 3: ADC sample time configuration

Example

The ADC should delay reading for 5.15 uS
For an ADCCLK running at 14 MHz
Determine the sample time (Setting for SMPx)?

Answer: 5.15uS = 72 cycles at 14 MHz.

ADC Control Registers (ADC_CR)

The ADC is controlled using two control registers ADC_CR1 and ADC_CR2
Bit 8 SCAN (Scan mode): In this mode, the inputs selected through ADC_SQRx registers are converted.
Bit 5 EOCIE (Interrupt enable for EOC): enable/disable the End of Conversion interrupt.
reference: ADC block diagram (page 216) RM0008 Reference manual

ADC Control Registers (ADC_CR)

To interrupt the microcontroller at the end of conversion:

1
2
ADC1->CR1 |= (1<<5);	// EOC interrupt
NIVC->ISER[0] |= (1<<18);	//Interrupt number 18

ADC Control Registers configuration

1
2
3
4
5
ADC1->CR2 |= (7<<17); // Set SWSTART as trigger
ADC1->CR2 |= (1<<20); // Enable external trigger
ADC1->CR2 &= ~(1<<11); // Right data alignment
ADC1->CR2 |= (1<<1); // Continuous conversion
ADC1->CR2 |= (1<<0); // Turn ADC ON

To perform all the operations above in one statement, we can use a bitwise-OR operation

Enable external trigger, EXTSEL = SWSTART, Continuous conversion, ADC enable

1
ADC1->CR2 = (1 << 20) | (7 << 17) | (1 << 1) | (1 << 0) ;

ADC calibration and conversion

1
2
3
4
5
6
7
8
9
//Calibration
ADC1->CR2 |= (1<<3); // reset calibration
while (ADC1->CR2 & (1<<3)); // wait until reset finished

ADC1->CR2 |= (1<<2); // start calibration
while (ADC1->CR2 & (1<<2)); // wait until calibration finished

//Conversion
ADC1->CR2 |= (1<<22);  // start SW conversion

ADC Status and Data Registers (ADC_SR)

Bit 4 STRT: Regular channel Start flag
Bit 3 JSTRT: Injected channel Start flag
Bit 2 JEOC: Injected channel end of conversion
Bit 1 EOC: End of conversion
Bit 0 AWD: Analog watchdog flag

ADC Status and Data Registers (ADC_SR)

Bits 31:16, ADC2DATA[15:0]: Contains the regular data of ADC2.
Bits 15:0, DATA[15:0]: Contain the conversion result from the regular channels.

1
2
3
4
if (ADC1->SR & (1 << 1)) { // If conversion has finished (Check EOC bit) 
AD_val = ADC1->DR & 0x0FFF; // Read AD converted value
ADC1->CR2 |= 1 << 22; // Start new conversion
}

Tutorial 3: Blinking the LEDs

This tutorial will explain how to blink the LEDs after they have been configured

Tutorial 3 >>

Other project files

The following source files are required for the project.

  • STM32F10x.c contains the CPU startup code for the STMicroelectronics STM32F10x devices.
  • IRQ.c contains the target-dependent interrupt functions for the Timer and A/D converter.
  • Retarget.c configures the target-dependent low-level functions for character I/O.
  • Setup.c and Blinky.c contain the application modules that monitor analog input, provide the text output, and toggle the LEDs.
  • STM32F10xR.LIB, contains the ST Software Library functions.
  • LCD_4bit.c, contains the functions to produce text for the LCD display.
  • Serial.c, contains the functions to communicate to the serial port.
Scroll to Top