STM32 ADC details

Time:2021-11-23

01. Introduction to ADC

ADC is the abbreviation of analog to digital converter. Refers to an analog-to-digital converter or an analog-to-digital converter. It refers to the device that converts the analog signal of continuous variable into discrete digital signal. A typical analog-to-digital converter converts an analog signal into a digital signal representing a certain proportional voltage value.

As can be seen from the following figure in the stm32f207 data book, stm32f207vc has three ADC controllers with an accuracy of 12bit and 16 external channels, while stm32f207zx with 144 pins and stm32f207ix with 176 pins have 8 channels and 24 external channels because they have pf pins. The A / D conversion of each channel can be performed single time, continuously, scanning or intermittently, and the ADC conversion results can be left aligned or right aligned and stored in the 16 bit data register.

02. ADC peripherals of stm32

As mentioned above, stm32f207 has three 12 bit ADC controllers, which will be explained below with channel 10 of adc3.

First, we confirm the address bus where the ADC peripherals are located. According to the following figure in the stm32f207 data manual, the ADC belongs to apb2 bus, and the apb2 clock frequency is 60MHz. For the specific STM32, please see the 60MHz apb2 obtained through the external 25m crystal oscillator《Analysis of stm32f207 clock system》。

Corresponding to GPIO, we can see from stm32f207 data manual that we can use PC0 as channel 10 of adc3.

It should be noted that when other peripherals are used in previous articles, such as《Stm32pwm output》In, when looking for the corresponding pin, we all look for it from the alternatefunctionmapping table in the stm32f207 data manual, because the pin corresponding to ADC uses additive functions and the pin corresponding to PWM uses alternatefunctions.

The difference is:

Additional functions: additional and auxiliary functions. The pins are connected to other modules for use. When using, they can be directly configured as normal. For example, the input channel of ADC is configured as analog input.

Alternate functions: multiplexing function, that is, the IO port is used as a function other than ordinary input and output, such as serial input and output. The multiplexing mode needs to be configured when using.

In previous articles《Stm32gpio details》It is described as follows.

STM32 standard peripheral library has the following codes

typedef enum
{   
    GPIO_Mode_IN   = 0x00, /*!< GPIO Input Mode */  
    GPIO_Mode_OUT  = 0x01, /*!< GPIO Output Mode */  
    GPIO_Mode_AF   = 0x02, /*!< GPIO Alternate function Mode */  
    GPIO_Mode_AN   = 0x03  /*!< GPIO Analog Mode */
}GPIOMode_TypeDef;

Where GPIO_ Mode_ AF corresponds to alternate functions: multiplexing functions, GPIO_ Mode_ An corresponds to additional functions: additional and auxiliary functions.

03. Explanation of stm32adc block diagram

The following figure is the structural block diagram of stm32adc, which is divided into 7 parts for explanation.

1. Input voltage range

The voltage range that ADC can measure is VREF – ≤ VIN ≤ VREF +, vssa   And VREF – ground, connect VREF + and vdda   Connect 3v3 to obtain the input voltage range of ADC: 0 ~ 3.3V.

2. Input channel

The signal of ADC enters the MCU through the input channel, and the MCU converts the analog signal into digital signal through the ADC module. The part marked ② in the above figure shows the 16 external channels and connected gpios. The corresponding relationship is as explained above. You need to find it in the stm32f20xpin and ball definitions table in the stm32f207 data manual. In fact, STM32 also has an internal channel, the channel of ADC1   16 is connected to the temperature sensor inside the chip, vreint   Connected to channel 17. Analog channel of ADC2   16 and   17 connected to the internal VSS.

3. Conversion channel

The 16 external channels are divided into regular channels and injection channels during conversion. There are at most 16 regular channels and 4 injection channels (injection channels seem to be used less). The following two channels are briefly introduced:

Regular channel

As the name suggests, the regular channel is the most common channel and the most commonly used channel. The usual ADC conversion is implemented with the regular channel. Regular channel and its conversion order in ADC_ Select in the sqrx register, and the total number of rule group conversions should be written to the ADC_ In L [3:0] of sqr1 register.

Injection channel

The injection channel is relative to the regular channel. When the regular channel is converted, the injection channel can forcibly insert the conversion, which is equivalent to an “interrupt channel”. When there is an injection channel to be converted, the conversion of the regular channel will stop, and the conversion of the injection channel will be performed first. After the conversion of the injection channel is completed, return to the previous regular channel for conversion. Up to 4 channels, injection group and its conversion sequence in ADC_ Select from the jsqr register. The total number of conversions in the injection group shall be written to the ADC_ In L [1:0] of jsqr register.

An ADC controller has multiple channels, which involves the use of multiple channels for conversion, which involves a sequential problem. After all, the regular conversion channel has only one data register. The use order of multiple channels can be divided into two cases: the conversion order of regular channels and the conversion order of injection channels.

Regular channel conversion order

The conversion order in the regular channel is controlled by three registers: sqr1, sqr2 and sqr3, which are 32-bit registers. The SQR register controls the number of conversion channels and conversion order. As long as the corresponding channel is written in the corresponding register bit sqx, this channel is the x-th conversion. The implementation of the conversion order on the register can be understood through the sqr1 register.

Injection channel conversion sequence

Like the control of regular channel conversion sequence, the conversion of injection channel is also controlled by injection register, but only one jsqr register. The control relationship is as follows:

It should be noted that only when JL = 4, the conversion sequence of injection channels will be executed in the order of jsq1, jsq2, jsq3 and jsq4. When JL < 4, the conversion order of the injection channel is exactly the opposite, that is, the execution order is jsq4, jsq3, jsq2 and jsq1.

Functions that configure the conversion order

void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel,uint8_t Rank, uint8_t ADC_SampleTime)

04. Trigger source

The input, channel and conversion sequence of ADC conversion have been explained, but how is ADC conversion triggered? Just like the communication protocol, a start signal must be specified to transmit information, and ADC also needs a trigger signal to implement analog-to-digital conversion.

One is triggered by directly configuring the register. By configuring the Adon bit of the control register CR2, the conversion starts when writing 1 and stops when writing 0. In the process of program running, as long as the library function is called, the Adon position 1 of CR2 register can be converted, which is easy to understand.

In addition, the conversion can also be triggered by an internal timer or external IO, that is, the ADC can be periodically converted by using the internal clock, or the ADC can be converted when needed by using the external io. The specific trigger is determined by the control register CR2.

05. Conversion cycle

The sampling time of each channel can be set independently

ADC will sample the input voltage in several adcclk cycles. ADC can be used_ Smpr1 and ADC_ SMPR2

The SMP [2:0] bit in the register modifies the number of cycles. Each channel can be sampled at different sampling times.

The total conversion time is calculated as follows:

Tconv = sampling time + 12 cycles

Example:

When adcclk = 30 MHz and sampling time = 3 cycles:

Tconv = 3 + 12 = 15 cycles = 0.5us (when apb2 is 60MHz)

The minimum sampling time is 0.42us (ADC clock = 36MHz and the sampling period is 3 cycles).

06. Data register

The data after conversion is stored in the data register, but the storage of data is also divided into regular channel conversion data and injection channel conversion data.

Rule data register

The regular data register is responsible for storing the data converted by the regular channel through the 32-bit register ADC_ Dr to store.

Injection data register

There are 4 data registers converted by the injection channel. Since there are at most 4 injection channels, the data converted by the injection channel has a fixed storage location, which will not cause the problem of data coverage like the regular register.   ADC_ Jdrx yes   32-bit, low   16 bit valid, high   16 bit reserved. The data is also divided into left alignment and right alignment. The specific storage method is determined by the ADC_ CR2   eleven   Bit align   set up.

07. Interruption

Four types of interrupts can be generated

① DMA overflow interrupt

When DMA is configured and DMA overflows, an interrupt is generated

② Rule channel conversion complete interrupt

After the rule channel data conversion is completed, an interrupt can be generated, and the value of the rule data register can be read in the interrupt function. This is also a way to read data in a single channel.

③ Injection channel conversion completion interrupt

After the data conversion of the injection channel is completed, an interrupt can be generated, and the value of the injection data register can also be read in the interrupt to read the data.

④ Simulated watchdog event

When the input analog quantity (voltage) is no longer within the threshold range, a watchdog event will be generated, which is used to monitor whether the input analog quantity is normal.

08. Voltage conversion

The converted data is a 12 bit binary number. We need to digitally represent the analog quantity (voltage) represented by this binary number. For example, the measured voltage range is 0 ~ 3.3V, and the converted binary number is X. because the 12 bit ADC divides the voltage range (i.e. 3.3) into 4096 (2 ^ 12) parts during conversion, the calculation method of the real voltage represented by the converted binary number x is as follows:

y=3.3* x / 4096

09. Circuit diagram design

The circuit diagram is very simple. You can input different voltages on the ADC pin, or you can directly and conveniently use the sliding rheostat to realize different voltage changes.

10. Code design

Structure of ADC peripheral configuration

typedef struct
{
  uint32_t ADC_Resolution;                /*!< Configures the ADC resolution dual mode. 
                                               This parameter can be a value of @ref ADC_resolution */                                   
  FunctionalState 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 */ 
  FunctionalState 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_ExternalTrigConvEdge;      /*!< Select the external trigger edge and
                                               enable the trigger of a regular group. 
                                               This parameter can be a value of 
                                               @ref ADC_external_trigger_edge_for_regular_channels_conversion */
  uint32_t ADC_ExternalTrigConv;          /*!< Select the external event used to trigger 
                                               the start of conversion of a regular group.
                                               This parameter can be a value of 
                                               @ref ADC_extrenal_trigger_sources_for_regular_channels_conversion */
  uint32_t ADC_DataAlign;                 /*!< Specifies whether the ADC data  alignment
                                               is left or right. This parameter can be 
                                               a value of @ref ADC_data_align */
  uint8_t  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. */
}ADC_InitTypeDef;

ADC_ Resolution: ADC working mode selection, ADC resolution

ADC_ Scanconvmode: ADC scan (multichannel) or single pass (single channel) mode selection

ADC_ Continuous continuous mode: ADC single conversion or continuous conversion selection

ADC_ Externaltrigconvedge: ADC external trigger polarity configuration

ADC_ Externaltrigconv: ADC conversion trigger signal selection

ADC_ Dataalign: ADC data register alignment format

ADC_ Nbrofconversion: number of ADC conversion channels

typedef struct

ADC_ Commoninittypedef is used to configure ADC_ Related parameters of CCR register

ADC peripheral and DMA configuration code

/**
  * @brief  ADC3 channel10 with DMA configuration
  * @param  None
  * @retval None
  */
void ADC3_CH10_DMA_Config(void)
{
  ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;
  GPIO_InitTypeDef      GPIO_InitStructure;
 
  /* Enable ADC3, DMA2 and GPIO clocks ****************************************/
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
 
  /* DMA2 Stream0 channel2 configuration **************************************/
  DMA_InitStructure.DMA_Channel = DMA_Channel_2;  
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  DMA_Cmd(DMA2_Stream0, ENABLE);
 
  /* Configure ADC3 Channel10 pin as analog input ******************************/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
 
  /* ADC Common Init **********************************************************/
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);
 
  /* ADC3 Init ****************************************************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_Init(ADC3, &ADC_InitStructure);
 
  /* ADC3 regular channel7 configuration *************************************/
  ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
 
 /* Enable DMA request after last transfer (Single-ADC mode) */
  ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);
 
  /* Enable ADC3 DMA */
  ADC_DMACmd(ADC3, ENABLE);
 
  /* Enable ADC3 */
  ADC_Cmd(ADC3, ENABLE);
}

Code download verification test

Hardware and software open source address:

https://github.com/strongercjd/STM32F207VCT6

Click to view the album where this article is located,Stm32f207 tutorial

Recommended Today

Seven solutions for distributed transactions

1、 What is distributed transaction Distributed transaction means that transaction participants, transaction supporting servers, resource servers and transaction managers are located on different nodes of different distributed systems. A large operation is completed by more than n small operations. These small operations are distributed on different services. For these operations, either all of them are […]