STM32F429 Discovery ADC (Analog to Digital Convertor)

NAME SURNAME:
NUMBER:
CEN 425 Embedded Systems
STM32F429 Discovery ADC (Analog to Digital Convertor)
In many embedded projects, we have to deal with signals directly from nature, like temperature,
pressure, current. Theses signals are analog by default and in most of cases we use sensors that
converts these analog signals to analog electrical voltage to be injected in the microcontroller to do
some work. Unfortunately, microcontrollers are digital and just can't deal with analog signals so these
signals must be converted again to digital signals that is comprehensible by the microcontroller.
For this purpose, microcontroller's manufacturers usually incorporate an ADC into the microcontroller.
ADC is actually stands for Analog to Digital Converter. This module is omnipresent in most of
microcontrollers.
ADC converts analog voltage to digital number, that can be used in microcontrollers. STM32F4xx
MCUs have up to 3 ADCs of which every has 19 channels.

16 external channels, connected to IO pins

3 internal channels
The 12-bit ADC is a successive approximation analog-to-digital converter. It has up to 19 multiplexed
channels allowing it to measure signals from 16 external sources, two internal sources, and the VBAT
channel. The A/D conversion of the channels can be performed in single, continuous, scan or
discontinuous mode. The result of the ADC is stored into a left or right-aligned 16-bit data register.
The analog watchdog feature allows the application to detect if the input voltage goes beyond the
user-defined, higher or lower thresholds.
ADC main features
• 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’.
• Discontinuous mode.
• Dual/Triple mode (on devices with 2 ADCs or more).
• Configurable DMA data storage in Dual/Triple ADC mode.
• Configurable delay between conversions in Dual/Triple interleaved mode
• ADC conversion type (refer to the datasheets)
• 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: VREF– ≤ VIN ≤ VREF+.
• DMA request generation during regular channel conversion.
Now that we have the ADC configured, we need to read the temperature. For now we will just use the debugger
to read the value of the sensor. But first we need to read the data then convert it to a temperature. To find the
formula for the conversion of the data, we can look at the reference manual for the STM32F4. The formula is
Temperature (in °C) = {(VSENSE – V25) / Avg_Slope} + 25
Where: V25 = VSENSE value for 25° C
Avg_Slope = average slope of the temperature vs. VSENSE curve (given in mV/°C or μV/°C)
Looking at the data sheet for the specific STM32F407VG processor the following values are found
V25 = 0.76V = 760 mV.
Avg_Slope = 2.5 mV/°C
Read the conversion value Value and converted into voltage Vsense, Vsense = Value × 3300/4095 (mV).
Temp = [( Vsense– 760) / 2500] + 25);
ADC_InitTypeDef Struct Reference
Data Fields







FunctionalState
uint32_t
uint32_t
uint32_t
uint8_t
uint32_t
FunctionalState
ADC_ContinuousConvMode
ADC_DataAlign
ADC_ExternalTrigConv
ADC_ExternalTrigConvEdge
ADC_NbrOfConversion
ADC_Resolution
ADC_ScanConvMode
FunctionalState ADC_InitTypeDef::ADC_ContinuousConvMode
Specifies whether the conversion is performed in Continuous or Single mode. This parameter can be set to
ENABLE or DISABLE.
uint32_t ADC_InitTypeDef::ADC_DataAlign
Specifies whether the ADC data alignment is left or right. This parameter can be a value of ADC_data_align.
uint32_t ADC_InitTypeDef::ADC_ExternalTrigConv
Select the external event used to trigger the start of conversion of a regular group. This parameter can be a
value of ADC_extrenal_trigger_sources_for_regular_channels_conversion.
uint32_t ADC_InitTypeDef::ADC_ExternalTrigConvEdge
Select the external trigger edge and enable the trigger of a regular group. This parameter can be a value of
ADC_external_trigger_edge_for_regular_channels_conversion.
uint8_t ADC_InitTypeDef::ADC_NbrOfConversion
Specifies the number of ADC conversions that will be done using the sequencer for regular channel group. This
parameter must range from 1 to 16.
uint32_t ADC_InitTypeDef::ADC_Resolution
Configures the ADC resolution dual mode. This parameter can be a value of ADC_resolution.
2
FunctionalState ADC_InitTypeDef::ADC_ScanConvMode
Specifies whether the conversion is performed in Scan (multichannels) or Single (one channel) mode. This
parameter can be set to ENABLE or DISABLE.
void ADC_Init (ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)
Initializes the ADCx peripheral according to the specified parameters in the ADC_InitStruct.
Note: This function is used to configure the global features of the ADC ( Resolution and Data Alignment),
however, the rest of the configuration parameters are specific to the regular channels group (scan mode
activation, continuous mode activation, External trigger source and edge, number of conversion in the regular
channels group sequencer).
Parameters:
ADCx: Where x can be 1, 2 or 3 to select the ADC peripheral.
ADC_InitStruct: Pointer to an ADC_InitTypeDef structure that contains the configuration information for the
specified ADC peripheral.
Return values: None.
void ADC_Cmd (ADC_TypeDef* ADCx,FunctionalState NewState)
Enables or disables the specified ADC peripheral.
Parameters:
ADCx: Where x can be 1, 2 or 3 to select the ADC peripheral.
NewState: New state of the ADCx peripheral. This parameter can be: ENABLE or DISABLE.
Return values: None.
void ADC_TempSensorVrefintCmd (FunctionalState NewState)
Enables or disables the temperature sensor and Vrefint channels.
Parameters:
NewState: New state of the temperature sensor and Vrefint channels. This parameter can be: ENABLE or
DISABLE.
Return values: None.
void ADC_RegularChannelConfig (ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank,
uint8_t ADC_SampleTime)
Configures for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
Parameters:
ADCx: Where x can be 1, 2 or 3 to select the ADC peripheral.
ADC_Channel: The ADC channel to configure. This parameter can be one of the following values:
ADC_Channel_0: ADC Channel0 selected
ADC_Channel_1: ADC Channel1 selected
ADC_Channel_2: ADC Channel2 selected
ADC_Channel_3: ADC Channel3 selected
ADC_Channel_4: ADC Channel4 selected
ADC_Channel_5: ADC Channel5 selected
ADC_Channel_6: ADC Channel6 selected
ADC_Channel_7: ADC Channel7 selected
ADC_Channel_8: ADC Channel8 selected
ADC_Channel_9: ADC Channel9 selected
ADC_Channel_10: ADC Channel10 selected
ADC_Channel_11: ADC Channel11 selected
ADC_Channel_12: ADC Channel12 selected
ADC_Channel_13: ADC Channel13 selected
ADC_Channel_14: ADC Channel14 selected
ADC_Channel_15: ADC Channel15 selected
ADC_Channel_16: ADC Channel16 selected
ADC_Channel_17: ADC Channel17 selected
ADC_Channel_18: ADC Channel18 selected
Rank: The rank in the regular group sequencer. This parameter must be between 1 to 16.
ADC_SampleTime: The sample time value to be set for the selected channel. This parameter can be one of the
following values:








ADC_SampleTime_3Cycles: Sample time equal to 3 cycles
ADC_SampleTime_15Cycles: Sample time equal to 15 cycles
ADC_SampleTime_28Cycles: Sample time equal to 28 cycles
ADC_SampleTime_56Cycles: Sample time equal to 56 cycles
ADC_SampleTime_84Cycles: Sample time equal to 84 cycles
ADC_SampleTime_112Cycles: Sample time equal to 112 cycles
ADC_SampleTime_144Cycles: Sample time equal to 144 cycles
ADC_SampleTime_480Cycles: Sample time equal to 480 cycles
Return values: None.
3
void ADC_SoftwareStartConv (ADC_TypeDef*
ADCx)
Enables the selected ADC software start conversion of the regular channels.
Parameters:
ADCx: Where x can be 1, 2 or 3 to select the ADC peripheral.
Return values: None.
FlagStatus ADC_GetFlagStatus (ADC_TypeDef* ADCx, uint8_t ADC_FLAG)
Checks whether the specified ADC flag is set or not.
Parameters:
ADCx: Where x can be 1, 2 or 3 to select the ADC peripheral.
ADC_FLAG: Specifies the flag to check. This parameter can be one of the following values:





ADC_FLAG_AWD: Analog watchdog flag
ADC_FLAG_EOC: End of conversion flag
ADC_FLAG_JEOC: End of injected group conversion flag
ADC_FLAG_JSTRT: Start of injected group conversion flag
ADC_FLAG_STRT: Start of regular group conversion flag
ADC_FLAG_OVR: Overrun flag

Return values: The new state of ADC_FLAG (SET or RESET).
uint16_t ADC_GetConversionValue (ADC_TypeDef* ADCx)
Returns the last ADCx conversion result data for regular channel.
Parameters:
ADCx: Where x can be 1, 2 or 3 to select the ADC peripheral.
Return values: The Data conversion value.
4
Laboratory Task:

Write the required C program code given as below

Connect 5 LEDs to the pins 11-12-13-14-15 of the port F of the STM32F429ZI Disco Board. Don’t forget the
GND connection and resistors.

Add the “Temperature” and “ADC1” variables to the watch window to observe the result.

Examine the operation of your experimental setup.

Note some values of “Temperature” (or ADC_TypeDef*) from watch window.

After that change ADC_InitDef.ADC_DataAlign = ADC_DataAlign_Left; and observe and note
the changes.

Than, change ADC_InitDef.ADC_DataAlign = ADC_DataAlign_Left; and observe and note the
changes.

After recovering the change, observe the current “Temperature” value and using the given formulations
calculate the measured temperature value. Write down your own observations.
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_tim.h"
#include "stm32f4xx_adc.h"
GPIO_InitTypeDef
GPIO_InitDef;
//Structure for analog pin
ADC_InitTypeDef
ADC_InitDef;
//Structure for ADC confguration
void GPIO_Config() {
//Clock configuration
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
GPIO_InitDef.GPIO_Pin = GPIO_Pin_11
| GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
GPIO_Pin_15;
GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOF, &GPIO_InitDef);
}
void ADC_Config() {
//Clock configuration
//The ADC1 is connected the APB2 peripheral bus
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
//ADC structure configuration
ADC_DeInit();
ADC_InitDef.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitDef.ADC_Resolution = ADC_Resolution_12b;
ADC_InitDef.ADC_ContinuousConvMode = ENABLE;
ADC_InitDef.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitDef.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitDef.ADC_NbrOfConversion = 1;
5
ADC_InitDef.ADC_ScanConvMode = DISABLE;
ADC_Init(ADC1, &ADC_InitDef); //Initialize ADC with the previous configuration
//Enable ADC conversion
ADC_Cmd(ADC1, ENABLE);
//Select the channel to be read from
ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 1, ADC_SampleTime_28Cycles);
}
void Delay(uint32_t nCount) {
while(nCount--) {
}
}
uint16_t readADC1(uint8_t channel) {
ADC_SoftwareStartConv(ADC1);
//Start the conversion
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); //Processing the conversion
return ADC_GetConversionValue(ADC1);
//Return the converted data
}
int main() {
GPIO_Config();
ADC_Config();
ADC_TempSensorVrefintCmd(ENABLE);
do {
unsigned int Temperature = readADC1(17);
if (
Temperature>500 ) {
GPIO_SetBits(GPIOF, GPIO_Pin_11);
}
if ( Temperature>750 ) {
GPIO_SetBits(GPIOF, GPIO_Pin_12);
}
if ( Temperature>1000
) {
GPIO_SetBits(GPIOF, GPIO_Pin_13);
}
if ( Temperature>1250) {
GPIO_SetBits(GPIOF, GPIO_Pin_14);
}
if ( Temperature>1500) {
GPIO_SetBits(GPIOF, GPIO_Pin_15);
}
Delay(1000000);
} while (1);
}
6