服务器网站环境,文字图片生成器在线,游戏网站风格,做公司 网站建设本节主要介绍以下内容#xff1a;
ADC简介
ADC功能框图详解
参考资料:《零死角玩转STM32》“ADC—电压采集”章节
一、ADC简介
ADC #xff1a;Analog to Digital#xff0c;模拟数字转换器
三个独立的ADC 1 / 2 / 3分辨率为12位每个ADC具有18个通道#xff0c;其中…本节主要介绍以下内容
ADC简介
ADC功能框图详解
参考资料:《零死角玩转STM32》“ADC—电压采集”章节
一、ADC简介
ADC Analog to Digital模拟数字转换器
三个独立的ADC 1 / 2 / 3分辨率为12位每个ADC具有18个通道其中外部通道16个
二、ADC功能框图讲解
框图主要分为以下七个部分 1-电压输入范围 2-输入通道 3-转换顺序 4-触发源 5-转换时间 6-数据寄存器 7-中断
2.1 电压输入范围 ADC 输入范围为VREF- ≤ VIN ≤ VREF。由VREF-、VREF 、VDDA 、VSSA、这四个外部引脚决定。我们在设计原理图的时候一般把VSSA和VREF-接地把VREF和VDDA 接3V3得到ADC的输入电压范围为0~3.3V。 如果我们想让输入的电压范围变宽去到可以测试负电压或者更高的正电压我们可以在外部加一个电压调理电路把需要转换的电压抬升或者降压到0~3.3V这样ADC 就可以测量了
输入电压VREF- ≤ VIN ≤ VREF
决定输入电压的引脚VREF-、 VREF 、 VDDA 、 VSSA
VSSA 和 VREF-接地把 VREF和 VDDA 接 3V3得到ADC 的输入电压范围为 0~3.3V。
那么超出0~3.3V的电压怎么测
ADC可以测量:-10V~10V 根据基尔霍夫定律KCL节点流入的电流等于流出的电流
(Vint – Vout)/R2 (3V3-Vout)/R1 Vout / R3
Vout (Vint 10) /6
2.2 输入通道 我们确定好ADC 输入电压之后那么电压怎么输入到ADC这里我们引入通道的概念STM32 的ADC 多达18 个通道其中外部的16 个通道就是框图中的ADCx_IN0、ADCx_IN1...ADCx_IN5。这16 个通道对应着不同的IO 口具体是哪一个IO 口可以从手册查询到。其中ADC1/2/3 还有内部通道ADC1的通道16连接到了芯片内部的温度传感器Vrefint 连接到了通道17。ADC2 的模拟通道16 和17 连接到了内部的VSS。ADC3 的模拟通道9、14、15、16 和17 连接到了内部的VSS。
每个ADC具有18个通道其中外部通道16个 2.3 输入通道分类 外部的 16 个通道在转换的时候又分为规则通道和注入通道其中规则通道最多有 16路注入通道最多有 4 路。那这两个通道有什么区别在什么时候使用 规则通道顾名思意规则通道就是很规矩的意思我们平时一般使用的就是这个通道。
注入通道注入可以理解为插入插队的意思是一种不安分的通道。它是一种在规则通道转换的时候强行插入要转换的一种。这点跟中断程序很像都是不安分的主。所以注入通道只有在规则通道存在时才会出现。平时不需要使用
2.3.1 通道转换顺序 由寄存器来决定规则通道的转换顺序叫规则序列寄存器SQR1 2 3 分别控制不同通道的转换方式比如SQR3控制通道1-6的转换设计2^4 16,可以取值到1-16如果取1表示通道1第一个转换取2表示通道2第一个转换。 规则序列寄存器有3 个分别为SQR3、SQR2、SQR1。SQR3 控制着规则序列中的第 一个到第六个转换对应的位为SQ1[4:0]~SQ6[4:0]第一次转换的是位4:0 SQ1[4:0]如 果通道16 想第一次转换那么在SQ1[4:0]写16 即可。SQR2 控制着规则序列中的第7 到第 12 个转换对应的位为SQ7[4:0]~SQ12[4:0]如果通道1 想第8 个转换则SQ8[4:0]写1 即可。SQR1 控制着规则序列中的第13 到第16 个转换对应位为SQ13[4:0]~SQ16[4:0] 如果通道6 想第10 个转换则SQ10[4:0]写6 即可。具体使用多少个通道由SQR1 的位 L[3:0]决定最多16 个通道。 2.4 触发源 通道选好了转换的顺序也设置好了那接下来就该开始转换了。ADC 转换可以由 ADC 控制寄存器2: ADC_CR2 的ADON 这个位来控制写1 的时候开始转换写0 的时候 停止转换这个是最简单也是最好理解的开启ADC 转换的控制方式理解起来没啥技术含 量。 除了这种庶民式的控制方法ADC 还支持触发转换这个触发包括内部定时器触发和 外部IO 触发。触发源有很多具体选择哪一种触发源由ADC 控制寄存器2:ADC_CR2 的 EXTSEL[2:0] 和JEXTSEL[2:0]位来控制。EXTSEL[2:0]用于选择规则通道的触发源 JEXTSEL[2:0]用于选择注入通道的触发源。选定好触发源之后触发源是否要激活则由 ADC 控制寄存器2:ADC_CR2 的EXTTRIG 和JEXTTRIG 这两位来激活。其中ADC3 的规则转 换和注入转换的触发源与ADC1/2 的有所不同在框图上已经表示出来。
1、软件触发ADC_CR2 :ADON/SWST ART/JSWSTART 2、外部事件触发内部定时器/外部IO
选择ADC_CR2 :EXTSEL[2:0]和 JEXTSEL[2:0]
激活ADC_CR2 :EXTEN 和 JEXTEN
2.5 转换时间 ADC 输入时钟ADC_CLK 由PCLK2 经过分频产生最大是14M分频因子由RCC 时 钟配置寄存器RCC_CFGR 的位15:14 ADCPRE[1:0]设置可以是2/4/6/8 分频注意这里没 有1 分频。一般我们设置PCLK2HCLK72M。 ADC 使用若干个ADC_CLK 周期对输入的电压进行采样采样的周期数可通过ADC 采样时间寄存器ADC_SMPR1 和ADC_SMPR2 中的SMP[2:0]位设置ADC_SMPR2 控制的 是通道0~9ADC_SMPR1 控制的是通道10~17。每个通道可以分别用不同的时间采样。其 中采样周期最小是1.5 个即如果我们要达到最快的采样那么应该设置采样周期为1.5 个 周期这里说的周期就是1/ADC_CLK。 ADC 的转换时间跟ADC 的输入时钟和采样时间有关公式为Tconv 采样时间 12.5 个周期。当ADCLK 14MHZ 最高采样时间设置为1.5 周期最快那么总 的转换时间最短Tconv 1.5 周期 12.5 周期 14 周期 1us。 一般我们设置PCLK272M经过ADC 预分频器能分频到最大的时钟只能是12M采 样周期设置为1.5 个周期算出最短的转换时间为1.17us这个才是最常用的。
转换时间Tconv 采样时间 12.5 个周期
ADC_CLKADC模拟电路时钟最大值为14M由PCLK2提供还可分频2/4/6/8RCC_CFGR 的 ADCPRE[1:0]设置。PCLK272M。
数字时钟RCC_APB2ENR用于访问寄存器
采样时间ADC 需要若干个 ADC_CLK 周期完成对输入的模拟量进行采样采样的周期数可通过ADC 采样时间寄存器 ADC_SMPR1 和 ADC_SMPR2 中的 SMPx[2:0]位设置 ADC_SMPR2控制的是通道 0~9 ADC_SMPR1 控制的是通道 10~17。每个通道可以分别用不同的时间采样。其中采样周期最小是 1.5 个即如果我们要达到最快的采样那么应该设置采样周期为 31.5个周期这里说的周期就是 1/ADC_CLK。 最短的转换时间Tconv 采样时间 12.5 个周期
PCLK2 72MADC_CLK 72/6 12M
Tconv 1.512.5 14周期 14/12us1.17us
2.6 数据寄存器
一切准备就绪后 ADC 转换后的数据根据转换组的不同规则组的数据放在ADC_DR 寄存器注入组的数据放在 JDRx。
2.6.1 规则数据寄存器 ADC 规则组数据寄存器ADC_DR 只有一个是一个32 位的寄存器低16 位在单ADC 时使用高16 位是在ADC1 中双模式下保存ADC2 转换的规则数据双模式就是ADC1 和 ADC2 同时使用。在单模式下ADC1/2/3 都不使用高16 位。因为ADC 的精度是12 位无 论ADC_DR 的高16 或者低16 位都放不满只能左对齐或者右对齐具体是以哪一种方式 存放由ADC_CR2 的11 位ALIGN 设置。 规则通道可以有16 个这么多可规则数据寄存器只有一个如果使用多通道转换那 转换的数据就全部都挤在了DR 里面前一个时间点转换的通道数据就会被下一个时间 点的另外一个通道转换的数据覆盖掉所以当通道转换完成后就应该把数据取走或者开 启DMA 模式把数据传输到内存里面不然就会造成数据的覆盖。最常用的做法就是开 启DMA 传输。 1-16位有效用于存放独立模式转换完成数据
2- ADC_CR2 ALIGN
3-只有一个多通道采集的是最好使用DMA
2.6.2 注入数据寄存器 ADC 注入组最多有4 个通道刚好注入数据寄存器也有4 个每个通道对应着自己的 寄存器不会跟规则寄存器那样产生数据覆盖的问题。ADC_JDRx 是32 位的低16 位有 效高16 位保留数据同样分为左对齐和右对齐具体是以哪一种方式存放由 ADC_CR2 的11 位ALIGN 设置。 1-16位有效用于存放注入通道转换完成数据
2- ADC_CR2 ALIGN
3-有4个这样的寄存器
2.7 中断
2.7.1 转换结束中断 数据转换结束后可以产生中断中断分为三种规则通道转换结束中断注入转换通道转换结束中断模拟看门狗中断。其中转换结束中断很好理解跟我们平时接触的中断一样有相应的中断标志位和中断使能位我们还可以根据中断类型写相应配套的中断服务程序。
2.7.2 模拟看门狗中断 当被ADC 转换的模拟电压低于低阈值或者高于高阈值时就会产生中断前提是我们开启了模拟看门狗中断其中低阈值和高阈值由ADC_LTR 和ADC_HTR 设置。例如我们设置高阈值是2.5V那么模拟电压超过2.5V 的时候就会产生模拟看门狗中断反之低阈值也一样。
2.7.3 DMA 请求 规则和注入通道转换结束后除了产生中断外还可以产生DMA 请求把转换好的 数据直接存储在内存里面。要注意的是只有ADC1 和ADC3 可以产生DMA 请求。有关 DMA请求需要配合《STM32F10X-中文参考手册》DMA控制器这一章节来学习。一般我们 在使用ADC 的时候都会开启DMA 传输。 那么怎么根据数据量算出模拟量 模拟电压经过ADC 转换后是一个12 位的数字值如果通过串口以16 进制打印出来的话可读性比较差那么有时候我们就需要把数字电压转换成模拟电压也可以跟实际的模拟电压用万用表测对比看看转换是否准确。 我们一般在设计原理图的时候会把ADC 的输入电压范围设定在0~3.3v因为ADC是12 位的那么12 位满量程对应的就是3.3V12 位满量程对应的数字值是2^12。数值0 对应的就是0V。如果转换后的数值为 X X 对应的模拟电压为Y那么会有这么一个等式成立 2^12 / 3.3 X / Y Y (3.3 * X ) / 2^12。 三、ADC初始化结构体讲解 标准库函数对每个外设都建立了一个初始化结构体xxx_InitTypeDef(xxx 为外设名称)结构体成员用于设置外设工作参数并由标准库函数xxx_Init()调用这些设定参数进入设置外设相应的寄存器达到配置外设工作环境的目的。 结构体xxx_InitTypeDef 和库函数xxx_Init 配合使用是标准库精髓所在理解了结构体 xxx_InitTypeDef 每个成员意义基本上就可以对该外设运用自如了。结构体xxx_InitTypeDef定义在stm32f10x_xxx.h 文件中库函数xxx_Init 定义在stm32f10x_xxx.c 文件中编程时我们可以结合这两个文件内注释使用。
ADC_InitTypeDef 结构体 ADC_Mode配置ADC 的模式当使用一个ADC 时是独立模式使用两个ADC 时是 双模式在双模式下还有很多细分模式可选具体配置ADC_CR1:DUALMOD 位。
ScanConvMode可选参数为ENABLE 和DISABLE配置是否使用扫描。如果是单通 道AD 转换使用DISABLE 如果是多通道AD 转换使用ENABLE 具体配置 ADC_CR1:SCAN 位。
ADC_ContinuousConvMode可选参数为ENABLE 和DISABLE配置是启动自动连续 转换还是单次转换。使用ENABLE 配置为使能自动连续转换使用DISABLE 配置为单次 转换转换一次后停止需要手动控制才重新启动转换具体配置ADC_CR2:CON 位。
ADC_ExternalTrigConv外部触发选择上文中断章节 列举了很多外部触发条件可根据 项目需求配置触发来源。实际上我们一般使用软件自动触发。
ADC_DataAlign转换结果数据对齐模式可选右对齐ADC_DataAlign_Right或者左对 齐ADC_DataAlign_Left。一般我们选择右对齐模式。
ADC_NbrOfChannelAD 转换通道数目根据实际设置即可。具体的通道数和通道的 转换顺序是配置规则序列或注入序列寄存器。
几个常用的固件库函数讲解 ADC_Init(); 429 RCC_ADCCLKConfig(); 680 //该函数配置ADC clock的分频ADC_RegularChannelConfig(); 442 //配置通道的转换顺序ADC_Cmd(); 431 ADC_SoftwareStartConvCmd(); 438 //软件触发ADC_ExternalTrigConvCmd(); 443 //外部触发ADC_DMACmd(); 432 //采集并转换完数据之后要不要启动DMA把 数据存储到其他地方
四、模数转换器相关代码讲解 STM32 的ADC 功能繁多我们设计三个实验尽量完整的展示ADC 的功能。首先是比 较基础实用的单通道采集实现开发板上电位器电压的采集并通过串口打印至PC端串口 调试助手。单通道采集适用AD 转换完成中断在中断服务函数中读取数据不使用DMA 传输在多通道采集时才使用DMA 传输。
4.1 硬件设计
霸道ADC接口 贴片滑动变阻器的动触点通过连接至STM32 芯片的ADC 通道引脚。当我们旋转滑动变阻器调节旋钮时其动触点电压也会随之改变电压变化范围为0~3.3V亦是开发板默认的ADC 电压采集范围。
4.2 软件设计
-独立模式-单通道-中断读取-独立模式-单通道-DMA读取-独立模式-多通道-DMA读取-双重模式-多通道-规则同步 4.2.1 -独立模式-单通道-中断读取
编程要点
初始化ADC用到的GPIO初始化ADC初始化结构体配置ADC时钟配置通道的转换顺序和采样时间使能ADC转换完成中断配置中断优先级使能ADC,准备开始转换校准ADC软件触发ADC,真正开始转换编写中断服务函数读取ADC转换数据编写main函数把转换的数据打印出来 bsp_adc.h
#ifndef __ADC_H
#define __ADC_H#include stm32f10x.h// ADC 编号选择
// 可以是 ADC1/2如果使用ADC3中断相关的要改成ADC3的
#define ADC_APBxClock_FUN RCC_APB2PeriphClockCmd
#define ADCx ADC2
#define ADC_CLK RCC_APB2Periph_ADC2// ADC GPIO宏定义
// 注意用作ADC采集的IO必须没有复用否则采集电压会有影响
#define ADC_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define ADC_GPIO_CLK RCC_APB2Periph_GPIOC
#define ADC_PORT GPIOC
#define ADC_PIN GPIO_Pin_1
// ADC 通道宏定义
#define ADC_CHANNEL ADC_Channel_11// ADC 中断相关宏定义
#define ADC_IRQ ADC1_2_IRQn
#define ADC_IRQHandler ADC1_2_IRQHandler//#define ADC_IRQ ADC3_IRQn
//#define ADC_IRQHandler ADC3_IRQHandlervoid ADCx_Init(void);#endif /* __ADC_H */
bsp_adc.c
#includebsp_adc.hstatic void ADCx_GPIO_Config(void )
{GPIO_InitTypeDef GPIO_InitStructure;ADC_GPIO_APBxClock_FUN(ADC_GPIO_CLK,ENABLE);// 配置 ADC IO 引脚模式// 必须为模拟输入GPIO_InitStructure.GPIO_Mode GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin ADC_PIN;// 初始化 ADC IOGPIO_Init(ADC_PORT, GPIO_InitStructure);
}static void ADCx_Mode_Config(void )
{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;// 初始化ADCADC_Init(ADC_x,ADC_InitStructure);//配置ADC时钟RCC_ADCCLKConfig(RCC_PCLK2_Div8);//配置通道的转换顺序和采样时间ADC_RegularChannelConfig(ADC_x,ADC_CHANNEL,1,ADC_SampleTime_55Cycles5);//4、使能ADC转换完成中断配置中断优先级 ADC_ITConfig(ADC_x, ADC_IT_EOC, ENABLE);//5、使能ADC,准备开始转换ADC_Cmd(ADC_x, ENABLE);// 初始化ADC 校准寄存器 ADC_ResetCalibration(ADC_x);// 等待校准寄存器初始化完成while(ADC_GetResetCalibrationStatus(ADC_x));//6、校准ADC// ADC开始校准ADC_StartCalibration(ADC_x);// 等待校准完成while(ADC_GetCalibrationStatus(ADC_x));//软件触发ADC,真正开始转换ADC_SoftwareStartConvCmd(ADC_x, ENABLE);}static void ADC_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStructure;//优先级分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//配置中断优先级NVIC_InitStructure.NVIC_IRQChannel ADC_IRQ;NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority 1;NVIC_Init(NVIC_InitStructure);}void ADCx_Init(void)
{ADC_NVIC_Config();ADCx_GPIO_Config();ADCx_Mode_Config();
}stm32f10x_it.c
/********************************************************************************* file Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c * author MCD Application Team* version V3.5.0* date 08-April-2011* brief Main Interrupt Service Routines.* This file provides template for all exceptions handler and * peripherals interrupt service routine.******************************************************************************* attention** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** h2centercopy; COPYRIGHT 2011 STMicroelectronics/center/h2*******************************************************************************//* Includes ------------------------------------------------------------------*/
#include stm32f10x_it.h#include bsp_adc.h
extern __IO uint16_t ADC_ConvertedValue;/** addtogroup STM32F10x_StdPeriph_Template* {*//* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*//******************************************************************************/
/* Cortex-M3 Processor Exceptions Handlers */
/******************************************************************************//*** brief This function handles NMI exception.* param None* retval None*/
void NMI_Handler(void)
{
}/*** brief This function handles Hard Fault exception.* param None* retval None*/
void HardFault_Handler(void)
{/* Go to infinite loop when Hard Fault exception occurs */while (1){}
}/*** brief This function handles Memory Manage exception.* param None* retval None*/
void MemManage_Handler(void)
{/* Go to infinite loop when Memory Manage exception occurs */while (1){}
}/*** brief This function handles Bus Fault exception.* param None* retval None*/
void BusFault_Handler(void)
{/* Go to infinite loop when Bus Fault exception occurs */while (1){}
}/*** brief This function handles Usage Fault exception.* param None* retval None*/
void UsageFault_Handler(void)
{/* Go to infinite loop when Usage Fault exception occurs */while (1){}
}/*** brief This function handles SVCall exception.* param None* retval None*/
void SVC_Handler(void)
{
}/*** brief This function handles Debug Monitor exception.* param None* retval None*/
void DebugMon_Handler(void)
{
}/*** brief This function handles PendSVC exception.* param None* retval None*/
void PendSV_Handler(void)
{
}/*** brief This function handles SysTick Handler.* param None* retval None*/
void SysTick_Handler(void)
{
}void ADC_IRQHandler(void)
{ if (ADC_GetITStatus(ADCx,ADC_IT_EOC)SET) {// 读取ADC的转换值ADC_ConvertedValue ADC_GetConversionValue(ADCx);}ADC_ClearITPendingBit(ADCx,ADC_IT_EOC);
}/******************************************************************************/
/* STM32F10x Peripherals Interrupt Handlers */
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
/* available peripheral interrupt handlers name please refer to the startup */
/* file (startup_stm32f10x_xx.s). */
/******************************************************************************//*** brief This function handles PPP interrupt request.* param None* retval None*/
/*void PPP_IRQHandler(void)
{
}*//*** }*/ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/main.c // ADC 单通道采集不使用DMA一般只有ADC2才这样使用因为ADC2不能使用DMA#include stm32f10x.h
#include bsp_usart.h
#include bsp_adc.hextern __IO uint16_t ADC_ConvertedValue;// 局部变量用于保存转换计算后的电压值
float ADC_ConvertedValueLocal; // 软件延时
void Delay(__IO uint32_t nCount)
{for(; nCount ! 0; nCount--);
} /*** brief 主函数* param 无* retval 无*/
int main(void)
{ // 配置串口USART_Config();// ADC 初始化ADCx_Init();printf(\r\n ----这是一个ADC单通道中断读取实验----\r\n);while (1){ADC_ConvertedValueLocal (float) ADC_ConvertedValue/4096*3.3; printf(\r\n The current AD value 0x%04X \r\n, ADC_ConvertedValue); printf(\r\n The current AD value %f V \r\n,ADC_ConvertedValueLocal); printf(\r\n\r\n);Delay(0xffffee); }
}
/*********************************************END OF FILE**********************/4.2.2-独立模式-单通道-DMA读取
优点快 不需要写中断服务函数 当数据又多又快的时候使用这个
初始化ADC用到的GPIO初始化ADC、DMA初始化结构体配置ADC时钟配置通道的转换顺序和采样事件编写main函数
此处仅提供bsp_adc.c,
#includebsp_adc.h__IO uint16_t ADC_ConveredValue;static void ADCx_GPIO_Config(void )
{GPIO_InitTypeDef GPIO_InitStructure;ADC_GPIO_APBxClock_FUN(ADC_GPIO_CLK,ENABLE);// 配置 ADC IO 引脚模式// 必须为模拟输入GPIO_InitStructure.GPIO_Mode GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin ADC_PIN;// 初始化 ADC IOGPIO_Init(ADC_PORT, GPIO_InitStructure);
}static void ADCx_Mode_Config(void )
{ADC_InitTypeDef ADC_InitStructure;DMA_InitTypeDef DMA_InitStructure;ADC_APBxClock_FUN(ADC_CLK,ENABLE);//打开DMA时钟DMA_AHBxClock_FUN(DMA_CLK,ENABLE);DMA_InitStructure.DMA_PeripheralBaseAddr ( uint32_t ) ( ( ADC_x-DR ) );DMA_InitStructure.DMA_MemoryBaseAddr (uint32_t)ADC_ConveredValue;DMA_InitStructure.DMA_DIR DMA_DIR_PeripheralSRC;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;//16位DMA_InitStructure.DMA_MemoryDataSize DMA_MemoryDataSize_HalfWord;DMA_InitStructure.DMA_Mode DMA_Mode_Circular; DMA_InitStructure.DMA_Priority DMA_Priority_High;DMA_InitStructure.DMA_M2M DMA_M2M_Disable;DMA_Init(DMA_CHANNEL, DMA_InitStructure); DMA_Cmd(DMA_CHANNEL , 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;// 初始化ADCADC_Init(ADC_x,ADC_InitStructure);//配置ADC时钟RCC_ADCCLKConfig(RCC_PCLK2_Div8);//配置通道的转换顺序和采样时间ADC_RegularChannelConfig(ADC_x,ADC_CHANNEL,1,ADC_SampleTime_55Cycles5);//使能ADC DMA请求ADC_DMACmd(ADC_x,ENABLE);//5、使能ADC,准备开始转换ADC_Cmd(ADC_x, ENABLE);//6、校准ADC// ADC开始校准ADC_StartCalibration(ADC_x);// 等待校准完成while(ADC_GetCalibrationStatus(ADC_x));//软件触发ADC,真正开始转换ADC_SoftwareStartConvCmd(ADC_x, ENABLE);}void ADCx_Init(void)
{ADCx_GPIO_Config();ADCx_Mode_Config();
}