目录

1. ADC是什么

2. ADC主要特性

3. ADC框图

3.1 ADC开关控制

3.2 ADC时钟

3.3 通道选择

3.4 单次转换模式和连续转换模式

3.5 时序图

3.6 模拟看门狗

4 温度传感器

5. ADC中断

6. ADC初始化结构体

6.1 ADC相关实验配置

7. 相关寄存器

7.1 ADC控制寄存器:ADC_CR1和ADC_CR2

7.2 ADC通用控制寄存器:ADC_CCR

7.3 ADC采样时间寄存器:ADC_SMPR1和ADC_SMPR2

7.4 ADC规则序列寄存器:ADC_SQRx(x取值1~3)

7.5 ADC规则数据寄存器:ADC_DR

7.6 ADC状态寄存器:ADC_SR

8. 库函数配置ADC1的通道5进行AD转换

9. 实验程序

9.1 main.c

9.2 ADC.c

9.3 ADC.h


首先明确,这里提到的ADC不是我们游戏中的ADC,这里提及的ADC是STM32的一种重要外设功能,ADC英文全程:Analog to Digital,又叫做模拟数字转换器。

1. ADC是什么

在高中的物理中,我们学习过电压表、电流表和万用表的使用,这些器件可以用来测量电路中的分路电流、电压值;强大的STM32单片机中也存在着这样的外设,称作模数转换器ADC;

很好理解,模数转换器就是把模拟量转换成数字量;数字对于我们来说是很亲切的,之所以存在这样的外设,也是为了更方便于使用者的理解和操作。

模拟量就如电压值、光敏电阻阻值、热敏电阻阻值等,通过该转换器可以转换为我们肉眼可见的数字。

STM32F4的ADC是12位逐次趋近型模数转换器。具有多达19个复用通道,可测量来自16个外部源、两个内部源通道的信号。ADC的结果存储在一个左对齐或者右对齐的16位数据寄存器中。

ADC具有模拟看门狗特性,允许应用检测输入电压是否超过了用户自定义的阈值上限或者下限。

STM32F4xx系列一般都有3个ADC,这些ADC可以独立使用,也可以使用双重/三重模样,来提高采样率。STM32F4的ADC是12位逐次逼近型的模拟数字转换器,它有19个通道,可以测16个外部源、2个内部源和Vbat通道的信号。STM32F4的ADC最大的转换速率为2.4Mhz,也就是转换时间为0.41us。

2. ADC主要特性

  • 可配置12位、10位、8位或6位分辨率
  • 在转换结束、注入转换结束以及发生模拟看门狗或溢出事件时产生中断
  • 单次和连续转换模式
  • 用于自动将通道0转换为通道“n”的扫描模式
  • 数据对齐以保持内置数据一致性
  • 可独立设置各通道采样时间
  • 外部触发器选项,可为规则转换和注入转换配置极性
  • ADC电源要求:全速运行时2.4V到3.6V,慢速运行时1.8V

3. ADC框图

1. 电压输入范围

表示正模拟参考电压输入,代表ADC高/正参考电压;

表示模拟电源输入,代表模拟电源电压等于

表示负模拟参考电压输入,代表ADC低/负参考电压;

表示模拟电源接地输入,代表模拟电源接地电压等于

输入电压:  <= VIN <=  

 和 接地,把接3V3,表示得到ADC的输入电压范围为0-3.3V;

STM32的ADC只能测0-3.3V的电压,如果超过了这个范围,只能在单片机上改变电压的范围(通过相应芯片的转电平作用),以保证能够被STM32的GPIO口识别。

2. 输入通道:

STM32的每个ADC都具有18个通道,其中外部通道16个:

STM32的ADC有16条复用通道。外部16个通道在转换的过程中又分为规则通道和注入通道。

可以将转换分为两组:规则转换注入转换。每个组包含一个转换序列,该序列可按任意顺序在任意通道上完成。

其中规则通道由规则序列寄存器ADC_SQRx(x可以取值为1 2 3)来配置,注入通道由注入序列寄存器ADC_JSQR来配置。

一个规则转换组最多由16个转换构成。必须在ADC_SQRx寄存器中选择转换序列的规则通道及其顺序。规则转换组中的转换总数必须写入ADC_SQRx寄存器中的L[3:0]位。

一个注入转换组最多由4个转换构成。必须在ADC_JSQR寄存器中选择转换序列的注入通道及其顺序。注入转换组中的转换总数必须写入ADC_JSQR寄存器中的L[1:0]位。

顾名思义,两个通道的区别就是:规则通道就是很规矩的意思,我们一般使用的就是这个规则通道。注入可以理解为插入、插队的意思,是一种不安分的通道,有点类似于中断程序;注入通道只有在规则通道存在时才会出现。

3.  转换顺序:

输入通道注入通道的转换顺序分别由规则序列寄存器ADC_SQRx(x可以取值为1 2 3)和注入序列寄存器ADC_JSQR来配置。

4. 触发源:

触发源相当于一个信号,用来告诉ADC可以开始转换了。

触发方式又分为软件触发外部事件触发(内部定时器/外部IO)。分别对应于上图中的左侧TIM和右侧TIM。

5. 转换时间:

转换时间:Tconv=采样时间+12个周期

采样时间: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。

ADC_CLK:ADC模拟电路时钟,最大值为14M,由PCLK2提供,还可以进行分频,2/4/6/8,RCC_CFGR的ADCPRE[1:0]设置。PCLK2=72M。

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

ag. 最短的转换时间:Tconv=采样时间+12个周期 (其中PCLK2=72M,ADC_CLK=72/6=12M ,Tconv=1.5+12.5=14=14/12us=1.17us)

6. 数据寄存器:

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

数据寄存器ADC_DR(ADC regular data register)

位31:16  保留,必须保持复位值

位15:0 DATA[15:0]:规则数据(Regular data) 这些位为只读。它们包括来自规则通道的转换结果。

该寄存器的1~16位有效,用于存放独立模式转换完成数据。当在双ADC模式(ADC1和ADC2同时使用)下,ADC1放在低16位上,ADC2放在高16位上。

7. 中断:

STM32F4相比于F1增加了DMA溢出标志。由模拟看门狗来检测采样的模拟量信号值的下限和上限。

电压转换:

所谓电压转换就是如何根据数字量去算出模拟量?  也可以说是外部电压假设是2.5V,通过ADC转换成数字量,也就是数字,存放在数据寄存器ADC_DR中,电压转换就是通过数据寄存器中的数字去反推出外部电压。

1. 电压输入范围为:0~3.3V

2. 分辨率为12位

3. 最小精度为:3.3/2^12

4. 设数字量为x,则有模拟量Y=(3.3/2^12)* x

3.1 ADC开关控制

可以通过将ADC控制寄存器ADC_CR2寄存器中的ADON位置1来为ADC供电。首次将ADON位置1时,会将ADC从掉电模式中唤醒。

SWSTART或JSWSTART位置1,启动AD转换。

可通过将ADON位清零来停止转换并使ADC进入掉电模式,在此模式下,ADC几乎不耗电,也可以说进入了低功耗模式。

3.2 ADC时钟

用于模拟电路的时钟:ADCCLK,所有ADC共用

此时钟来自于经可编程预分频器分频的APB2时钟,该预分频器允许ADC在、/4、/6或/8下工作。

用于数字接口的时钟:(用于寄存器读/写访问)

此时钟等效于APB2时钟。可以通过RCC APB2外设时钟使能寄存器(RCC_APB2ENR)分别为每个ADC使能/禁止数字接口时钟。

3.3 通道选择

STM32的ADC有16条复用通道。外部16个通道在转换的过程中又分为规则通道和注入通道。

可以将转换分为两组:规则转换注入转换。每个组包含一个转换序列,该序列可按任意顺序在任意通道上完成。

一个规则转换组最多由16个转换构成。必须在ADC_SQRx寄存器中选择转换序列的规则通道及其顺序。规则转换组中的转换总数必须写入ADC_SQRx寄存器中的L[3:0]位。

一个注入转换组最多由4个转换构成。必须在ADC_JSQR寄存器中选择转换序列的注入通道及其顺序。注入转换组中的转换总数必须写入ADC_JSQR寄存器中的L[1:0]位。

顾名思义,两个通道的区别就是:规则通道就是很规矩的意思,我们一般使用的就是这个规则通道。注入可以理解为插入、插队的意思,是一种不安分的通道,有点类似于中断程序;注入通道只有在规则通道存在时才会出现。因为注入通道相当于中断,那么当程序正常执行的时候,中断是可以打断你的执行的。因此注入通道的转换可以打断规则通道的转换,在注入通道被转换完成之后,规则通道才得以继续转换。

如果在转换期间修改 ADC_SQRx 或 ADC_JSQR 寄存器,将复位当前转换并向 ADC 发送一 个新的启动脉冲,以转换新选择的组。

温度传感器、内部通道

对于STM32F40x系列的开发板,温度传感器内部连接到ADC1_IN16。内部参考电压连接到ADC1_IN17。

注意: 温度传感器、只在主ADC1外设上可用。

3.4 单次转换模式和连续转换模式

单次转换模式下,ADC执行一次转换。CONT位为0时,可以通过以下三种方式启动此模式:

  • 将ADC_CR2寄存器中的SWSTART位置1(仅适用于规则通道)
  • 将JSWSTART位置1(适用于注入通道)
  • 外部触发(适用于规则通道和注入通道)

如果转化了规则通道:

  • 转换数据存储在16位ADC_DR寄存器中
  • EOC(转换结束)标志位置1
  • EOCIE位置1时将产生中断

如果转换了注入通道:

  • 转换数据存储在16位ADC_JCR1寄存器中
  • JEOC(注入转换结束)标志置1
  • JEOCIE位置1时将产生中断

连续转换模式下,ADC结束一个转换后立即启动一个新的转换。CONT位为1时,可通过外部触发或将ADC_CR2寄存器中的SWSTRT位置1来启动该模式(仅适用于规则通道)

如果转换了规则通道组:

  • 上次转换的数据存储在16位ADC_DR寄存器中
  • EOC(转换结束)标志置1
  • EOCIE位置1时将产生中断

STM32F4的ADC在单次转换模式下,只执行一次转换,该模式可通过ADC_CR2寄存器的ADON位(只适用于规则通道)启动,也可以通过外部触发启动(适用于规则通道和注入通道),这时CONT位为0。

以规则通道为例,一旦所选择的通道转换完成,转换结果将被存储在ADC_DR寄存器中,EOC(转化结束)标志将被置位,如果设置了EOCIE,则会产生中断。然后ADC将停止,直到下次启动。

3.5 时序图

在时序图中, ADC_CLK表示ADC的时钟;ADON是ADC控制寄存器中的最低位,将该位置1表示开启寄存器;SWSTART/JSWSTART用来设置转换模式;

ADC在开始精确转换之前需要一段稳定时间。ADC开始转换并经过15个时钟周期后,EOC标志置1,转换结果存放在16位ADC数据寄存器中。

3.6 模拟看门狗

如果ADC转换的模拟电压低于阈值下限或者高于阈值上限,则AWR模拟看门狗状态位会置1。这些阈值在ADC_HTR或ADC_LTR 16位寄存器的12个最低有效位中进行编程。可以使用ADC_CR1寄存器中的AWDIE位使能中断。

4 温度传感器

我们都很清楚传感器的用处,那么显然温度传感器就是用来测量器件的环境温度()的。

对应STM32F40x系列的开发板器件(其他的型号开发板对应不同的ADC通道),温度传感器内部连接到ADC1_IN16通道,而ADC1用于将传感器输出电压转换为数字值。不使用时可以将传感器置于掉电模式。

注意:必须将TSVREFE位置1才能同时对两个通道进行转换。ADC1_IN16(温度传感器)和ADC1_IN17(VREFINT)。

主要特性

  • 支持的温度范围(可以通过ADC转换成的数字范围):-40℃到125℃
  • 精度:1.5℃

 读取温度

  • 选择ADC1_IN16输入通道
  • 选择一个采样时间,该采样时间要大于数据手册上指定的最低采样时间
  • 在ADC_CCR寄存器中将TSVREFE位置1,以便将温度传感器从掉电模式中唤醒
  • 通过将SWSTART位置1开始ADC转换
  • 读取ADC数据寄存器中生成的数据

计算温度

温度(单位℃)={-/Avg_Slope}+25

其中:   =25℃时的值          Avg_Slope=温度与曲线的平均斜率

注意

传感器从掉电模式中唤醒需要一个启动时间,启动时间过后其才能正确输出。ADC在上电后同样需要一个启动时间,因此,为尽可能减少延迟时间,应同时将ADON和TSVREFE位置1。

温度传感器的输出电压随温度线性变化。

5. ADC中断

当模拟看门狗状态位和溢出状态位分别置1时,规则组和注入组在转换结束时可能会产生中断。可以使用单独的中断使能位以实现灵活性。

ADC_SR寄存器中存在另外两个标志,但这两个标志不存在中断相关性:

  • JSTRT(开始转换注入组的通道)
  • STRT(开始转换规则组的通道)

6. ADC初始化结构体

ADC_InitTypeDef

typedef struct
{uint32_t ADC_Resolution;         //ADC分辨率                                        FunctionalState ADC_ScanConvMode;     //ADC扫描多通道或者ADC单通道模式选择  通过ADC_CR1的SCAN位来配置FunctionalState ADC_ContinuousConvMode;   //ADC单次转换或者连续转换选择 通过ADC_CR2的CON位来配置uint32_t ADC_ExternalTrigConvEdge;      //ADC转换触发信号范围选择uint32_t ADC_ExternalTrigConv;          //ADC外部触发转换模式选择  通过ADC_CR2的EXTTRIG和EXTSEL位来配置uint32_t ADC_DataAlign;                 //ADC数据寄存器对齐格式uint8_t  ADC_NbrOfConversion;           //ADC采集通道数
}ADC_InitTypeDef;

typedef struct
{uint32_t ADC_Mode;              //ADC模式 通过ADC_CR1:DUALMOD位来配置                                                 uint32_t ADC_Prescaler;              //ADC预分频值                       uint32_t ADC_DMAAccessMode;           uint32_t ADC_TwoSamplingDelay;        //ADC多通道模式
}ADC_CommonInitTypeDef;

6.1 ADC相关实验配置

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

  • 初始化ADC用到的GPIO
  • 初始化ADC初始化结构体
  • 配置ADC时钟,配置通道的转换顺序和采样时间
  • 使能ADC转换完成中断,配置中断优先级
  • 使能ADC,准备开始转换
  • 校准ADC   ADC_StartCalibration      ADC_GetCalibrationStatus
  • 软件触发ADC,真正开始转换   ADC_SoftwareStartConvCmd
  • 编写中断服务函数,读取ADC转换数据
  • 编写main函数,把转换的数据打印出来

2-独立模式-单通道-DMA读取                DMA是一种直接存储器,DMA是不占用CPU的,可以一边读取数据,一边处理数据。

  • 初始化ADC用到的GPIO
  • 初始化ADC初始化结构体
  • 配置ADC时钟,配置通道的转换顺序和采样时间
  • 使能ADC转换完成中断,配置中断优先级

3-独立模式-多通道-DMA读取

  • 初始化ADC用到的GPIO
  • 初始化ADC初始化结构体
  • 配置ADC时钟,配置通道的转换顺序和采样时间
  • 使能ADC转换完成中断,配置中断优先级

配置过程相同,只不过初始化IO口时需要初始化多个IO口通道。并且调用函数ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_480Cycles );  获取多个通道执行多个功能即可。

7. 相关寄存器

7.1 ADC控制寄存器:ADC_CR1和ADC_CR2

ADC控制寄存器1:ADC_CR1(ADC control register 1)

SCAN位:设置扫描模式位,通过软件将该位置1或者清零可以使能/禁止扫描模式。 在扫描模式下,转换由规则序列寄存器ADC_SQRx注入序列寄存器ADC_JSQRx选中的通道被转换 。

0:禁止扫描模式

1:使能扫描模式

如果设置了EOCIE和JEOCIE,只在最后一个通道转换完毕后才会产生EOC和JEOC中断。

RES位[1:0]:通过该位来设置分辨率(Resolution)

00:12位(15 ADCCLK周期)

01:10位(13 ADCCLK周期)

10:8位(11 ADCCLK周期)

11:6位(9 ADCCLK周期)

ADC控制寄存器2:ADC_CR2(ADC control register 2)

ADON位:设置A/D转换器开启或者关闭

0:禁止ADC转换并转至掉电模式

1:使能ADC

CONT位:该位用来设置连续转换模式或者单次转换模式

0:单次转换模式

1:连续转换模式

ALIGN位:该位用来设置数据是左对齐还是右对齐

0:右对齐

1:左对齐

EXTEN位:该位用来设置规则通道的外部触发是否使能

00:禁止触发检测

01:上升沿上的触发检测

10:下降沿上的触发检测

11:上升沿和下降沿上的触发检测

SWSTART位:用于开始规则通道的转换,我们每次转换(单次转换模式下)都需要向该位写1

0:复位状态

1:开始转换规则通道

7.2 ADC通用控制寄存器:ADC_CCR

ADC通用控制寄存器:ADC_CCR(ADC common control register)

TSVREFE位:温度传感器和使能位

0:禁止

1:使能

ADCPRE位:ADC预分频器,该位由软件置1或者清0,以选择ADC的时钟频率。该时钟为所有ADC所共有。

00:PCLK2    2分频

01:PCLK2    4分频

10:PCLK2    6分频

11:PCLK2    8分频     STM32的ADC最大工作频率为36Mhz,而ADC时钟来自于APB2,APB2频率一般是84Mhz,所以一般的我们置ADCPRE=01,即4分频,这样得到ADCPRE频率为21Mhz。

MULTI位:该位用来选择ADC的多重模式,本次实验我们使用的是独立模式,将该5位置0即可

  • 所有 ADC 均独立:
  • 00000:独立模式
  • 00001 到 01001:双重模式,ADC1 和 ADC2 一起工作,ADC3 独立
  • 00001:规则同时 + 注入同时组合模式
  • 00010:规则同时 + 交替触发组合模式
  • 00011:Reserved
  • 00101:仅注入同时模式
  • 00110:仅规则同时模式 仅交错模式
  • 01001:仅交替触发模式
  • 10001 到 11001:三重模式:ADC1、ADC2 和 ADC3 一起工作
  • 10001:规则同时 + 注入同时组合模式
  • 10010:规则同时 + 交替触发组合模式
  • 10011:Reserved
  • 10101:仅注入同时模式
  • 10110:仅规则同时模式 仅交错模式
  • 11001:仅交替触发模式

7.3 ADC采样时间寄存器:ADC_SMPR1和ADC_SMPR2

这两个寄存器用于设置通道0~18的采样时间,每个通道占用3个位

ADC采样时间寄存器:ADC_SMPR1(ADC sample time register 1)

ADC采样时间寄存器:ADC_SMPR2(ADC sample time register 2)

采样时间通俗的讲就是收集模拟量的时间,为了保证转换后的数字量更加精准,采样时间通常设置的尽量长一些。由此带来的负面影响会降低ADC的转换效率。

        ADC转换时间计算:=采样时间+12个周期

7.4 ADC规则序列寄存器:ADC_SQRx(x取值1~3)

ADC规则序列寄存器1:ADC_SQR1(ADC regular sequence register 1)

L位:规则通道序列长度

0000:1次转换

0001:2次转换

……

1111:16次转换

SQx位:分别对应规则序列中的第x次转换(x取值13 14 15 16)其余的1~12分别位于ADC规则序列寄存器2和3中

7.5 ADC规则数据寄存器:ADC_DR

ADC规则数据寄存器:ADC_DR(ADC regular data register)

DATA位: 规则数据位,这些位为只读,它们包括来自规则通道的转换结果。

注意:ADC转换完成后的数字量会存储在该寄存器中,且该寄存器的存储值受ADC_CR2的ALIGN位设置的左对齐还是右对齐控制,所以在读取时需要特别注意。

7.6 ADC状态寄存器:ADC_SR

ADC状态寄存器:ADC_SR(ADC status register)

EOC位: 通过该位来决定是否此次规则通道的AD转换已完成,如果该位为1,则表示转换已经完成了,这时就可以从ADC_DR中读取转换结果,否则等待转换完成。

8. 库函数配置ADC1的通道5进行AD转换 

1. 开启PA口时钟和ADC1时钟,设置PA5为模拟输入

STM32F407ZG的ADC12通道IN5位于引脚PA5上,所以我们要使能GPIOA时钟和ADC1时钟。

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);     //使能GPIOA时钟 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);       //使能ADC1时钟 

注意:对于IO口复用的ADC我们要设置模式为模拟输入,而不是复用功能。

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;      //模拟输入 

2. 设置ADC的通用控制寄存器CCR,配置ADC输入时钟分频,模式为独立模式

在库函数中, 初始化CCR寄存器是通过调用ADC_CommonInit来实现的;

typedef struct
{uint32_t ADC_Mode;              //ADC模式 通过ADC_CR1:DUALMOD位来配置                                                 uint32_t ADC_Prescaler;              //ADC预分频值                       uint32_t ADC_DMAAccessMode;           //DMA模式禁止或者使能相应的DMA模式uint32_t ADC_TwoSamplingDelay;        //ADC两个采样阶段之间的延迟周期数
}ADC_CommonInitTypeDef;第一个参数ADC_Mode:设置独立模式还是多重模式
第二个参数ADC_Prescaler:设置ADC预分频器,这里设置时一定保证ADC1的时钟频率不超过36MHz
第三个参数ADC_DMAAccessMode:DMA模式禁止或者使能相应的DMA模式
第四个参数ADC_TwoSamplingDelay:设置ADC两个采样阶段之间的延迟周期数

void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) 

ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;     //独立模式 

ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;    //ADC预分频值

ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;   //ADC的DMA模式禁止或者使能相应DMA模式

ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; 

3. 初始化ADC1参数,设置ADC1的转换分辨率,转换方式,对齐方式,以及规则序列等相关信息

void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)  //初始化ADC函数

typedef struct
{uint32_t ADC_Resolution;         //ADC分辨率                                        FunctionalState ADC_ScanConvMode;     //ADC扫描多通道或者ADC单通道模式选择  通过ADC_CR1的SCAN位来配置FunctionalState ADC_ContinuousConvMode;   //ADC单次转换或者连续转换选择 通过ADC_CR2的CON位来配置uint32_t ADC_ExternalTrigConvEdge;      //ADC转换触发信号范围选择uint32_t ADC_ExternalTrigConv;          //ADC外部触发转换模式选择  通过ADC_CR2的EXTTRIG和EXTSEL位来配置uint32_t ADC_DataAlign;                 //ADC数据寄存器对齐格式uint8_t  ADC_NbrOfConversion;           //ADC采集通道数
}ADC_InitTypeDef;第一个参数ADC_Resolution:设置ADC转换分辨率
第二个参数ADC_ScanConvMode:设置是否打开扫描模式
第三个参数ADC_ContinuousConvMode:设置时单次转换模式还是连续转换模式
第四个参数ADC_ExternalTrigConvEdge:设置外部通道的触发使能和检测方式
第五个参数ADC_ExternalTrigConv:设置ADC外部触发转换模式
第六个参数ADC_DataAlign:设置数据对齐方式  是左对齐还是右对齐
第七个参数ADC_NbrOfConversion:设置规则序列的长度   单次转换

ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式 

ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式 

ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换 

ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //禁止触发检测,使用软件触发 

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐

ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 

ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化

4. 开启AD转换器

开启AD转换器通过ADC_CR2寄存器控制

ADC_Cmd(ADC1, ENABLE);//开启AD转换器

5. 读取ADC值

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

                                                                                                                                                                              // 设置规则序列通道及采样周期

ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_480Cycles );   //规则序列中的第一个转换,采样周期设置为480

ADC_SoftwareStartConvCmd(ADC1);          //使能指定的ADC1的软件转换启动功能 

ADC_GetConversionValue(ADC1);       //获取转换ADC转换结果数据

FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG)    //获取AD转换的状态信息函数

        ag.  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束 

9. 实验程序

该实验需要用杜邦线将PA5引脚接到GND或者3.3V上,测其电压原始值和转化后的值,切记不能接5.5V,会损坏开发板的ADC;

9.1 main.c

#include "stm32f4xx.h"
#include "delay.h"
#include "usart.h"
#include "LED.h"
#include "lcd.h"
#include "usmart.h"
#include "Key.h"
#include "ADC.h"//LCD状态设置函数
void led_set(u8 sta)//只要工程目录下有usmart调试函数,主函数就必须调用这两个函数
{LED1=sta;
}
//函数参数调用测试函数
void test_fun(void(*ledset)(u8),u8 sta)
{led_set(sta);
}int main(void)
{u16 adcx;float temp;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);delay_init(168);uart_init(115200);LED_Init();LCD_Init();Adc_Init();POINT_COLOR=RED;LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");LCD_ShowString(30,70,200,16,16,"ADC TEST");LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(30,110,200,16,16,"2023/20/23");POINT_COLOR=BLUE;LCD_ShowString(30,130,200,16,16,"ADC1_CH5_VAL:");LCD_ShowString(30,150,200,16,16,"ADC1_CH5_VOL:0.000V");  //显示小数点while(1){adcx=Get_Adc_Average(ADC_Channel_5,20);//adc通道5,取20次平均值LCD_ShowxNum(134,130,adcx,4,16,0); //显示ADC采样后的原始值temp=(float)adcx*(3.3/4096);  //获取计算后带小数的实际电压值,如3.1111adcx=temp;  //赋值整数部分给adcxLCD_ShowxNum(134,150,adcx,1,16,0);//显示电压值的整数部分temp=temp-adcx; //把已经显示的整数部分去掉,留下小数部分 3.1111-3=0.1111temp=temp*1000;//把小数部分乘以1000,变成整数打印出来,乘以1000相当于保留3位小数,乘以10000相当于保留四位小数LCD_ShowxNum(150,150,temp,3,16,0x80); //显示小数部分LED0=!LED0;delay_ms(250);}
}

9.2 ADC.c

#include "stm32f4xx.h"
#include "ADC.h"
#include "delay.h"//初始化ADC
void Adc_Init(void)
{RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);// 使能ADC1时钟//初始化ADC1通道5 IO口GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;  //模式为模拟输入GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;  //PA5 通道5GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL; //不带上下拉GPIO_Init(GPIOA,&GPIO_InitStructure);RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);   //ADC1复位RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);    //复位结束//初始化CCR通用控制寄存器配置ADC_CommonInitTypeDef ADC_CommonInitStructure;ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled; //DMA失能ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;  //独立模式ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;  //预分频值设置ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间延迟5个时钟ADC_CommonInit(&ADC_CommonInitStructure);//初始化ADC1相关参数ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;  //关闭连续转换ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;  //右对齐ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None; //禁止触发检测,使用软件触发ADC_InitStructure.ADC_NbrOfConversion=1;  //1个转换在规则序列中ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;  //12位模式ADC_InitStructure.ADC_ScanConvMode=DISABLE; //非扫描模式ADC_Init(ADC1,&ADC_InitStructure); //ADC初始化ADC_Cmd(ADC1,ENABLE);   //开启AD转换器
}
//获取ADC值
//ch:通道值 0~16
//返回值:转换结果
u16 Get_Adc(u8 ch)
{ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_480Cycles);//设置ADC规则组通道,一个序列,采样时间480ADC_SoftwareStartConv(ADC1);//使能指定的ADC1的软件转换启动功能while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//读取状态寄存器的状态位EOC,等待转换结束return ADC_GetConversionValue(ADC1);//返回最近一次的ADC1规则组的转换结果
}
//获取通道ch的转换值,取times次,然后平均
//ch:通道编号  times:获取次数
//返回值:通道ch的times次转换结果平均值
u16 Get_Adc_Average(u8 ch,u8 times)
{u32 temp_val=0;u8 t;for(t=0;t<times;t++){temp_val=temp_val+Get_Adc(ch); //取times次通道值进行求和delay_ms(5);}return temp_val/times; //返回平均值
}

9.3 ADC.h

#ifndef _ADC__H_
#define _ADC__H_void Adc_Init(void);
u16 Get_Adc(u8 ch);
u16 Get_Adc_Average(u8 ch,u8 times);#endif

STM32F4_模数转换器(ADC)详解相关推荐

  1. STM32 ADC详解

    目录 01.ADC简介 02.STM32的ADC外设 03.STM32ADC框图讲解 04.触发源 05.转换周期 06.数据寄存器 07.中断 08.电压转换 09.电路图设计 10.代码设计 01 ...

  2. 【GD32】从0开始学GD32单片机(13)—— ADC模数转换器外设详解+PS2遥杆例程

    目录 简介 自校准功能 可编程的采样时间 外部触发 规则组和注入组 转换模式 单次转换模式 连续转换模式 扫描转换模式 间断转换模式 注入通道管理 自动注入 触发注入 同步模式 规则并行模式 注入并行 ...

  3. 【STM32】ADC详解

    00. 目录 文章目录 00. 目录 01. ADC简介 02. ADC主要特性 03. ADC功能说明 04. ADC开关控制 05. ADC时钟 06. 通道选择 07. 转换模式 08. 时序图 ...

  4. STM32开发 -- ADC详解

    如需转载请注明出处:https://blog.csdn.net/qq_29350001/article/details/89498527 最近项目中有用到ADC,正好来做一下总结. 一.ADC简介 A ...

  5. STM32—ADC详解

    1.ADC简介 STM32F103 系列最少都拥有 2 个 ADC,我们选择的 STM32F103RCT 包含有 3 个 ADC,STM32的最大转换速率为1Mhz,也就是转换时间为1us,除此之外, ...

  6. MSP430单片机的ADC详解

    ADC模数转化器是430单片机的重要的片上外设,而且在开发当中也常常需要用到ADC,下面根据使用手册结合我个人的学习感悟,总结一下430的ADC的使用要点. 430的ADC的特点: 1.是一个12位的 ...

  7. STM32F4_外部中断详解(EXTI)

    目录 1. EXTI 是什么? 2. EXTI主要特性 3. EXTI框图 3.1 外部中断/事件线映射 4. EXTI寄存器 4.1 中断屏蔽寄存器 EXTI_IMR 4.2 事件屏蔽寄存器 EXT ...

  8. ADC(模数转换)详解

    ADC(模数转换)详解 前言 ADC的定义 ADC简介 ADC特性 ADC时钟 工作模式 单通道单次转换练习 多通道扫描模式单次转换 前言 在STM32微控制器中,ADC代表模数转换器(Analog- ...

  9. adc网络语什么意思_王者荣耀adc是什么意思详解 专业术语大全

    王者荣耀adc是什么意思详解 专业术语大全.大家在游戏中经常会碰到一些小术语,比如最常见的ADC.AP以及AD等等,有很多小萌新不知道这些术语是什么意思,下面小编就来详细的为大家说明这个问题. ADC ...

最新文章

  1. sql server密码过期,通过SSMS修改策略报错
  2. 为什么运营商玩不转物联网?
  3. Linux安装Elasticsearch+Kibana(7.10.2)
  4. #pragma comment(linker,/SECTION:shared,RWS)
  5. oracle datafilereuse,Oracle 数据文件 reuse 属性 说明
  6. xp中mysql优化_XP加速技巧大盘点 看看那个最实用
  7. export TERM=xterm导致终端reset命令失效
  8. ASP.NET Core 中的那些认证中间件及一些重要知识点
  9. nssl1519-背包签到题【数论】
  10. http://ju.outofmemory.cn/entry/307891---------TICK
  11. 小米为什么拆分红米? | 畅言
  12. OSPF路由控制原理与实验
  13. 摩尔庄园手游服务器链接不稳定,摩尔庄园手游公测常见问题解决方法一览
  14. 『中文、英文词频统计分析软件』免费工具分享
  15. Redmine 父子问题树形结构显示技巧
  16. linux下的触摸板关闭
  17. 用fail2ban阻止ssh暴力破解root密码
  18. Java并发编程之volatile
  19. easyuefi只能在基于uefi启动的_只需2个命令,就能将win10 BIOS启动方式转换为UEFI,你见过吗!...
  20. 南京网预赛 11 BY bly

热门文章

  1. 2020 BNUZ 新生现场赛 题解
  2. 谁是卧底线下发牌器微信小程序源码下载
  3. FusionGAN:VIIF
  4. 【机器学习】聚类学习笔记+西瓜书数据集K-means实现
  5. KWP2000协议学习笔记(二)
  6. 消息队列——kafka基础
  7. 电工基础知识分享(四):图文并茂,史上最全万用表使用手册
  8. html仿微信朋友圈图片浏览,模仿微信朋友圈 图片浏览 h5 html5 js
  9. 快速入门产品经理,需要做的是什么?
  10. oracle支持几国语言,Oracle数据库多语言支持