Cubemx与HAL库系列教程|ADC DMA多通道采集详解

什么是ADC

资料源码获取见文末

你以为的ADC

哈哈,开个玩笑,S11 EDG LPL最后的荣光,加油~~~

说起来ADC,先来聊聊模拟信号与数字信号

模拟信号与数字信号简介

  • 模拟信号

模拟电压信号在时间上和幅值上均是连续的信号叫做模拟信号。此类信号的特点是,在一定动态范围内幅值可取任意值。

  • 数字信号

与模拟信号相对应,时间和幅值均离散( 不连续 ) 的信号叫做数字信号。数字信号的特点是幅值只可以取有限个值。

下文引自:

https://baijiahao.baidu.com/s?id=1701463655357562703&wfr=spider&for=pc

通过观察声音的波形我们就会发现:

模拟信号在一段连续的时间范围内可以在任意时间点呈现任意数值,但是这种数值是随着时间连续变化。

数字信号的取值是离散的二进制数,它和具有连续波形的模拟信号所展现出来的东西千差万别。

模拟信号与数字信号如何相互转换

模拟信号一般通过脉码调制PCM的方法量化调制成数字信号,这个动作叫做模数转换。模拟信号会经过采样、量化、编码等一系列的动作最终转化成能被存储介质存储的一串0和1组成的数字信号。

也即是我们本次要介绍的ADC(analogue-to-digital conversion),模数转换。

数字信号也可以还原成模拟信号。这种转化器件简称DAC,基本由即权电阻网络、运算放大器、基准电源和模拟开关组成。

STM32 ADC介绍

上面说了一大堆,还是属于比较基础的介绍,有兴趣的小伙伴可以多多了解下AD转换器构成,实现原理,通信原理相信都学过,PCM编码都忘了吧,哈哈,好巧,我也忘了...

STM32 拥有 1~3 个 ADC(STM32F101/102 系列只有 1 个 ADC),这些 ADC 可以独立使用, 也可以使用双重模式(提高采样率)。

STM32 的 ADC 是 12 位逐次逼近型的模拟数字转换器。它有 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的 A/D 转换可以单次、连续、扫 描或间断模式执行。ADC 的结果可以左对齐或右对齐方式存储在 16 位数据寄存器中。

STM32 的 ADC 最大的转换速率为 1Mhz,也就是转换时间为 1us(在 ADCCLK=14M,采样周期为 1.5 个 ADC 时钟下得到),不要让 ADC 的时钟超过 14M,否则将导致结果准确度下降

  • 转换时间

采样周期最小是 1.5 个,即如果我们要达到最快的采样,那么应该设置采样周期为 1.5 个周期,这里说的周期就是1/ADC_CLK

ADC 的总转换时间跟 ADC 的输入时钟和采样时间有关,其公式如下:

Tconv = 采样时间 + 12.5 个周期

其中 Tconv 为 ADC 总转换时间,当 ADC_CLK=14Mhz 的时候,并设置 1.5 个周期的采样时间,则 Tcovn=1.5+12.5=14 个周期=1us。通常经过 ADC 预分频器能分频到最大的时钟只能是 12M,采样周期设置为 1.5 个周期,算出最短的转换时间为 1.17us

外部的 16 个通道在转换的时候可分为 2 组通道:规则通道组和注入通道组,其中规则通道组最多有 16 路,注入通道组最多有 4 路

  • 规则通道组:

从名字来理解,规则通道就是一种规规矩矩的通道,类似于正常执行的程序。通常我们使用的都是这个通道

  • 注入通道组:

从名字来理解,注入即为插入,是一种不安分的通道,类似于中断。当程序正常往下执行时,中断可以打断程序的执行。同样如果在规则通道转换过程中,有注入通道插队,那么就要先转换完注入通道,等注入通道转换完成后,再回到规则通道的转换流程

  • DMA 请求

规则和注入通道转换结束后,除了产生中断外,还可以产生 DMA 请求,把转换好的数据直接存储在内存里面。

要注意的是只有 ADC1 和 ADC3 可以产生DMA 请求。一般我们在使用 ADC 的时候都会开启 DMA 传输

  • 转换方式

单次转换:顾名思义,ADC 执行一次转换。想要在转换需要再次开启

连续转换:

ADC 结束一个转换后立即启动一个新的转换,需要注意的是:此模式无法连续转换注入通道。连续模式下唯一的例外情况是,注入通道配置为在规则通道之后自动转换

STM ADC引脚映射

有些没有的管脚就不用关心了,比如F1的没有PF6-10引脚

DMA通道映射

cubemx 配置

时钟之类的配置,劳烦各位小伙伴补补课,翻翻小飞哥前面的文章哈,直接进入正题

单通道DMA转换

时钟配置为分频之后为12MHZ

选择 ADC1->IN8->PB0

需要关注的几个点,扫描模式,这个在单通道时是无法使能的,只有多通道才可以开启,连续转换模式,根据自己实际需求决定是连续转换还是单次转换,触发方式,触发方式是非常多的,可以软件触发,PWM触发,定时器触发,也是根据自己的需要选择即可

中断,需要就开启,不需要就不用开启,直白~

DMA配置,DMA的中断是默认开启的,并且无法配置关闭

配置很简单,你学废了吗...

代码实现

ADC配置的代码

关于DMA的配置

extern ADC_HandleTypeDef hadc1;
extern DMA_HandleTypeDef hdma_adc1;

uint16_t adc_buffer[50] = {0};
static void prvPrintTask( void *pvParameters )
{
 float adc_value = 0;
 
 HAL_ADCEx_Calibration_Start(&hadc1);
 HAL_ADC_Start_DMA(&hadc1,(uint32_t *)adc_buffer,50);
 int iIndexToString;
 /* Two instances of this task are created. The task parameter is used to pass
 an index into an array of strings into the task. Cast this to the required type. */
 iIndexToString = ( int ) pvParameters;
 for( ;; )
 {

for(int index =0;index < 50;index++)
 {
  adc_value += adc_buffer[index];
 }
 adc_value/=50;
 
 adc_value = adc_value *3.3/(1<<12);
 debug_printf('\nadc_value = %.2f\n',adc_value);
  
 vTaskDelay( ( rand() & 0x1FF ) );
 }
}

配置为连续模式,DMA为循环模式,数据在buffer中不断循环更新

配置为不连续模式,只转换一次

我是直接接到3.3V测试的,精度还可以

接GND,是有一些非零值的,所以必要的滤波还是要做的,这里我是用了最简单的均值滤波处理

多通道DMA转换

配置和单通道有些不同,扫描模式就可以打开了,通道数可以选择,我们选择4即可,下面的顺序就是我们要转换的顺序

/* ADC1 init function */void MX_ADC1_Init(void){

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */  /** Common config  */  hadc1.Instance = ADC1;  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;  hadc1.Init.ContinuousConvMode = ENABLE;  hadc1.Init.DiscontinuousConvMode = DISABLE;  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;  hadc1.Init.NbrOfConversion = 4;  if (HAL_ADC_Init(&hadc1) != HAL_OK)  {    Error_Handler();  }  /** Configure Regular Channel  */  sConfig.Channel = ADC_CHANNEL_8;  sConfig.Rank = ADC_REGULAR_RANK_1;  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)  {    Error_Handler();  }  /** Configure Regular Channel  */  sConfig.Channel = ADC_CHANNEL_9;  sConfig.Rank = ADC_REGULAR_RANK_2;  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)  {    Error_Handler();  }  /** Configure Regular Channel  */  sConfig.Channel = ADC_CHANNEL_10;  sConfig.Rank = ADC_REGULAR_RANK_3;  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)  {    Error_Handler();  }  /** Configure Regular Channel  */  sConfig.Channel = ADC_CHANNEL_11;  sConfig.Rank = ADC_REGULAR_RANK_4;  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)  {    Error_Handler();  }  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

主函数中编写如下代码:

为了更直观的观察效果,定义二维数组,每个存储4个值,可以看到,4个通道是依次转换的,各取10个值,求平均值

extern ADC_HandleTypeDef hadc1;
extern DMA_HandleTypeDef hdma_adc1;

uint16_t adc_buffer[10][4] = {0,0};
  
static void prvPrintTask( void *pvParameters )
{
 float adc_value[4] = {0};
 HAL_ADCEx_Calibration_Start(&hadc1);
 HAL_ADC_Start_DMA(&hadc1,(uint32_t *)adc_buffer,40);
 int iIndexToString;
 /* Two instances of this task are created. The task parameter is used to pass
 an index into an array of strings into the task. Cast this to the required type. */
 iIndexToString = ( int ) pvParameters;
 for( ;; )
 {
  for(int i=0;i<4;i++)
  {
   for(int j=0;j<10;j++)
   {
    adc_value[i]+=adc_buffer[j][i];
   }
  adc_value[i]=(float)adc_value[i]/(10*4096)*3.3;//求平均值并转换成电压值
  //ADC_Value[i]=(float)sum/10;
  printf('ADC_Value[%d] = %.2f\n',i,adc_value[i]);
 }  
  vTaskDelay( ( rand() & 0x1FF ) );
  }
}

经验交流

(0)

相关推荐

  • 面向信号处理过程的ADC特性使传感器连接变得简单

    单片机(MCU)和传感器测控系统中,经常遇到需要模拟量传感器输入的情况. 这种输入的模拟量,需要由模拟数字转换器外设,简称ADC,来转换为N位数字量后再由CPU进行处理.近年来,随着智能传感器技术和物 ...

  • STM32_H750_ADC总结

    DMA中断方式 STM32cubemx的一些基础配置 注意H750引脚,很多引脚有后缀例如PC3_C(不是PC3) ADC和DMA都不是连续模式 初始化开启DMA传输 HAL_ADC_Start_DM ...

  • 【电路“芯”说】单片机ADC扩展

    早在几天前,我写了一篇关于单片机IO口扩展的文章,接着有网友和我来讨论关于ADC扩展的问题了,关于这个问题,这篇文章有详细的讨论.单片机ADC为何要扩展现在的主流MCU都内置了不止一个多通道的ADC, ...

  • 【以拆会友】拆解一台4通道记录仪

    应饺神要求,拆解一台AD工业的PowerLab4/25 四通道记录仪,设备为四通道16bit 100K记录仪,主要用于医疗记录生理电位信息,可以用于心电图等,相对高速记录仪来讲应该是比较慢了.废话就不 ...

  • 基于A/D转换器IC层叠并联实现通道倍扩展

    [导读]1 引 言 A/D转换器是数据采集中常用的模/数转换器件,对于具有检测功能的智能仪表来说,设计者总希望在硬件电路板的最小面积内获得更多的检测通道.本文以MCS-51和AD 1 引 言 A/D转 ...

  • STM32】ADC的基本原理、寄存器(超基础、详细版)

    ADC的基本介绍 ADC的基本定义 Analog-to-Digital Converter的缩写.指模/数转换器或者模拟/数字转换器.是指将连续变量的模拟信号转换为离散的数字信号的器件. 典型的模拟数 ...

  • 【免费申请真机体验】全方位解读泰克全新一代3系列MDO和4系列MSO中端示波器

    立刻申请产品体验 抢先一步,体验新一代示波器 更大尺寸的高清显示,更多通道以及全新的触摸用户体验 识别下方二维码,或点击"阅读原文" 填写申请表 6月10日,泰克科技在北京召开媒体 ...

  • 【STM32】HAL库 STM32CubeMX教程三

    前言 上一节我们讲解了STM32CubeMX的基本使用和工程的配置,那么这一节我们正式来学习CubeMX配置STM32的各个外设功能了 今天我们会详细的带你学习STM32CubeMX配置外部中断,并且 ...

  • 【国画教程】八哥画法步骤详解

    [国画教程]八哥画法步骤详解 八哥学名鸲鹆,生于南方,因其本性灵巧,能仿人言,故多有贩卖,久之南北流传.八哥通身乌黑,初级飞羽中部具白斑,黑白分明,愈显俏丽.头前鼻上有丛毛,色亦乌黑.爪.嘴多为粉黄. ...

  • 蜻蜓的工笔画教程:分步骤讲解蜻蜓工笔画教程(附工笔染色详解)

    蜻蜓的画法 画前准备 用笔:勾线笔.染色笔 用色:藤黄.花青.曙红.钛白.墨汁 其他:调色盘.熟宣纸 蜻蜓为益虫,国画中蜻蜓代表着闲澹怡然的田园形象,大多生活在有水的地方,并配有各种植物,如荷花.竹叶 ...

  • 山水画基础技法之山石画法教程,石分三面勾线技巧详解

    山水画基础技法之山石画法教程,石分三面勾线技巧详解

  • 【国画教程】工笔猫技法详解

    本文摘录自<工笔猫技法全解>,邢诚爱编绘,天津杨柳青画社出版.节选内容仅供参考,如需深入学习.请从正规渠道购买正版图书. 画猫的笔法 画猫,尤其画猫毛,掌握几种笔法是至关重要的.为了愉当地 ...

  • 图文教程|工笔猫技法详解

    本文摘录自<工笔猫技法全解>,邢诚爱编绘,天津杨柳青画社出版.节选内容仅供参考,如需深入学习.请从正规渠道购买正版图书. 画猫的笔法         画猫,尤其画猫毛,掌握几种笔法是至关重 ...

  • PS图层混合模式教程,图层混合知识详解

    PS是一个强大的平面设计软件,它对图像颜色的修改功能是十分震撼的,世界各国平面设计领域都使用Photoshop来进行作品.图片的颜色处理.技术方面在全球处于独一无二的地位. 它的图像-调整菜单,提供了 ...

  • PS颜色调整教程,色彩调整命令可选颜色详解

    可选颜色:改变所选择颜色的色相. 可选颜色面板 可选颜色调色原理: 颜色选项所选的颜色和颜色滑块没有去动的颜色色阶数值不会发生改变. 调色原理是我们在调色过程中要清楚的.要牢记的,要不然我们是没办法去 ...

  • PS颜色调整教程,色相/饱和度命令详解之饱和度、明度剖析

    在上节课中我们详细地学习了色相有关的知识. 色相.饱和度.明度是颜色的三大属性,色相或者说颜色的改变并不会改变颜色的饱和度以及明度,一种颜色改变成另一种颜色后,会继承原来颜色的饱和度和明度. 那么如果 ...