ADC基本原理与应用

参考资料
正点原子STM32FX开发板
《STM32FX开发指南》-第X章 ADC实验
STM32FXxx官方资料:
《STM32FX中文参考手册》-第X章 模数转换(ADC)

笔记基于正点原子官方视频
视频连接https://www.bilibili.com/video/BV1Wx411d7wT?p=71&spm_id_from=333.1007.top_right_bar_window_history.content.click
如有侵权,联系删除

一、ADC基本原理

1.ADC简介

Analog-to-Digital Converter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。
典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号。

2.STM32 ADC特点

  • 可配置12位、10位、8位或6位分辨率
  • 在转换结束、注入转换结束以及发生模拟看门狗或溢出事件时产生中断
  • 单次和连续转换模式
  • 用于自动将通道0转换为通道“n”的扫描模式
  • 数据对齐以保持内置数据一致性
  • 可独立设置各通道采样时间
  • 外部触发器选项,可为规则转换和注入转换配置极性
  • 不连续采样模式
  • 双重/三重模式(具有2个或更多ADC的器件提供)
  • 双重/三重ADC模式下可配置的 DMA数据存储
  • 双重/三重交替模式下可配置的转换间延迟
  • ADC转换类型(参见数据手册)
  • ADC电源要求:全速运行时为2.4V到3.6 V,慢速运行时为1.8 v
  • ADC输入范围:VREF-≤VIN ≤VREF+
  • 规则通道转换期间可产生 DMA请求

3.STM32芯片的ADC控制器数量 和通道数量

4.STM32系列ADC外部通道和引脚对应关系

总结(针对正点原子开发板使用芯片): 144脚芯片因为带PF脚,所以多8个通道,为24个外部通道。小于144脚芯片只有16个外部通道。

5.ADC框图


6.ADC引脚

7.ADC测量电压范围

VREF- ≤ VIN ≤ VREF+
通常情况下,VSSA 和 VREF-接GND, VREF+和
VDDA 接 3.3V,则ADC 的输入电压范围为: 0~3.3V。

测量更大范围电压(例如:-N<Vin<+N)
① 先加法:Vin+N之后,测量输入范围为:Vi1=0~2N
② 再乘法:输入范围缩小为0~3.3V。2N/x=3.3,乘法因子x=3.3/2N
③ 最后换算。
或者先乘法,再加法,都是可以的。
① 先乘法:N*x=3.3/2=1.65,x=1.65/N
② 再加法:加上1.65。
③ 最后换算。

1)实现思路1

2)实现思路2

8.STM32通道组

① **规则通道组:**相当正常运行的程序。最多16个通道。规则通道和它的转换顺序在ADC_SQRx寄存器中选择,规则组转换的总数应写入ADC_SQR1寄存器的L[3:0]中
② **注入通道组:**相当于中断。最多4个通道。注入组和它的转换顺序在ADC_JSQR寄存器中选择。注入组里转化的总数应写入ADC_JSQR寄存器的L[1:0]中


9.ADC触发方式(软件触发、外部触发)

1)ADC软件触发方式:ADC_CR2

位0: ADON:A/D转换器开启/关闭(A/D Converter ON /OFF)
此位由软件置1和清零。
注:0:禁止ADC转换并转至掉电模式
1:使能ADC
**位22 ** JswSTART:开始转换注入通道(Start conversion of injected channels)
转换开始后,软件将该位置1,而硬件将该位清零。
0:复位状态
1:开始转换注入通道
注:该位只能在ADON =1时置1,否则不会启动转换。
位30: swSTART:开始转换常规通道(Start conversion of regular channels)
通过软件将该位置1可开始转换,而硬件会在转换开始后将该位清零。0:复位状态
1:开始转换常规通道
注:该位只能在ADON=1时置1,否则不会启动转换。

2)ADC外部触发方式:规则通道

3)ADC外部触发方式:注入通道

4)ADC外部触发极性

10.ADC中断

11.ADC时钟配置

M3:确保ADC时钟不要超过14MHz。可以设置分频系数为4、6、8 。
M4/M7:确保ADC时钟不要超过36MHz。可以设置分频系数为6、8 。

12.ADC分辨率(ADC_CR1)

13.ADC采样时间

14.ADC数据对齐方式


15.ADC转换结果

规则通道数据寄存器ADC_DR
注入通道数据寄存器ADC_JDRx

16.ADC数据计算方法

如果分辨率为12,采集范围为0~3.3V。
那么ADC转换数据范围为:0~(2^12-1),即0~4095
如果采集的数字量为X,那么输入电压为Y=3.3/(2^12)*X

17.STM32的ADC模式

STM32的ADC的各通道可以单次,连续,扫描或者间断模式执行。

1)单次转换模式

在单次转换模式下,ADC执行一次转换。CONT位为О时,可通过以下方式启动此模式;

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

完成所选通道的转换之后:

  • 如果转换了规则通道;

    • 转换数据存储在16位ADC_DR寄存器中
    • EOC(转换结束)标志置1
    • EOCIE位置1时将产生中断
  • 如果转换了注入通道;

    • 转换数据存储在16位ADC_JDR1寄存器中
    • JEOC(注入转换结束)标志置1
    • JEOCIE位置1时将产生中断
      然后,ADC停止。
2)连续转换模式

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

  • 如果转换了规则通道组:

    • 上次转换的数据存储在16位ADC_DR寄存器中
    • EOC(转换结束)标志置1
    • EOCIE位置1时将产生中断
      无法连续转换注入通道。连续模式下唯一的例外情况是,注入通道配置为在规则通道之后自动转换(使用JAUTO位),请参见自动注入一节。
3)扫描模式

此模式用于扫描一组模拟通道。

通过将ADC_CR1寄存器中的SCAN位置1来选择扫描模式。将此位置1后,ADC会扫描在ADC_SQRx寄存器(对于规则通道〉或ADC_JSQR寄存器(对于注入通道)中选择的所有通道。为组中的每个通道都执行一次转换。每次转换结束后,会自动转换该组中的下一个通道。如果将CONT位置1,规则通道转换不会在组中最后一个所选通道处停止,而是再次从第一个所选通道继续转换。

如果将DMA位置1,则在每次规则通道转换之后,均使用直接存储器访问(DMA)控制器将转换自规则通道组的数据(存储在ADC_DR寄存器中)传输到SRAM。

在以下情况下,ADC_SR寄存器中的EOC位置1:
- 如果EOCS位清零,在每个规则组序列转换结束时
- 如果 EOCS位置1,在每个规则通道转换结束时
从注入通道转换的数据始终存储在ADC_JDRx寄存器中。

ADC_CR1控制寄存器1

二、ADC相关寄存器

1.ADC_CR1寄存器

在扫描模式下,由ADC_SQRx或者ADC_JSQRx寄存器选中的通道被转换。如果设置了EOCIE或者JEOCIE为0,在最后一个通道转换完毕后才会产生EOC或者JEOC中断。

2.ADC_CR2寄存器



3.ADC_SMPR1寄存器

4.ADC_SMPR2寄存器

5.ADC_SQR1/SQR2/SQR3规则序列寄存器

6.ADC_JSQR注入系列寄存器

7.ADC_DR规则通道数据寄存器

8.ADC_JDR注入通道数据寄存器

6.ADC_SR状态寄存器

三、ADC相关HAL库函数

1.HAL库文件

stm32f4xx_hal_adc.c/stm32f4xx_hal_adc.h
位置:工程文件 - HALLIB - stm32f4xx_hal_adc.c/stm32f4xx_hal_adc.h
stm32f4xx_hal_adc_ex.c/stm32f4xx_hal_adc_ex.h
位置:工程文件 - HALLIB - stm32f4xx_hal_adc_ex.c/stm32f4xx_hal_adc_ex.h

2.常用HAL库函数一(通用函数/常规通道)

  • HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc);
    ADC初始化函数,设置ADC的基本参数(如采样时间、分辨率、数据对其方式等)

  • void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc);
    ADC回调函数(弱函数),我们可以根据需要来改写(改写内容:时钟使能IO口的配置等)。

  • HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc);
    开启ADC(软件层面)

  • HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc);
    关闭ADC(软件层面)

  • HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout);
    等待转换结束(判断EOC位是否发出结束指令)

  • HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc);
    启动ADC的同时开启中断

  • HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc);
    启动ADC的同时关闭中断

  • HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig);
    ADC通道配置(规则序列)

  • uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc);

3.常用HAL库函数二(中断相关)

  • HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc);

  • HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc);

  • void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc);

  • void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);

  • void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc);

  • void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc);

  • void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc);

4.常用HAL库函数三(注入模式/多重模式)

  • HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc);

  • HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc);

  • HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout);

  • uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef* hadc, uint32_t InjectedRank);

  • HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);

  • HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc);

  • uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef* hadc);

  • hadcHAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc,ADC_InjectionConfTypeDef* sConfigInjected);

  • HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef* hadc, ADC_MultiModeTypeDef* multimode);

4.ADC初始化函数 HAL_ADC_Init

函数体:HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc);
位置:工程文件 - HALLIB - stm32f4xx_hal_adc.c

函数体只有一个,时函数体指针,查看定义如下:

typedef struct
{
ADC_TypeDef                                 *Instance;
ADC_InitTypeDef                             Init;
__IO uint32_t                                   NbrOfCurrentConversionRank;
DMA_HandleTypeDef                   *DMA_Handle;
HAL_LockTypeDef                          Lock;
__IO HAL_ADC_StateTypeDef       State;
__IO uint32_t                                    ErrorCode;
}ADC_HandleTypeDef;

ADC初始化结构体ADC_InitTypeDef定义:

typedef struct
{uint32_t ClockPrescaler;                 //预分频系数uint32_t Resolution;                   //分辨率:12/10/8/6 uint32_t DataAlign;                      // 对齐方式uint32_t ScanConvMode;           //扫描模式uint32_t EOCSelection;                //EOC中断uint32_t ContinuousConvMode;     //连续转换模式uint32_t DMAContinuousRequests;     //关闭/打开DMA请求uint32_t NbrOfConversion;                   //规则序列转换数uint32_t DiscontinuousConvMode;        //不连续采样模式uint32_t NbrOfDiscConversion;              // 不连续采用模式通道数uint32_t ExternalTrigConv;                         //触发方式uint32_t ExternalTrigConvEdge;                 //触发极性
}ADC_InitTypeDef;

5.ADC规则通道配置函数HAL_ADC_ConfigChannel

函数体:HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig)

typedef struct
{uint32_t Channel;          //通道uint32_t Rank;              //序列号uint32_t SamplingTime; //采样时间uint32_t Offset;              // 转换结果偏移量:注入通道
}ADC_ChannelConfTypeDef;

6.开启ADC转换

HAL_ADC_Start(&ADC1_Handler);

7.等待转换完成

HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)

8.获取转换结果(规则通道)

uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc);

9.正点原子给的adc.c文档(供参考)

#include "adc.h"
#include "delay.h"ADC_HandleTypeDef ADC1_Handler;//ADC句柄//初始化ADC
//ch: ADC_channels
//通道值 0~16取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
void MY_ADC_Init(void)
{ ADC1_Handler.Instance=ADC1;ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4;   //4分频,ADCCLK=PCLK2/4=90/4=22.5MHZADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B;             //12位模式ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //右对齐ADC1_Handler.Init.ScanConvMode=DISABLE;                      //非扫描模式ADC1_Handler.Init.EOCSelection=DISABLE;                      //关闭EOC中断ADC1_Handler.Init.ContinuousConvMode=DISABLE;                //关闭连续转换ADC1_Handler.Init.NbrOfConversion=1;                         //1个转换在规则序列中 也就是只转换规则序列1 ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;             //禁止不连续采样模式ADC1_Handler.Init.NbrOfDiscConversion=0;                     //不连续采样通道数为0ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START;       //软件触发ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发ADC1_Handler.Init.DMAContinuousRequests=DISABLE;             //关闭DMA请求HAL_ADC_Init(&ADC1_Handler);                                 //初始化
}//ADC底层驱动,引脚配置,时钟使能
//此函数会被HAL_ADC_Init()调用
//hadc:ADC句柄
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_ADC1_CLK_ENABLE();            //使能ADC1时钟__HAL_RCC_GPIOA_CLK_ENABLE();          //开启GPIOA时钟GPIO_Initure.Pin=GPIO_PIN_5;            //PA5GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}//获得ADC值
//ch: 通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
//返回值:转换结果
u16 Get_Adc(u32 ch)
{ADC_ChannelConfTypeDef ADC1_ChanConf;ADC1_ChanConf.Channel=ch;                                   //通道ADC1_ChanConf.Rank=1;                                       //第1个序列,序列1ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //采样时间ADC1_ChanConf.Offset=0;                 HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);        //通道配置HAL_ADC_Start(&ADC1_Handler);                               //开启ADCHAL_ADC_PollForConversion(&ADC1_Handler,10);                //轮询转换return (u16)HAL_ADC_GetValue(&ADC1_Handler);           //返回最近一次ADC1规则组的转换结果
}
//获取指定通道的转换值,取times次,然后平均
//times:获取次数
//返回值:通道ch的times次转换结果平均值
u16 Get_Adc_Average(u32 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;
}

34.ADC基本原理与配置相关推荐

  1. 带你理解交换机基本原理和配置

    带你理解交换机基本原理和配置 1. 交换机的定位 交换机在TCP/IP五层模型中属于数据链路层 主要是生成和传输数据帧 在网络中相邻节点之间,实现可靠的数据通信,并且控制传输速率. 2. 以太网(MA ...

  2. STM32H743Nucleo ADC使用DMA配置无法读取数据的问题及解决

    STM32H743Nucleo ADC使用DMA配置无法读取数据的问题及解决 一.对ADC进行配置 二.对程序进行修改 三.程序执行结果 四.问题解决 一.对ADC进行配置 使用STM32H743Nu ...

  3. 【计算机网络】(2)网络传输介质+交换机的基本原理与配置+vlan+trunk

    目录 一.网络传输介质 1.1 双绞线(网线) 1.1.1 双绞线的连接规范: 1.1.2 标准网线和交叉线 1.1.3 制作双绞线跳线 1.2 光纤 二.交换机的基本原理与配置 2.1 数据链路层 ...

  4. STM32——ADC基本原理

    ADC:Analog-to-Digital Converter的缩写,指模/数转换器或者模拟/数字转换器,是指将连续变量的模拟信号转换位离散的数字信号的器件.典型的模拟数字转换器将模拟信号转换为表示一 ...

  5. 深入浅出学习透析Nginx服务器的基本原理和配置指南「负载均衡篇」

    负载均衡 之前的章节内容中[深入浅出学习透析Nginx服务器的基本原理和配置指南「初级实践篇 」]和 [深入浅出学习透析Nginx服务器的基本原理和配置指南「进阶实践篇」],我们采用的代理仅仅指向一个 ...

  6. OSPF的基本原理及配置命令

    一.OSPF OSPF基本原理以及邻居关系建立过程 OSPF是一种链路状态型路由选择协议.它依靠5种(Hello, DBD, LSR, LSU and LSAck)不同种类的数据包来识别.建立和维护邻 ...

  7. ADC基本原理与STM32F030ADC应用

    一.什么是ADC 1.ADC的定义 ADC(Attack Damage Carry/Core)是普通攻击持续输出核心的简称,是一场游戏中伤害输出核心之一(最主要是能以普通攻击来造成持续伤害输出,以免输 ...

  8. 【ENSP模拟器】链路技术(HCNA)——Smart Link的基本原理和配置实例

    目录 Smart Link的配置实例 1.配置思路 2.配置步骤 (1)配置SwitchA(LSW3) (2)配置SwitchA(LSW3) (3)配置SwitchA(LSW3) (4)配置Switc ...

  9. 深入浅出学习透析 Nginx 服务器的基本原理和配置指南「运维操作实战篇」

    Nginx前提回顾 Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性: Web服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效 ...

  10. stm32f103 adc采集 程序配置

    这个例程是采集电压adc值 对于通道几是如何选择的: 这里在adc初始化函数中,设置通道几的采样率只是设置要使用的通道几,并不是选择用通道几,真正的选择用通道几是在Get_Adc()AD采样这个函数中 ...

最新文章

  1. 怎样删除usb计算机连接网络打印机驱动,惠普激光打印机安装驱动时报“跟这台计算机连接的一个 USB 设备运行不正...
  2. babel css3新特性_2018年面试前端总结
  3. python经典类新式类_Python新式类与经典类(旧式类)的区别
  4. 如何给ppt编辑页码_拒绝千篇一律:Word插入“侧边”页码,让文档别具一格!...
  5. url get参数 php,怎么取得Url中Get参数
  6. 信息学奥赛一本通 1015:计算并联电阻的阻值 | OpenJudge NOI 1.3 10
  7. (转)Spring的bean管理(注解方式)
  8. adb命令启动某个action_Android adb shell启动应用程序的方法
  9. Android Volley 源码解析(三),图片加载的实现
  10. ORBSLAM3整体框架
  11. MCAFEE卸载软件测试初学者,迈克菲卸载软件怎么用(手把手教你彻底卸载干净)...
  12. 常用的正则字母大小写转换
  13. kotlin 中关键字 lateinit
  14. C#基础(10)——飞行棋游戏
  15. ARM嵌入式开发总结
  16. 短视频头部效应加剧,秒拍整军三月强势归来
  17. linux scp 详解
  18. MySQL一行变多行,多行变一行
  19. 线切割泡沫的产生用线切割工作液消泡剂到底有那些效果
  20. MinIO+NPS+DDNS+旧笔记本搭建私有图床

热门文章

  1. 计算适应度函数(目标函数)(单目标)
  2. android 获取刘海高度,不同刘海屏幕获取安全高度
  3. VTK学习笔记(三十四)VTK简介
  4. uniapp实现打印PDF文件
  5. 搬: 含有对象成员指针的类的对象成员指针初始化问题
  6. c++ 专题 2 面向对象:常量成员函数
  7. Postgresql的使用-1 创建数据库
  8. 高清录播系统与流媒体服务器,来同品牌全高清录播系统方案
  9. 云计算现在好就业吗?薪资怎么样?
  10. qt 设计师界面 图片_如果没有设计界面,设计师会发生什么?