STM32ADC experimental explanation, from entry to abandonment.


foreword

This article refers to blog posts on the Internet, and summarizes them to help newbies from getting started to giving up .


Reminder: The following is the main text of this article

1. ADC


What is ADC?

ADC : Abbreviation for Analog-to-Digital Converter. Refers to an analog/digital converter or analog/digital converter . Refers to a device that converts an analog signal of a continuous variable into a discrete digital signal. A typical analog-to-digital converter converts an analog signal into a digital signal representing a proportional voltage value.

The 12-bit ADC is a successive approximation analog-to-digital converter . It has up to 19 multiplexed channels and can measure signals from 16 external sources, two internal sources and the V BAT channel. A/D conversion for these channels can be performed in single, continuous, sweep, or discontinuous sampling modes. The result of the ADC is stored in a left- or right-justified 16-bit data register. The ADC has an analog watchdog feature that allows the application to detect if the input voltage exceeds a user-defined upper or lower threshold.

The STM32f103 series has 3 ADCs with 12-bit accuracy and each ADC has up to 16 external channels. Among them, ADC1 and ADC2 have 16 external channels, ADC3 generally has 8 external channels, the A/D conversion of each channel can be performed in a single, continuous, scan or intermittent manner, and the results of ADC conversion can be left-aligned or right-aligned and stored in 16 bit data register. The input clock of the ADC must not exceed 14MHz , and its clock frequency is generated by dividing the frequency of PCLK2 .

What are the main features of ADC?

①12-bit successive approximation type analog-to-digital converter; ②Up to
3 ADC controllers, which can be used alone, or can use dual mode to increase the sampling rate;
③Support up to 23 channels, can measure up to 21 external and 2 internal Signal source;
④Support single-shot and continuous conversion mode;
⑤Conversion end, injection conversion end, and interrupt when analog watchdog event occurs;
⑥Auto scan mode from channel 0 to channel n;
⑦Auto-calibration;
⑧The sampling interval can be Program by channel;
⑨Regular channel and injection channel have external trigger options; ⑩Conversion
result supports left-aligned or right-aligned storage in 16-bit data register;
⑪ADC conversion time: maximum conversion rate 1us (maximum conversion speed is 1MHz, in ADCCLK =14M, the sampling period is 1.5 ADC clock);
⑫ ADC power supply requirements: 2.4V-3.6V;

ADC input range: VREF- ≤ VIN ≤ VREF+.
insert image description here

Function description of ADC

1. Voltage input
Let's take a look at the following picture:
insert image description here
The voltage range that the ADC can measure is VREF- ≤ VIN ≤ VREF+ , connect VSSA and VREF- to ground, and connect VREF+ and VDDA to 3V3, the ADC's input voltage range is: 0~3.3V.
2. Input channel
The part taken from the above:
insert image description hereThe signal input of ADC is realized through the channel, and the signal is input into the single-chip microcomputer through the channel. After the single-chip microcomputer is converted, the analog signal is output as a digital signal .

The corresponding relationship between ADC channels and pins of STM32F103ZET6:
insert image description here
It can be seen that STM32F103ZET6 has 3 ADC controllers, supporting a total of 23 channels, including 21 external and 2 internal signal sources; but each ADC controller can only have at most 18 channels including 16 external and 2 internal sources.

Regarding channels, we are divided into regular channels and injection channels during conversion .
insert image description here
Regular channel: The usual ADC conversions are implemented with regular channels, and a maximum of 16 channels can be arranged. If there is out-of-column processing, the conversion of the injection channel can be enabled.

Injection channel: The injection channel can forcibly insert the conversion when the regular channel is converted, which is equivalent to an "interruption channel".

An inappropriate analogy is that the conversion of the regular channel group is like the normal execution of the program, and the conversion of the injection channel group is like an interrupt handler outside the normal execution of the program.

About channel selection
There are 16 multiplexed channels. Transformations can be divided into two groups: rule transformations and injection transformations. Each group contains a conversion sequence that can be done on any channel in any order. For example, the sequence can be converted in the following order: ADC_IN3, ADC_IN8, ADC_IN2, ADC_IN2, ADC_IN0, ADC_IN2, ADC_IN2, ADC_IN15.

A rule transformation group consists of up to 16 transformations. The regular channels of the conversion sequence and their order must be selected in the ADC_SQRx registers. The total number of conversions in the regular conversion group must be written to the L[3:0] bits in the ADC_SQR1 register.

An injection transformation group consists of up to 4 transformations. The injection channels of the conversion sequence and their order must be selected in the ADC_JSQR register. The total number of conversions injected into the conversion group must be written to the L[1:0] bits in the ADC_JSQR register

If the ADC_SQRx or ADC_JSQR registers are modified during conversion, the current conversion is reset and a new start pulse is sent to the ADC to convert the newly selected bank.

Temperature Sensor, V REFINT and V BAT Internal Channels

For STM32F40x and STM32F41x devices, the temperature sensor is internally connected to channel ADC1_IN16. The internal reference voltage VREFINT is connected to
ADC1_IN17. For STM23F42x and STM32F43x devices, the temperature sensor is internally connected to
channel ADC1_IN18 shared with VBAT. Only one conversion (temperature sensor or VBAT) can be selected at a time. When both temperature sensor and VBAT conversion are set, only VBAT conversion will be performed.

The internal reference voltage VREFINT is connected to ADC1_IN17.
The V BAT channel is connected to channel ADC1_IN18. The channel can also be converted to an injection channel or a regular channel.
Note: The temperature sensor, V REFINT and V BAT channels are only available on the main ADC1 peripheral.

Conversion Mode
The conversion order in regular channels is controlled by three registers: SQR1, SQR2, SQR3
insert image description here
Injection channel conversion order

There is only one JSQR register to control. insert image description here
Only when JL=4, the conversion order of the injection channel will be executed in the order of JSQ1, JSQ2, JSQ3, JSQ4. When JL<4, the conversion order of the injection channel is just the opposite, that is, the execution order is: JSQ4, JSQ3, JSQ2, JSQ1.

ADC single conversion mode

In the single conversion mode, the ADC only performs one conversion. This mode can be started by the ADON bit of the ADC_CR2 register (applicable to regular channels only), or it can be started by external triggers (applicable to regular channels and injection channels). At this time, CONT bit is 0.

1. Set the SWSTART bit in the ADC_CR2 register to 1 (for regular channels only)
2. Set the JSWSTART bit to 1 (for injection channels)
3. External trigger (for regular channels or injection channels)

Once the conversion of the selected channel is complete
If the regular channel is converted :

— The conversion data is stored in the 16-bit ADC_DR register
— The EOC (End of Conversion) flag is set
— An interrupt is generated when the EOCIE bit is set

If the injected channel is converted :

— The conversion data is stored in the 16-bit ADC_JDR1 register
— The JEOC (End of Injection Conversion) flag is set
— An interrupt is generated when the JEOCIE bit is set

Then, the ADC stops.

ADC continuous conversion mode
In continuous conversion mode, the ADC starts a new conversion immediately after finishing a conversion. When the CONT bit is 1, this mode can be started by an external trigger or by setting the SWSTART bit in the ADC_CR2 register to 1 (only applicable to rules channel)
after each conversion:
● If a regular group of channels is converted:
— The last converted data is stored in the 16-bit ADC_DR register
— The EOC (End of Conversion) flag is set
— An interrupt is generated when the EOCIE bit is set
No continuous conversions can be injected into the channel . The only exception to continuous mode is when the injection channel is configured to automatically transition after the regular channel (using the JAUTO bit)

ADC scan mode (for scanning a group of analog channels)

Scan mode is selected by setting the SCAN bit in the ADC_CR1 register. When this bit is set, the ADC scans all channels selected in the ADC_SQRx registers (for regular channels) or ADC_JSQR registers (for injected channels). One conversion is performed for each channel in the group. After each conversion, the next channel in the group is automatically converted. If the CONT bit is set, regular channel conversion does not stop at the last selected channel in the group, but resumes conversion from the first selected channel again.

If the DMA bit is set, the data converted from the regular channel group (stored in the ADC_DR register) is transferred to SRAM using the Direct Memory Access (DMA) controller after each regular channel conversion.

The EOC bit in the ADC_SR register is set:
● at the end of each regular group sequence conversion if the EOCS bit is clear ● if the EOCS bit is set, the data converted from the injected channel at the
end of each regular channel conversion is always
Stored in the ADC_JDRx registers.

Interrupts for ADCs
When the analog watchdog status bit and the overflow status bit are set to 1, respectively, the rule group and the injection group may generate an interrupt at the end of the conversion. A separate interrupt enable bit can be used for flexibility.
There are two other flags in the ADC_SR register, but these two flags have no interrupt correlation:
● JSTRT (start converting the channel of the injection group)
● STRT (start converting the channel of the rule group)
insert image description here

insert image description here
ADC conversion time

Conversion time = sampling time + 12.5 cycles

12.5 cycles are fixed, generally we set PCLK2=72M, the maximum clock that can be divided by the ADC prescaler can only be 12M, the sampling period is set to 1.5 cycles, and the shortest conversion time is calculated to be 1.17us.

Each signal conversion of the ADC takes time, and this time is the conversion time. The conversion time is determined by the input clock and sampling period. ADC is mounted on the APB2 bus in STM32

The ADC clock is obtained by dividing the frequency of PCLK2 (72MHz). The frequency dividing factor is set by bits 15:14ADCPRE[1:0] of the RCC clock configuration register RCC_CFGR, which can be divided by 2/4/6/8 . General configuration The frequency division factor is 6, that is, the input clock frequency of the ADC obtained by dividing by 6 is 12MHz. (Generally no more than 14MHz)

The sampling period is established on the input clock. Configuring the sampling period can determine how many ADC clock cycles are used to sample the voltage. The number of cycles can be set by the SMP[2:0] bits in the ADC sampling time registers ADC_SMPR1 and ADC_SMPR2. ADC_SMPR2 controls channels 0~9, and ADC_SMPR1 controls channels 10~17. Each channel can be configured with different sampling periods, but the minimum sampling period is 1.5 periods, that is to say, if you want to sample at the fastest time, set the sampling period to 1.5.

Data Alignment of ADC
The ALIGN bit in the ADC_CR2 register is used to select the alignment of the data stored after conversion. There are two options for left alignment and right alignment.

It should be noted that the precision of ADC conversion is 12 bits, and there are 16 bits in the register to store data, so it is necessary to specify whether the data storage is left-aligned or right-aligned.

insert image description here
Timing diagram of ADC

insert image description here

2. Experimental steps

Code part explanation


The steps required are:

1. Turn on the PA port clock and ADC1 clock, and set PA1 as an analog input.
2. Reset ADC1 and set the ADC1 divide factor at the same time.
3. Initialize ADC1 parameters, set the working mode of ADC1 and related information of regular sequence.
4. Enable the ADC and calibrate.
5. Read the ADC value.

1. Turn on the PA port clock and ADC1 clock, and set PA1 as an analog input.

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); 
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.1

2. Reset ADC1 and set the ADC1 divide factor at the same time.

RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置 ADC1 分频因子为6
ADC_DeInit(ADC1);//复位 ADC1

3. Initialize ADC1 parameters and set the working mode of ADC1

void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)/*下面是结构体里的内容
typedef struct
{
uint32_t ADC_Mode;
FunctionalState ADC_ScanConvMode;
FunctionalState ADC_ContinuousConvMode;
uint32_t ADC_ExternalTrigConv;
uint32_t ADC_DataAlign;
uint8_t ADC_NbrOfChannel;
}ADC_InitTypeDef;
*/
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC 工作模式:独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //AD 单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //AD 单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
//转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC 数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的 ADC 通道的数目 1
ADC_Init(ADC1, &ADC_InitStructure); //根据指定的参数初始化外设 ADCx

4. Enable ADC and calibrate

ADC_Cmd(ADC1, ENABLE); //使能指定的 ADC1
ADC_ResetCalibration(ADC1);//复位校准
ADC_StartCalibration(ADC1); //开始指定 ADC1 的校准状态
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
while(ADC_GetCalibrationStatus(ADC1)); //等待校 AD 准结束

5. Read the ADC value.

void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel,
uint8_t Rank, uint8_t ADC_SampleTime)ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能指定的 ADC1 的软件转换启动功能
ADC_GetConversionValue(ADC1);//获取转换 ADC 转换结果数据
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG)//获取 AD 转换的状态信息的函数
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束


The reference voltage of the ADC needs to be explained here. The battleship STM32 development board uses STM32F103ZET6. The chip has external reference voltages: Vref- and Vref+, of which Vref- must be connected with VSSA, and the input range of Vref+ is: 2.4~ VDDA. The battleship STM23 development board uses the P7 port to set Vref- and Vref+ to set the reference voltage. By default, we connect Vref- to GND and Vref+ to VDDA through the jumper cap, and the reference voltage is 3.3V. If you want to set other reference voltages by yourself, just connect your reference voltages to Vref- and Vref+. In this chapter, our reference voltage is set to 3.3V.

code example

adc.c:

//初始化 ADC
//这里我们仅以规则通道为例
//我们默认将开启通道 0~3
void Adc_Init(void)
{
    
     
	ADC_InitTypeDef ADC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能 ADC1 通道时钟
	RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置 ADC 分频因子 6
	//72M/6=12,ADC 最大时间不能超过 14M
	//PA1 作为模拟通道输入引脚
	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
	GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.1
	ADC_DeInit(ADC1); //复位 ADC1,将外设 ADC1 的全部寄存器重设为缺省值
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC 独立模式
	ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单通道模式
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//转换由
	//软件而不是外部触发启动
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC 数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的 ADC 通道的数目
	ADC_Init(ADC1, &ADC_InitStructure); //根据指定的参数初始化外设 ADCx
	ADC_Cmd(ADC1, ENABLE); //使能指定的 ADC1
	ADC_ResetCalibration(ADC1); //开启复位校准
	while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
	ADC_StartCalibration(ADC1); //开启 AD 校准
	while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
}

//获得 ADC 值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)
{
    
    
	//设置指定 ADC 的规则组通道,设置它们的转化顺序和采样时间
	ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );
	//通道 1,规则采样顺序值为 1,采样时间为 239.5 周期
	ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能软件转换功能
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
	return ADC_GetConversionValue(ADC1); //返回最近一次 ADC1 规则组的转换结果
}

u16 Get_Adc_Average(u8 ch,u8 times)
{
    
    
	u32 temp_val=0;
	u8 t;
	for(t=0;t<times;t++)
	{
    
     
		temp_val+=Get_Adc(ch);
		delay_ms(5);
	}
	return temp_val/times;
}

main.c:

int main(void)
{
    
    
	u16 adcx;
	float temp;
	delay_init(); //延时函数初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置 NVIC 中断分组 2
	uart_init(115200); //串口初始化波特率为 115200
	LED_Init(); //LED 端口初始化
	LCD_Init(); //LCD 初始化
	Adc_Init(); //ADC 初始化
	POINT_COLOR=RED; //设置字体为红色
	LCD_ShowString(60,50,200,16,16,"WarShip STM32");
	LCD_ShowString(60,70,200,16,16,"ADC TEST");
	LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
	LCD_ShowString(30,110,200,16,16,"2015/1/14");
	//显示提示信息
	POINT_COLOR=BLUE; //设置字体为蓝色
	LCD_ShowString(60,130,200,16,16,"ADC_CH0_VAL:");
	LCD_ShowString(60,150,200,16,16,"ADC_CH0_VOL:0.000V");
	while(1)
	{
    
    
		adcx=Get_Adc_Average(ADC_Channel_1,10);
		LCD_ShowxNum(156,130,adcx,4,16,0);//显示 ADC 的值
		temp=(float)adcx*(3.3/4096);
		adcx=temp;
		LCD_ShowxNum(156,150,adcx,1,16,0);//显示电压值
		temp-=adcx;
		temp*=1000;
		LCD_ShowxNum(172,150,temp,3,16,0X80);
		LED0=!LED0;
		delay_ms(250);
	}
}

Summarize

That's all for today's article. If you think it's okay to write, please like and follow. If you still don't understand, click the link, the video link of Xiaopo Station goes directly

Guess you like

Origin blog.csdn.net/qq_42866708/article/details/113448658