ADC analog-to-digital conversion (1) - independent mode single-channel voltage acquisition experiment

 

Figure 21-1 (cut from the stm32f103 reference manual)

Figure 21-1 is the functional block diagram of the ADC, which will be analyzed below.

Voltage input range

Figure 21-2 (cut from the stm32f103 reference manual)

ADC is generally used to collect small voltage, and its input value cannot exceed V_ {DDA}, namely: V_{REF-} \the Wine \the V_{REFf+}. The relevant definitions are shown in Figure 21-2. Generally, connect V_ {SSA}and V_{REF-}ground, V_ {DDA}and V_{REF+}connect to 3V3, then the input range of ADC is 0~3.3V.

If you want to collect an analog voltage that exceeds the threshold, you can improve the circuit so that the voltage input to the ADC is within the valid range.

input channel

The voltage enters the ADC through the input channel. The ADC of stm32 has a total of 18 channels, of which 16 are external channels, ADCx_IN0~ADCx_IN15. There are also two internal passages. The related pin definitions and descriptions can be found in the data sheet of the development board.

The 16 external channels are divided into regular channels (up to 16 channels) and injection channels (up to 4 channels). In general, we use the regular channel, and the injection channel needs to be forcibly inserted during the regular channel conversion process. Once inserted, you must wait for the injection channel conversion to complete before continuing the regular channel conversion. Similar to interrupt servicing.

Conversion order

The three regular sequence registers ADC_SQR1, ADC_SQR2, and ADC_SQR3 respectively define the 13th~16th, 7th~12th, and 1st~6th conversions. Which channel wants which conversion can assign the corresponding channel to the corresponding conversion bit. For example, if channel 0 wants the ninth conversion, write 0 in SQ9[4:0]. The specific conversion number is determined by L[3:0] of ADC_SQR1, up to 16 conversions.

The injection sequence register has only one ADC_JSQR, which supports up to 4 channels. The specific conversion number is determined by the JL[1:0] bits. It should be noted that if the value of the JL bit is less than 4 (excluding 4), the conversion order is just the opposite, that is, the first conversion is JSQx[4:0] (x=4-JL), not JSQ1[4 :0].

trigger source

In addition to controlling the start and stop of conversions with the ADON bit of the ADC_CR2 register, trigger conversions can also be supported. Including internal timer trigger and external IO trigger. The specific trigger source is controlled by the EXTSEL[2:0] bits (regular channel trigger source) and JEXTSEL[2:0] (injection channel trigger source) of ADC_CR2.

Conversion time

The input clock ADCCLK of the ADC is generated by frequency division of PCLK2, and the frequency division factor is configured by ADCPRE[1:0] of RCC_CFGR, which can be divided by 2/4/6/8. The maximum ADCCLK after frequency division should not exceed 14MHz.

When sampling the input voltage, the SMP[2:0] bits of the ADC_SMPR1 (channel 0~9) and ADC_SMPR2 (channel 10~17) registers can be configured to control the sampling period. Each channel can be configured with different sampling periods, and the minimum period is 1.5. Then, the conversion time of the ADC is (there is a formula in the reference manual):

T = sample time + 12.5 cycles, where 1 cycle is 1/ADCCLK

For example, ADCCLK is divided into 12MHz (PCLK2 is 72MHz, divided by 6), and the sampling time is 1.5 cycles, then T=14 cycles=1.17us.

ADC_DR and ADC_JDRx

ADC_DR and ADC_JDRx are the rule data register and the injection data register, respectively. There is only one ADC_DR, which has 32 bits. The lower 16 bits are used when a single ADC is used, and the upper 16 bits are used in ADC1 to save the regular data converted by ADC2 in dual mode (dual mode means that ADC1 and ADC2 are used at the same time).

There are up to 16 regular channels, and only one ADC_DR. In the case of multi-channel conversion, the data converted at the previous time point needs to be quickly moved out, otherwise it will be overwritten by the data converted at the next time point. The DMA mode is used here to transfer data to memory. Figure 21-3 is the register description of ADC_DR.

Figure 21-3

There are only 4 injection channels at most, just ADC_JDRx also has 4, and each channel has a corresponding register, which will not cause data coverage problems. Figure 21-4 shows the register description of ADC_JDRx.

Figure 21-4

Since the ADC precision is 12 bits, it cannot be fully filled regardless of the lower 16 bits or the upper 16 bits. At this time, the left-alignment or right-alignment of the conversion result is configured by the ALIGN bit of ADC_CR2.

interrupt

There are three types: regular channel conversion end interrupt, injection channel conversion end interrupt and analog watchdog interrupt. The first two types of end-of-conversion interrupts are generally judged and executed according to the interrupt flag bit and the enable bit. The analog watchdog interrupt is described here.

When the analog watchdog interrupt is enabled, an interrupt is generated when the analog voltage value converted by the ADC is below the low threshold or above the high threshold. The high and low values ​​of the threshold are configured by ADC_LTR and ADC_HTR.

DMA request

After the conversion of rules and injection channels, a DMA request is generated to transfer the converted data to memory. It should be noted that only ADC1 and ADC3 can generate DMA requests. (For DMA requests, you can move to stm32: DMA data transfer )

voltage conversion

After the analog voltage is converted, it is a 12-bit digital value. Frankly speaking, this value cannot be understood by humans, so it needs to be converted into a voltage value with better readability, that is, the voltage value measured with a multimeter.

In general, the input voltage range of the ADC is 0~3.3v, so the voltage value corresponding to the 12-bit full scale is 3.3v, and the digital value is 2^12. We assume that the 12-bit value converted by the ADC is x, and its corresponding voltage value is y, then,

2^{12} / 3.3 = x / y ,Right now y = (3.3*x) / 2^{12}

The obtained y value is the voltage value we need, which is the value measured with a multimeter.

 

ADC_InitTypeDef

At this point, the basic part of ADC is probably clear, and the description of the program can be started. Let's talk about the ADC_InitTypeDef structure first.

Figure 21-5

The screenshot of the structure in Figure 21-5 is taken from the stm32f10x_adc.h file, and the structure members are analyzed one by one below.

  • ADC_Mode: ADC mode, use one ADC for independent mode, use two ADCs for dual mode, etc. Configured by the DUALMOD[3:0] bits of the ADC_CR1 register;
  • ADC_ScanConvMode: Configure whether to enable scanning. If it is a single-channel AD conversion, it is DISABLE, and if it is a multi-channel AD conversion, it is ENABLE. Specifically configured by the SCAN bit of the ADC_CR1 register;
  • ADC_ContinuousConvMode: Configure whether to automatically convert continuously. ENABLE is to enable automatic continuous conversion, and DISABLE is for single conversion (manual control is required to restart the conversion after one conversion). Specifically configured by the CONT bit of the ADC_CR2 register;
  • ADC_ExternalTrigConv: External trigger conversion, Figure 21-1 lists many external trigger conditions, and the trigger source can be configured according to project requirements. However, we generally use software triggers;
  • ADC_DataAlign: conversion result data alignment mode, ADC_DataAlign_Right and ADC_DataAlign_Left are optional, we generally choose right alignment mode;
  • ADC_NbrOfChannel: The number of AD conversion channels, which can be configured according to the actual project.

Standalone Mode Single-Channel Acquisition Experiment

This experiment is used to collect the voltage of the potentiometer (sliding rheostat), and print the collected voltage value to the serial debugging assistant through the serial port. Here, AD conversion is used to complete the interrupt, the data is read in the interrupt service function, and DMA transmission is not used, and DMA transmission is used only when multi-channel acquisition is performed.

GPIO configuration of ADC

Enables the GPIO clock of the ADC peripheral and configures the ADC's pins in analog input mode.

Consult the pin definition description of the data sheet (Table 5. High-density STM32F103xx pin definitions), we can select the PC1 pin, which supports ADC1/2/3_IN11, which will be used by the ADC configuration program later, as shown in Figure 21- 6. For the configuration of the peripheral pin mode, please refer to the 8.1.11 GPIO configuration chapter of the peripheral in the reference manual, as shown in Figure 21-7.

Figure 21-6

Figure 21-7

ADC configuration

In fact, it is to configure the members of the ADC_InitTypeDef structure and configure them as required by the project. Posting the code directly is more intuitive.

/**
  * @brief  配置ADC工作模式
  * @param  无
  * @retval 无
 */ static void ADC_Mode_Config(void) { ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // 独立模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 这是单通道实验,不使用扫描 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 连续转换 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 不使用外部触发,使用软件触发 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 转化结果右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; // 通道数量,这是单通道,所以为1 ADC_Init(ADC1, &ADC_InitStructure); RCC_ADCCLKConfig(RCC_PCLK2_Div8); // 配置ADC时钟为8分频,即9MHz // 转换通道、转换顺序、采样时间(这里是55.5个周期) ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5); ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); // 转换结束中断 ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); // 初始化ADC校准寄存器 while(ADC_GetResetCalibrationStatus(ADC1)); // 等待校准寄存器初始化完成 ADC_StartCalibration(ADC1); // ADC开始校准 while(ADC_GetCalibrationStatus(ADC1)); // 等待校准完成 ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 软件触发ADC转换 } 

The relevant analysis is in the program comments, which is easy to read. Only one key point is mentioned here. The ADC_RegularChannelConfig() function is used to configure the conversion sequence and sampling time of the ADC. Regarding the period selection of the sampling time, the longer the period, the higher the sampling accuracy, and vice versa.

interrupt configuration

The configuration of interrupts is also introduced in the previous article , which can be read step by step. The configuration code is directly posted here.

/**
  * @brief  ADC中断配置
  * @param  无
  * @retval 无
 */ static void ADC_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn; // ADC中断源 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 子优先级为1 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } 

interrupt service function

The interrupt function is generally defined in the stm32f10x_it.c file. After entering the interrupt service function, the ADC conversion result is directly read in the function and saved in the ADC_ConvertedValue variable, which is defined in the main.c file.

extern __IO uint16_t ADC_ConvertedValue; // 该变量在main.c文件定义,所以需添加extern关键字 void ADC_IRQHandler(void) { if (ADC_GetITStatus(ADC1, ADC_IT_EOC) == SET) { ADC_ConvertedValue = ADC_GetConversionValue(ADC1); // 读取ADC的转换值 } ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); } 

The ADC_GetConversionValue() library function directly reads the value of the ADC_DR register.

Finally, execute the voltage conversion formula in the main() function to get the voltage value we need.

ADC_ConvertedValueLocal = (float)ADC_ConvertedValue / 4096 * 3.3; 

Then ADC_ConvertedValueLocal is the value we need, which can be compared with the value measured by the multimeter.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326641150&siteId=291194637