STM32 ADC—模数转换器

目录

一、ADC功能框图

1.电压输入范围

2.输入通道

3.转换顺序

4.触发源

5.转换时间

6.数据寄存器

二、ADC初始化结构体介绍

三、ADC常用固件库函数

四、实验设计

1.独立模式-单通道-中断读取

2.独立模式-(单)多通道-必须采用DMA读取

3.双重模式-多通道-规则同步


简介:STM32单片机中含有

1-三个独立的ADC 1 / 2 / 3

2-分辨率为12位

3-每个ADC具有18个通道,其中外部通道16个,可测量16个外部和2个内部信号源。

例如:温度传感器/VREFINT内部通道:温度传感器和通道ADC1_IN16相连接,内部参照电压VREFINT和ADC1_IN17相连接。可以按注入或规则通道对这两个内部通道进行转换。

一、ADC功能框图

STM32 ADC—模数转换器_第1张图片

1.电压输入范围

输入电压:VREF- ≤ VIN ≤ VREF+

决定输入电压的引脚:VREF-、VREF+、VDDA、VSSA

参考负电压VREF接到VSSA,VSSA接地;参考正电压VREF+接到VDDA,VDDA接3V3,得到ADC 的输入电压范围为: 0~3.3V

STM32 ADC—模数转换器_第2张图片

由于MINI板子的芯片用的是64脚的,所以就没有VREF-、VREF+两个引脚,输入电压范围只由VDDA、VSSA确定。只有100脚以上的芯片才有这两个引脚。

2.输入通道

STM32 ADC—模数转换器_第3张图片

由于板上引脚资源紧张,我们只留下通道11:PC1作为单独的ADC通道,不与其他任何外设相关。

在使用ADC转换时,VARPC1排针要短接,我们可以把蜂鸣器与A15的排针拔掉去用。

外部的16个通道在转换的时候又分为规则通道注入通道,其中规则通道最多有16路,注入通道最多有4路。

通道的分类

规则通道:很规矩的意思,我们平时一般使用的就是这个通道。

注入通道:注入,可以理解为插入,插队的意思。它是一种在规则通道转换的时候强行插入要转换的一种。这点跟中断程序很像,规则通道正在执行过程中注入通道插入执行。所以,注入通道只有在规则通道存在时才会出现。

3.转换顺序

1-规则序列寄存器

STM32 ADC—模数转换器_第4张图片

如果我们需要转换3个通道,SQR1寄存器的低4位取值就是3,要设置第3个通道为第一个转换的通道,SQR3寄存器的SQ1位取值就是3,设置第2个通道为第三个转换的通道,SQR3寄存器的SQ3位取值就是2。

2-注入序列寄存器

STM32 ADC—模数转换器_第5张图片

我们设置1、5、6、7作为注入通道,通道7个作为第一个转换,JSQR寄存器的JSQ1位就该置7;通道1作为最后一个转换,JSQR寄存器的JSQ4位就该置1.以上这是4个注入通道的时候,如果注入通道小于4个,就需要按图片上面的配置。

4.触发源

1、软件触发:ADC_CR2控制寄存器2 :ADON/SWST(规则通道)
ART/JSWSTART(注入通道)

2、外部事件触发:内部定时器/外部IO

选择:ADC_CR2 :EXTSEL[2:0]和 JEXTSEL[2:0]

激活:ADC_CR2 :EXTEN 和 JEXTEN

5.转换时间

转换时间:Tconv = 采样时间 + 12.5 个固定的周期

周期指的就是ADC_CLKADC模拟电路时钟,最大值为14M,由PCLK2 (PCLK2=72M)提供,还可分频:2/4/6/8,分频因子由RCC_CFGR控制器的ADCPRE[1:0]设置。通常我们使用6分频=12M.

STM32 ADC—模数转换器_第6张图片

采样时间由ADC 采样时间寄存器 ADC_SMPR1和ADC_SMPR2控制,通道0-9是寄存器2,通道10-17由寄存器1控制。

数字时钟:RCC_APB2ENR,用于访问寄存器

6.数据寄存器

一切准备就绪后, ADC 转换后的数据根据转换组的不同,规则组的数据放在ADC_DR 寄存器,注入组的数据放在JDRx

STM32 ADC—模数转换器_第7张图片

ADC1和ADC2的数据共用这一个寄存器

1-16位有效,用于存放独立模式转换完成数据
2- ADC_CR2 :ALIGN位控制左对齐还是右对齐,一般采取右对齐

3-该寄存器只有一个,多通道采集的是最好使用DMA,数据一旦产生就接着搬运走。

STM32 ADC—模数转换器_第8张图片

1-16位有效,用于存放注入通道转换完成数据
2- ADC_CR2 :ALIGN

3-有4个这样的寄存器

二、ADC初始化结构体介绍

STM32 ADC—模数转换器_第9张图片

1-ADC_MODE:模式选择,ADC_CR1寄存器的DUALMOD位

STM32 ADC—模数转换器_第10张图片

独立模式使用最多:单独的使用ADC1/2/3。

规则同步模式:规则通道,两个ADC同时使用,一主一从,两个ADC同时采集转换数据。采集到的数据存放在ADC规则数据寄存器内(ADC_DR)

交替触发模式:两个ADC,一个采集数据的时候另一个进行数据转换,提高工作项效率。

2-ADC_ScanConvMode:扫描模式,ADC_CR1寄存器的SCAN位

0:关闭扫描模式;1:使用扫描模式。用于多通道采集(采集多个信号源)的情况下。

3-ADC_ContinuousConvMode:连续转换模式,ADC_CR2寄存器的CON位

0:单次转换模式;1:连续转换模式。单次转换:采集一个点就结束,连续转换:不断对外部信号源进行采集并且转换为数字信号量。

4-ADC_ExternalTrigConv:外部触发转换选择,ADC_CR2寄存器的EXTTRIG和EXTSEL[2:0]位

确定好要转换多少个通道,一切就绪之后,我们就要给ADC一个信号,让它开始转换。这个信号可以用软件触发,也可以由外部触发。

外部触发:下图中的11和15引脚,也就是板子上的所有11和15引脚发生的电平变化就可以产生一个事件,这个事件可以触发ADC进行转换。

   我们通常采用软件触发。

STM32 ADC—模数转换器_第11张图片

5-ADC_DataAlign:数据对齐格式,ADC_CR2寄存器的ALIGN位。我们通常使用右对齐。

6-ADC_NbrOfChannel:转换的通道数,配置规则序列寄存器和注入序列寄存器。

规则序列寄存器(ADC_SQR1)

STM32 ADC—模数转换器_第12张图片

注入序列寄存器(ADC_JSQR)

STM32 ADC—模数转换器_第13张图片

三、ADC常用固件库函数

ADC_Init();   初始化结构体成员

RCC_ADCCLKConfig();   ADC时钟配置 配置采样时钟的分频因子

ADC_RegularChannelConfig();规则通道配置 配置采样时间,转换顺序

ADC_Cmd(); 

ADC_SoftwareStartConvCmd();   软件触发

ADC_ExternalTrigConvCmd();    外部触发

ADC_DMACmd();   DMA相关

四、实验设计

1.独立模式-单通道-中断读取

首先是初始化及配置端口引脚。一个是配置ADC用到的GPIO,然后配置、初始化ADC结构体,最后配置NVIC,处理中断。

static void ADCx_GPIO_Config(void)//配置 ADC 用到的 GPIO
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	// 打开 ADC IO端口时钟
	ADC_GPIO_APBxClock_FUN ( ADC_GPIO_CLK, ENABLE );
	
	// 配置 ADC IO 引脚模式
	// 必须为模拟输入
	GPIO_InitStructure.GPIO_Pin = ADC_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	//只有在 GPIO口 用作输出的时候才需要配置速度,输入不需要
	
	// 初始化 ADC IO
	GPIO_Init(ADC_PORT, &GPIO_InitStructure);		
}

static void ADC_Mode_Config(void)//配置、初始化 ADC 结构体
{
	ADC_InitTypeDef ADC_InitStructure;	

	// 打开ADC时钟
	ADC_APBxClock_FUN ( ADC_CLK, ENABLE );
	
	// ADC 模式配置
	// 只使用一个ADC,属于独立模式
	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;
	
	// 转换通道1个
	ADC_InitStructure.ADC_NbrOfChannel = 1;	
		
	// 初始化ADC
	ADC_Init(ADCx, &ADC_InitStructure);
	
/*配置采样周期*/	
	// 配置ADC时钟为PCLK2的8分频,即9MHz
	RCC_ADCCLKConfig(RCC_PCLK2_Div8); 
	
	// 配置 ADC 通道转换顺序和采样时间
	ADC_RegularChannelConfig(ADCx,ADC_CHANNEL,1,ADC_SampleTime_55Cycles5);

/*数据转换结束产生中断*/	
	// ADC 转换结束产生中断,在中断服务程序中读取转换值
	ADC_ITConfig(ADCx, ADC_IT_EOC, ENABLE);
	
	// 开启ADC ,并开始转换
	ADC_Cmd(ADCx, ENABLE);
	
	// 初始化ADC 校准寄存器  
	ADC_ResetCalibration(ADCx);
	// 等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADCx));
	
	// ADC开始校准
	ADC_StartCalibration(ADCx);
	// 等待校准完成
	while(ADC_GetCalibrationStatus(ADCx));
	
	// 由于没有采用外部触发,所以使用软件触发ADC转换 
	ADC_SoftwareStartConvCmd(ADCx, ENABLE);	
}

static void ADCx_NVIC_Config(void)//配置 NVIC,处理中断
{
  NVIC_InitTypeDef NVIC_InitStructure;
	// 优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // 配置中断优先级
  NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQ;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);	
}

然后再写中断程序,检测到产生中断之后,读取ADC的转换值。

void ADC_IRQHandler(void)
{	
	if (ADC_GetITStatus(ADCx,ADC_IT_EOC)==SET)//检测是否产生了中断 
	{
		// 读取ADC的转换值
		ADC_ConvertedValue = ADC_GetConversionValue(ADCx);
	}
	ADC_ClearITPendingBit(ADCx,ADC_IT_EOC);
}

主函数里面,对转换出来的模拟量进行转换,转换成外部采集到的模拟量。

电压的模拟范围是0-3.3V,数字量的模拟范围:2的12次方 = 4096。3.3 / 4096 = 模拟量对应数字量的最小精度。在此基础上再乘转换出来的模拟量 就等于外部采集的模拟量。

2.独立模式-(单)多通道-必须采用DMA读取

采用DMA高效的读取转换的数据。

我们用通道10-15做实验,这些通道对应的引脚是PC0-PC5,用到的时钟就是C端口的时钟。但是ADC2没有DMA功能,我们只能用ADC1做实验。

先采集通道一的数据,然后进行数据转换,数据放到规则数据寄存器里面。但由于我们是多通道采集数据,如果不及时读走数据就会被覆盖,所以数据放到规则数据寄存器里就应该立马被读走。我们可以预先定义一个数组,DMA立刻将规则数据寄存器里的数据读到数组里面去(我们用到0-5 6个通道,所以数组里面有6个数据)。读取完通道一的数据之后,立刻采集通道二的数据…所有通道的数据读取完之后,就循环再读一遍。

先是配置ADC所用的GPIO;再初始化DMA和ADC的结构体。

static void ADCx_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	// 打开 ADC IO端口时钟
	ADC_GPIO_APBxClock_FUN ( ADC_GPIO_CLK, ENABLE );
	
	// 配置 ADC IO 引脚模式
	GPIO_InitStructure.GPIO_Pin = 	ADC_PIN1|
																		ADC_PIN2|
																		ADC_PIN3|
																		ADC_PIN4|
																		ADC_PIN5|
																		ADC_PIN6;

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	
	// 初始化 ADC IO
	GPIO_Init(ADC_PORT, &GPIO_InitStructure);				
}

static void ADCx_Mode_Config(void)
{
	DMA_InitTypeDef DMA_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;
	
	// 打开DMA时钟
	RCC_AHBPeriphClockCmd(ADC_DMA_CLK, ENABLE);
	// 打开ADC时钟
	ADC_APBxClock_FUN ( ADC_CLK, ENABLE );
	
	// 复位DMA控制器
	DMA_DeInit(ADC_DMA_CHANNEL);	
	// 配置 DMA 初始化结构体
	// 外设基址为:ADC 数据寄存器地址
	DMA_InitStructure.DMA_PeripheralBaseAddr = ( u32 ) ( & ( ADC_x->DR ) );
	// 存储器地址
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;	
	// 数据源来自外设
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;	
	// 缓冲区大小,应该等于数据目的地的大小
	DMA_InitStructure.DMA_BufferSize = NOFCHANEL;	
	// 外设寄存器只有一个,地址不用递增
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	// 存储器地址递增
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 	
	// 外设数据大小为半字,即两个字节
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;	
	// 内存数据大小也为半字,跟外设数据大小相同
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;	
	// 循环传输模式
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;	
	// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;	
	// 禁止存储器到存储器模式,因为是从外设到存储器
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;	
	// 初始化DMA
	DMA_Init(ADC_DMA_CHANNEL, &DMA_InitStructure);	
	// 使能 DMA 通道
	DMA_Cmd(ADC_DMA_CHANNEL , ENABLE);
	
	// ADC 模式配置
	// 只使用一个ADC,属于单模式
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	
	// 扫描模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE ; 
	// 连续转换模式
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
	// 不用外部触发转换,软件开启即可
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	// 转换结果右对齐
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	
	// 转换通道个数
	ADC_InitStructure.ADC_NbrOfChannel = NOFCHANEL;			
	// 初始化ADC
	ADC_Init(ADC_x, &ADC_InitStructure);	
	// 配置ADC时钟N狿CLK2的8分频,即9MHz
	RCC_ADCCLKConfig(RCC_PCLK2_Div8); 
	
	// 配置ADC 通道的转换顺序和采样时间
	ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL1, 1, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL2, 2, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL3, 3, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL4, 4, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL5, 5, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL6, 6, ADC_SampleTime_55Cycles5);
	
	// 使能ADC DMA 请求
	ADC_DMACmd(ADC_x, ENABLE);
	
	// 开启ADC ,并开始转换
	ADC_Cmd(ADC_x, ENABLE);
	
	// 初始化ADC 校准寄存器  
	ADC_ResetCalibration(ADC_x);
	// 等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADC_x));
	
	// ADC开始校准
	ADC_StartCalibration(ADC_x);
	// 等待校准完成
	while(ADC_GetCalibrationStatus(ADC_x));
	
	// 由于没有采用外部触发,所以使用软件触发ADC转换 
	ADC_SoftwareStartConvCmd(ADC_x, ENABLE);
}

注意:用作ADC采集的IO必须没有复用,否则采集电压会有影响。

ADC的I/O使用的模式使用的模式是模拟输入,既不上拉,也不下拉,采集到的数值完全取决于你想采集的模拟量。

3.双重模式-多通道-规则同步

双ADC进行采集,ADC1作为主,ADC2作为从,一个通道采集。二者的采集与转换都是同时进行的。ADC1的数据放在规则数据寄存器的低16位,ADC2的数据放在规则数据寄存器的高16位。数据放好之后,DMA会把数据读走,读到预先定义好的数组内(与上面一样),数组要定义为32,之前只有一个ADC,所以只需要16位的数组即可。

先是配置ADC所用的GPIO;再初始化DMA和ADC1和2的结构体。

static void ADCx_GPIO_Config(void)//ADC 的GPIO配置、初始化
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	// ADCx_1 GPIO 初始化
	ADCx_1_GPIO_APBxClock_FUN ( ADCx_1_GPIO_CLK, ENABLE );
	GPIO_InitStructure.GPIO_Pin = ADCx_1_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_Init(ADCx_1_PORT, &GPIO_InitStructure);

	// ADCx_2 GPIO 初始化
	ADCx_1_GPIO_APBxClock_FUN ( ADCx_2_GPIO_CLK, ENABLE );
	GPIO_InitStructure.GPIO_Pin = ADCx_2_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_Init(ADCx_2_PORT, &GPIO_InitStructure);	
}

static void ADCx_Mode_Config(void)
{
	DMA_InitTypeDef DMA_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;
	
	// 打开DMA时钟
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	// 打开ADC时钟
	ADCx_1_APBxClock_FUN ( ADCx_1_CLK, ENABLE );
	ADCx_2_APBxClock_FUN ( ADCx_2_CLK, ENABLE );
	
  /* ------------------DMA模式配置---------------- */	
	// 复位DMA控制器
	DMA_DeInit(ADC_DMA_CHANNEL);	
	// 配置 DMA 初始化结构体
	// 外设基址为:ADC 数据寄存器地址
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&( ADCx_1->DR ));	
	// 存储器地址
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue;	
	// 数据源来自外设
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;	
	// 缓冲区大小,应该等于数据目的地的大小
	DMA_InitStructure.DMA_BufferSize = NOFCHANEL;	
	// 外设寄存器只有一个,地址不用递增
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	// 存储器地址递增
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 	
	// 外设数据大小
	DMA_InitStructure.DMA_PeripheralDataSize = 
	                                  DMA_PeripheralDataSize_Word;	
	// 内存数据大小,跟外设数据大小相同
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;	
	// 循环传输模式
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;	
	// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;	
	// 禁止存储器到存储器模式,因为是从外设到存储器
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;	
	// 初始化DMA
	DMA_Init(ADC_DMA_CHANNEL, &DMA_InitStructure);	
	// 使能 DMA 通道
	DMA_Cmd(ADC_DMA_CHANNEL , ENABLE);
	
	/* ----------------ADCx_1 模式配置--------------------- */
	// 双ADC的规则同步
	ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;	
	// 扫描模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE ; 
	// 连续转换模式
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
	// 不用外部触发转换,软件开启即可
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	// 转换结果右对齐
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	
	// 转换通道个数
	ADC_InitStructure.ADC_NbrOfChannel = NOFCHANEL;			
	// 初始化ADC
	ADC_Init(ADCx_1, &ADC_InitStructure);	
	// 配置ADC时钟N狿CLK2的8分频,即9MHz
	RCC_ADCCLKConfig(RCC_PCLK2_Div8); 	
	// 配置ADC 通道的转换顺序和采样时间
	ADC_RegularChannelConfig(ADCx_1, ADCx_1_CHANNEL, 1, 
	                         ADC_SampleTime_239Cycles5);	
	// 使能ADC DMA 请求
	ADC_DMACmd(ADCx_1, ENABLE);
	
	
		/* ----------------ADCx_2 模式配置--------------------- */
	// 双ADC的规则同步
	ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;	
	// 扫描模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE ; 
	// 连续转换模式
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
	// 不用外部触发转换,软件开启即可
	ADC_InitStructure.ADC_ExternalTrigConv = 
	                           ADC_ExternalTrigConv_None;
	// 转换结果右对齐
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	
	// 转换通道个数
	ADC_InitStructure.ADC_NbrOfChannel = NOFCHANEL;			
	// 初始化ADC
	ADC_Init(ADCx_2, &ADC_InitStructure);	
	// 配置ADC时钟为PCLK2的8分频,即9MHz
	RCC_ADCCLKConfig(RCC_PCLK2_Div8); 	
	// 配置ADC 通道的转换顺序和采样时间
	ADC_RegularChannelConfig(ADCx_2, ADCx_2_CHANNEL, 1, 
	                         ADC_SampleTime_239Cycles5);
	/* 使能ADCx_2的外部触发转换 */
  ADC_ExternalTrigConvCmd(ADC2, ENABLE);
	
	/* ----------------ADCx_1 校准--------------------- */
	// 开启ADC ,并开始转换
	ADC_Cmd(ADCx_1, ENABLE);	
	// 初始化ADC 校准寄存器  
	ADC_ResetCalibration(ADCx_1);
	// 等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADCx_1));	
	// ADC开始校准
	ADC_StartCalibration(ADCx_1);
	// 等待校准完成
	while(ADC_GetCalibrationStatus(ADCx_1));
	
  /* ----------------ADCx_2 校准--------------------- */
		// 开启ADC ,并开始转换
	ADC_Cmd(ADCx_2, ENABLE);	
	// 初始化ADC 校准寄存器  
	ADC_ResetCalibration(ADCx_2);
	// 等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADCx_2));	
	// ADC开始校准
	ADC_StartCalibration(ADCx_2);
	// 等待校准完成
	while(ADC_GetCalibrationStatus(ADCx_2));

	// 由于没有采用外部触发,所以使用软件触发ADC转换 
	ADC_SoftwareStartConvCmd(ADCx_1, ENABLE);
}

注意:为什么ADC2要使用外部触发?

在双重采集模式下,ADC1是主,ADC2是从,在内部,ADC1会给ADC2一个触发信号,这个是在双重模式下硬件自动启动的。如果想让此启动成功,就要把ADC2外部触发的开关打开(此信号是ADC1给它的,相当于外部给它的)。

在实验中,我们可以不用跳线帽,我们用到了ADC1(PC1)和ADC2(PC4),我们观察ADC1的数据,可以用杜邦线把PC1和3V3连接起来;观察ADC2数据的时候,可以用杜邦线把PC4(液晶屏下面那个引脚)和3V3连接起来。

 

你可能感兴趣的:(STM32,单片机,嵌入式硬件,stm32)