Library 06- AD Converter on STM32F4
In this tutorial I will talk about ADC (Analog to Digital Converter). AD 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
- Vbat
- Voltage on battery pin for RTC
- Temp sensor
- unusable for measure temp,only for measure difference in temperature because it can fail up to 45°C
- Vref
- Voltage reference for ADC
- Vbat
Below is table with and channels connected to physical pins.
Library
Features
- Measure analog value with pooling mode
- Use all possible ADC’s with all possible pins
- Measure Vbat pin for RTC battery
Dependencies
- CMSIS
- STM32F4xx
- STM32F4xx RCC
- STM32F4xx GPIO
- STM32F4xx ADC
- TM
- TM GPIO
- defines.h
- TM GPIO
Channel | ADC1 | ADC2 | ADC3 |
---|---|---|---|
APB | 2 | 2 | 2 |
ADC Channel 0 | PA0 | PA0 | PA0 |
ADC Channel 1 | PA1 | PA1 | PA1 |
ADC Channel 2 | PA2 | PA2 | PA2 |
ADC Channel 3 | PA3 | PA3 | PA3 |
ADC Channel 4 | PA4 | PA4 | PF6 |
ADC Channel 5 | PA5 | PA5 | PF7 |
ADC Channel 6 | PA6 | PA6 | PF8 |
ADC Channel 7 | PA7 | PA7 | PF9 |
ADC Channel 8 | PB0 | PB0 | PF10 |
ADC Channel 9 | PB1 | PB1 | PF3 |
ADC Channel 10 | PC0 | PC0 | PC0 |
ADC Channel 11 | PC1 | PC1 | PC1 |
ADC Channel 12 | PC2 | PC2 | PC2 |
ADC Channel 13 | PC3 | PC3 | PC3 |
ADC Channel 14 | PC4 | PC4 | PF4 |
ADC Channel 15 | PC5 | PC5 | PF5 |
My library ADCx:
- Resolution 12bits
- Prescaler set to 4: APB2 clock / 4
- Single mode,
- Independent mode,
- 8 clock cycles between 2 reads
Functions and enumerations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
/** * @defgroup TM_ADC_Typedefs * @brief Library Typedefs * @{ */ /** * @brief ADC available channels */ typedef enum { TM_ADC_Channel_0, /*!< Operate with ADC channel 0 */ TM_ADC_Channel_1, /*!< Operate with ADC channel 1 */ TM_ADC_Channel_2, /*!< Operate with ADC channel 2 */ TM_ADC_Channel_3, /*!< Operate with ADC channel 3 */ TM_ADC_Channel_4, /*!< Operate with ADC channel 4 */ TM_ADC_Channel_5, /*!< Operate with ADC channel 5 */ TM_ADC_Channel_6, /*!< Operate with ADC channel 6 */ TM_ADC_Channel_7, /*!< Operate with ADC channel 7 */ TM_ADC_Channel_8, /*!< Operate with ADC channel 8 */ TM_ADC_Channel_9, /*!< Operate with ADC channel 9 */ TM_ADC_Channel_10, /*!< Operate with ADC channel 10 */ TM_ADC_Channel_11, /*!< Operate with ADC channel 11 */ TM_ADC_Channel_12, /*!< Operate with ADC channel 12 */ TM_ADC_Channel_13, /*!< Operate with ADC channel 13 */ TM_ADC_Channel_14, /*!< Operate with ADC channel 14 */ TM_ADC_Channel_15, /*!< Operate with ADC channel 15 */ TM_ADC_Channel_16, /*!< Operate with ADC channel 16 */ TM_ADC_Channel_17, /*!< Operate with ADC channel 17 */ TM_ADC_Channel_18 /*!< Operate with ADC channel 18 */ } TM_ADC_Channel_t; /** * @} */ /** * @defgroup TM_ADC_Functions * @brief Library Functions * @{ */ /** * @brief Initializes ADCx peripheral * @param *ADCx: ADCx peripheral to initialize * @retval None */ void TM_ADC_InitADC(ADC_TypeDef* ADCx); /** * @brief Initializes ADCx with ADCx channel * @param *ADCx: ADCx peripheral to operate with * @param channel: channel for ADCx * @retval None */ void TM_ADC_Init(ADC_TypeDef* ADCx, uint8_t channel); /** * @brief Reads from ADCx channel * @param *ADCx: ADCx peripheral to operate with * @param channel: channel for ADCx to read from * @retval ADC value */ uint16_t TM_ADC_Read(ADC_TypeDef* ADCx, uint8_t channel); /** * @brief Enables Vbat channel for ADC * @param None * @retval None */ void TM_ADC_EnableVbat(void); /** * @brief Disables Vbat channel for ADC * @param None * @retval None */ void TM_ADC_DisableVbat(void); /** * @brief Reads vbat pin voltage * @param *ADCx: ADCx peripheral to use for Vbat measurement * @retval voltage in mV */ uint16_t TM_ADC_ReadVbat(ADC_TypeDef* ADCx); /** * @} */ |
Example 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
/** * Keil project for ADC peripheral * * Before you start, select your target, on the right of the "Load" button * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 */ /* Include core modules */ #include "stm32f4xx.h" /* Include my libraries here */ #include "defines.h" #include "tm_stm32f4_delay.h" #include "tm_stm32f4_usart.h" #include "tm_stm32f4_adc.h" #include <stdio.h> int main(void) { char str[15]; /* Initialize system */ SystemInit(); /* Initialize Delay library */ TM_DELAY_Init(); /* Initialize USART1, 115200baud, TX: PB6 */ TM_USART_Init(USART1, TM_USART_PinsPack_2, 115200); /* Initialize ADC1 on channel 0, this is pin PA0 */ TM_ADC_Init(ADC1, ADC_Channel_0); /* Initialize ADC1 on channel 3, this is pin PA3 */ TM_ADC_Init(ADC1, ADC_Channel_3); while (1) { /* Read ADC1 Channel0 Read ADC1 Channel3 */ sprintf(str, "%4d: %4d\n\r", TM_ADC_Read(ADC1, ADC_Channel_0), TM_ADC_Read(ADC1, ADC_Channel_3)); /* Put to USART */ TM_USART_Puts(USART1, str); /* Little delay */ Delayms(100); } } |
Example 2
- Measure voltage on Vbat pin
- Result is in mV
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
/** * Keil project for ADC peripheral how to measure Vbat pin * * Before you start, select your target, on the right of the "Load" button * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 */ /* Include core modules */ #include "stm32f4xx.h" /* Include my libraries here */ #include "defines.h" #include "tm_stm32f4_delay.h" #include "tm_stm32f4_adc.h" #include "tm_stm32f4_usart.h" #include <stdio.h> int main(void) { char str[150]; /* Initialize system */ SystemInit(); /* Initialize Delay library */ TM_DELAY_Init(); /* Initialize USART1, 115200 baud, TX: PB6 */ TM_USART_Init(USART1, TM_USART_PinsPack_2, 115200); /* Initialize ADC1 */ TM_ADC_InitADC(ADC1); /* Enable vbat channel */ TM_ADC_EnableVbat(); while (1) { /* Read & format data */ sprintf(str, "----------------------------\nVbat voltage: %d mV\n", TM_ADC_ReadVbat(ADC1)); /* Put to USART */ TM_USART_Puts(USART1, str); /* Little delay */ Delayms(1000); } } |
Projects are available on Github, download library below.
ADC library to read analog voltage
Recent comments