本文使用的是APM32E103作为示例的, STM32F/E以及APM32F等系列同样适用。

一、ADC及其通道

ADC1:最多16个外部通道,2个内部通道。内部通道分别是温度传感器和参考电压

①:温度传感器内部连接 ADC_IN16 通道,传感器产生的电压随着温度线性变化,可通过 ADC 获取转 换的电压值换算成温度;

②:参考电压内部连接 ADC_IN17 通道,可通过 ADC 获取该 V REFINT ;V REFINT 为 ADC提供稳定的电压输出。

ADC2:最多16个外部通道;

ADC3:最多8个外部通道。

内置 3 个 ADC采集精度为 12 位,各通道 A/D 转换模式有单次、连续、扫描或间断,ADC 转换结果可以左对齐或右对齐存储在 16 位数据寄存器中;支持模拟看门狗,支持 DMA。

二、ADC转换模式

MCU内部有3个ADC,每个ADC有多个通道,可以根据将转换模式可以分为独立ADC和双重ADC,所以可以将ADC转换模式分为以下几类:

1.单ADC,单通道

因为只有一个通道所以不用开启扫描模式,也不用使用DMA,所以只需要选择使用单次转换模式还是连续转换模式就可以了,不使用外部触发。

(1)单次转换:对单个通道而言之只对此通道进行一次转换,对多通道而言只对此组通道进行一次转换,转换时序如下图

图 单次转换时序

(2)连续转换:模式对单通道而言之对此通道进行连续转换

图 连续转换时序

2.单个ADC,多通道

单ADC多通道,要使用扫描模式,不使用外部触发,软件触发,ADC 转换结果数据使用 DMA 传输到存储器。

(1)DMA:规则通道转换结束后产生 DMA 请求,可以将转换的数据结果从 ADC_REGDATA寄存器传输到存储器中。只有 ADC1 和 ADC3 可以产生 DMA 请求,ADC2 的转换结果通过 ADC1 的DMA 功能传输。

(2)规则通道:由 16 个通道组成,转换数据存储到ADC_REGDATA中,单 ADC 模式下只使用低16 位存储转换数据,双 ADC 模式下低 16 位存储 ADC1 的转换数据,高 16 位存储 ADC2 的转换数据,由于规则通道最多有 16 个,但规则数据寄存器只有 1 个,所以在多通道转换时将产生数据覆盖问题,此时就需要使用 DMA 传输

(3)注入通道:由 4 个通道组成,有四个 32 位的寄存器,其低 16 位有效,高 16 位保留。注入通道最多有 4 个,注入数据寄存器也有四个,在多通道转换时不会发生数据覆盖问题,数据对齐方式为左对齐和右对齐

(4)内部输入通道:

①:温度传感器用来测量芯片内部的温度,选择 ADC1_IN16 输入通道

②:内部参考电压 V REFINT 用来提供一个稳定的电压输出给 ADC,选择 ADC1_IN17 输入通道

(5)扫描模式:该模式适用于一组通道,相当于在一组通道的每个通道上进行单次转换(扫描模式的注入触发时序图可查阅数据手册)。

图 扫描模式时序

(6)间断模式:该模式适用于一组通道,相当于对一组通道里的多个通道进行连续转换。

图 规则触发间断模式时序

对于规则组,该模式通过配置寄存器 ADC_CTRL1 的 REGDISCEN 位启动,启动后进行一次 n 个通道的短序列转换(n

图注入触发间断模式时序

对于注入组,该模式通过配置寄存器 ADC_CTRL1 的 INJDISCEN 位启动,启动后按序列寄存器配置顺序进行一个通道的转换,通过软件控制或外部触发源可以按顺序启动下一个通道的转换,直到该组通道全部转换完成,EOCFLG 位和INJEOCFLG 位置 1

3.双重 ADC 模式、一组 模式、一组通道转换模式

两个或两个以上 ADC 模块的产品,使用双重 ADC 模式,ADC1 默认为主ADC,其他默认为从 ADC,通过配置 ADC1_CTRL1 寄存器中 DUALMCFG[2:0]位设置双 ADC 模式。当配置由外部事件触发时,需要设置为仅触发主 ADC,然后配置从 ADC 为软件触发。(主和从的外部触发必须同时发生)在本文中就不过多的赘述了,想了解的小伙伴可以查阅数据手册。

三、标准库软件配置

使用DMA采集ADC1 的6个通道,规则通道

1.时钟配置

static void RCM_Configuration(void)
{RCM_ConfigADCCLK(RCM_PCLK2_DIV_4);//ADCCLK = PCLK2/4 RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);//Enable ADC1 and DMA clockRCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA1);
}

2.中断配置

static void NVIC_Configuration(void)
{NVIC_EnableIRQRequest(DMA1_Channel1_IRQn, 0, 0);
}

3.DMA初始化配置

static void DMA_init(void)
{DMA_Config_T    DMA_ConfigStruct;DMA_Reset(DMA1_Channel1);DMA_ConfigStruct.peripheralBaseAddr = (uint32_t)&ADC1->REGDATA;DMA_ConfigStruct.memoryBaseAddr = (uint32_t)&DST_Buffer;DMA_ConfigStruct.dir = DMA_DIR_PERIPHERAL_SRC;       //0:从外设到存储器  DMA_ConfigStruct.bufferSize = BUF_SIZE;DMA_ConfigStruct.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;DMA_ConfigStruct.memoryInc = DMA_MEMORY_INC_ENABLE;DMA_ConfigStruct.peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_HALFWORD;DMA_ConfigStruct.memoryDataSize = DMA_MEMORY_DATA_SIZE_HALFWORD;DMA_ConfigStruct.loopMode = DMA_MODE_CIRCULAR;DMA_ConfigStruct.priority = DMA_PRIORITY_HIGH;DMA_ConfigStruct.M2M = DMA_M2MEN_DISABLE;DMA_Config(DMA1_Channel1, &DMA_ConfigStruct);
}

4.ADC_GPIO 配置

static void GPIO_Configuration(void)
{GPIO_Config_T configStruct;RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOC);configStruct.pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;configStruct.mode = GPIO_MODE_ANALOG;GPIO_Config(GPIOC, &configStruct);configStruct.pin = GPIO_PIN_2|GPIO_PIN_3;configStruct.mode = GPIO_MODE_ANALOG;GPIO_Config(GPIOA,&configStruct);
}

5.ADC配置

static void ADC_Init(void)
{ADC_Config_T ADC_configStruct;GPIO_Configuration();ADC_configStruct.mode = ADC_MODE_INDEPENDENT;             //独立模式ADC_configStruct.scanConvMode = ENABLE;                  //扫描模式ADC_configStruct.continuosConvMode = ENABLE;  //连续模式ADC_configStruct.externalTrigConv = ADC_EXT_TRIG_CONV_None;ADC_configStruct.dataAlign = ADC_DATA_ALIGN_RIGHT;ADC_configStruct.nbrOfChannel = 6;ADC_Config(ADC1, &ADC_configStruct);/* ADC1 regular channel configuration */ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_2 , 1, ADC_SAMPLETIME_55CYCLES5);ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_3 , 2, ADC_SAMPLETIME_55CYCLES5);ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_10, 3, ADC_SAMPLETIME_55CYCLES5);ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_11, 4, ADC_SAMPLETIME_55CYCLES5);ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_12, 5, ADC_SAMPLETIME_55CYCLES5);ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_13, 6, ADC_SAMPLETIME_55CYCLES5);ADC_Enable(ADC1);ADC_ResetCalibration(ADC1);//ADC 校准复位while(ADC_ReadResetCalibrationStatus(ADC1));//复位完成ADC_StartCalibration(ADC1);//ADC校准while(ADC_ReadCalibrationStartFlag(ADC1));//校准完成
}

6.开启检测

static void ADC_DMA_Start(void)
{DMA_EnableInterrupt(DMA1_Channel1, DMA_INT_HT);DMA_Enable(DMA1_Channel1);ADC_EnableDMA(ADC1);    ADC_EnableSoftwareStartConv(ADC1);
}

7.ADC_DMA 初始化

在初始化的时候一定要注意,要先初始化DMA,再初始化ADC,否则ADC通道顺序与DMA采集的AD值会发生错乱

void ADC_init(void)
{ADC_Config_T ADC_configStruct;RCM_Configuration();NVIC_Configuration();DMA_init();ADC_Init();ADC_DMA_Start();
}

STM32/APM32 用DMA采集ADC1多通道--标准库相关推荐

  1. STM32从零到一,从标准库移植到HAL库,UART串口1以DMA模式收发不定长数据代码详解+常见问题 一文解析

    前言 本文的参考资料 感谢提供标准库版本的CSDN同学:这两篇文章至少是我看过的最详细的标准库配置DMA版本.而且代码实测稳定能用. STM32 | DMA配置和使用如此简单(超详细)_...| .. ...

  2. STM32读取SHT3x系列温湿度传感器,标准库和HAL库

    STM32读取SHT3x系列(SHT30.SHT31.SHT35)温湿度传感器的数据并显示在0.96寸OLED屏上. 我下面提供两份代码,一份是标准库使用硬件I2C的,另一份是HAL库使用软件模拟II ...

  3. STM32歌唱《孤勇者》(标准库)

    先说一下自己玩两年的单片机的想法吧,玩了大概有两年了,从刚刚开始的不知所措,到现在的成熟,终于还是搞明白了一件事,编程思路,远远比源码更重要,所以,我接下来会给大家完整的介绍,完成此项目的心得,太心酸 ...

  4. STM32使用ADC+DMA进行多通道模拟量采集 (踩坑及傻瓜式解析)

    STM32使用ADC+DMA进行多通道模拟量采集 (踩坑及通俗解析) ​ 利用STM32的片上外设可采集多个模拟量(如传感器数值),并在嵌入式程序中使用.如果只使用了一个通道,用时令ADC转换而后读取 ...

  5. STM32F407 DMA采集多通道ADC

    STM32F407和STM32F103在HAL库使用的时候有较大的差别,同时407取消掉了ADC校准,在使用DMA进行多通道采集时需要打开DMA连续请求:hadc1.Init.DMAContinuou ...

  6. 【STM32学习】(30)STM32实现18B20温度采集(标准库和HAL库实现)

    单片机型号:STM32F103 源码下载链接:(2条消息) STM32实现18B20温度采集(标准库和HAL库实现)-电信文档类资源-CSDN下载 现要求完成温度采集并在串口或液晶屏上显示.我们这里使 ...

  7. stm32 DMA转运ADC多通道

    一.DMA的使用方法 了解概念: 1.单次传输和循环传输:在DMA中源地址中的数据传输之后,如果要关闭DMA再打开才能继续传输.在如果传输玩后自动开始下一次传输,就是循环传输. 2.触发选择:软件触发 ...

  8. 基于STM32的ADC电压采集(DMA传输)

    我最近在写stm32的adc电压采集过程中遇到了一些问题,这些问题或许对stm32初学者入手adc有所帮助. 对adc采集到的数据进行均值滤波处理,新建一个数组ADC_ConvertedValue_1 ...

  9. STM32单片机实现DMA+ADC+UART功能

    突然想测试一下STM32单片机ADC采样速率问题,按照常规方法,可以通过ADC采样,然后将采样值打印出来.但是这种方法在处理和打印数据的时候会占用很多时间,导致处理数据的时间超过了ADC的采样时间.于 ...

最新文章

  1. 宏基因组教程Metagenomics Tutorial (HUMAnN2)
  2. js中用tagname和id获取元素的3种方法
  3. 【学习笔记】mybatis中的缓存介绍和使用
  4. Magento利用input type=”file”上传图片
  5. 20150928所学粗略整理
  6. mysql多主单向环形_mysql多主单向--gt;环形同步_MySQL
  7. html翻转切换div效果,图片翻转效果
  8. 依赖注入与对象间关系
  9. java设计模式—单例模式
  10. app运行租用服务器,app租用服务器
  11. UVa 706 ZOJ 1146 LC-Display
  12. 【 数据结构(C语言)】线性表——链表反转
  13. centos下mysql备份数据库命令_[CentOS]下mysql数据库常用命令总结
  14. Wireshark对京东网站进行抓包
  15. 《深度学习入门-基于Python的理论与实现》第七章带读 -- CNN介绍
  16. 开发公链社群币种钱包系统软件
  17. 通过路由器管理界面刷openwrt
  18. 网络访问:从网络访问此计算机属性增加guest组,workgroup无法访问,详细教您workgroup无法访问如何解决...
  19. ECCV2016 paper list (完整版)
  20. JAVA获取GMT毫秒_关于java:如何获得GMT当前时间?

热门文章

  1. 你以为Shell只是命令行?读懂这篇文,给你的工作赋能
  2. CodeForces - 1144G Two Merged Sequences
  3. 关于华硕笔记本BIOS设置
  4. Re:从零开始的 RTL-SDR 折腾记
  5. 阅读笔记 - 20220401
  6. vim 配置及插件安装管理(超级详细)
  7. 金融分析与风险管理——资本资产定价模型
  8. 软件测试的7个基本原则
  9. SpringBoot导出word模板并动态渲染数据
  10. 计算机管理上移动硬盘显示其他设备,移动硬盘坏了插上之后电脑会显示有新设备接入而且设备运转正常,但我 爱问知识人...