0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

介绍如何通过意法的STM32 MCU实现用DMA完成多通道的AD采样功能

贸泽电子设计圈 2018-01-24 15:41 次阅读

嵌入式产品中有时候需要实现对外部的模拟量进行采样处理和记录,而这就需要使用到ADC功能,将外部的模拟量转换成数字量。而在复杂的嵌入式产品中,往往需要使用多路AD采样,例如在智能家居产品,电池电量检测,热敏温度传感器,烟雾传感器,气敏传感器等都是可以使用ADC来实现采样的。在本文章,将会介绍如何通过意法的STM32 MCU实现用DMA完成多通道的AD采样功能。

什么叫ADC

ADC即模拟数字转换器(英语:Analog-to-digital converter)是用于将模拟形式的连续信号转换为数字形式的离散信号的一类设备。一个模拟数字转换器可以提供信号用于测量。与之相对的设备成为数字模拟转换器。

影响AD采样的因素有哪些

分辨率

分辨率指的是ADC的位数,例如STM32F103MCU的内部ADC的分辨率是12位,那么它所采样的结果就在0-4096之间。

最小采样单位值

根据基准电压和参考电压的不同,其值也是不同的,例如在基准电压为3.3V,参考电压最低为0V,最高为3.3V,采样分辨率位12位的嵌入式系统中,则ADC的最小量程单位则为:3.3V/4096 = 0.00080566。

量程

在无负电压的嵌入式系统中,量程范围0-基准电压。

电源噪音

电源质量直接影响了AD采样的正确性和稳定性,如果条件满足,建议使用线性稳压源,若是使用开关电源的话,需要在VDDA模拟电源输入和参考电压输入接一个线性稳压管,同时要注意减小PCB板布局走线中结电容对采样电路的影响。

STM32F103 ADC主要特性

12-位分辨率

转换结束,注入转换结束和发生模拟看门狗事件时产生中断

单次和连续转换模式

从通道0到通道n的自动扫描模式

自校准

带内嵌数据一致的数据对齐

通道之间采样间隔可编程

规则转换和注入转换均有外部触发选项

间断模式

双重模式(带2个或以上ADC的器件)

ADC转换时间:─ STM32F103xx 增强型产品: ADC 时钟为 56MHz 时为 1μs(ADC 时钟为 72MHz 为 1.17μs)─ STM32F101xx 基本型产品: ADC 时钟为 28MHz 时为 1μs(ADC 时钟为 36MHz 为 1.55μs)─ STM32F102xxUSB 型产品: ADC 时钟为 48MHz 时为 1.2μs

ADC供电要求: 2.4V到3.6V

ADC输入范围: VREF- ≤ VIN ≤ VREF+● 规则通道转换期间有DMA请求产生。

DMA简介

直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU任何干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。

STM32F103 DMA主要特性

12个 独立的可配置的通道(请求)DMA1有7个通道, DMA2有5个通道

每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过软件来配置。

在七个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),假如在相等优先权时由硬件决定(请求0优先于请求1,依此类推) 。

独立的源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐。

支持循环的缓冲器管理

每个通道都有3个事件标志(DMA 半传输, DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求。

存储器和存储器间的传输

外设和存储器,存储器和外设的传输

闪存、 SRAM、外设的SRAM、 APB1 APB2和AHB外设均可作为访问的源和目标。

可编程的数据传输数目:最大为65536

如何实现多通道AD采样的DMA传输

ADC功能引脚配置

void ADC_GPIO_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* Enable DMA clock */

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

/* Enable ADC1 and GPIOC clock */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);

//配置模拟通道输入引脚

GPIO_InitStructure.GPIO_Pin = ADC1_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//配置引脚为模拟输入模式

GPIO_Init(ADC1_GPIOX, &GPIO_InitStructure); // 输入时不用设置速率

//配置模拟通道输入引脚

GPIO_InitStructure.GPIO_Pin = ADC2_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//配置引脚为模拟输入模式

GPIO_Init(ADC2_GPIOX, &GPIO_InitStructure); // 输入时不用设置速率

//配置模拟通道输入引脚

GPIO_InitStructure.GPIO_Pin = ADC3_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//配置引脚为模拟输入模式

GPIO_Init(ADC3_GPIOX, &GPIO_InitStructure); // 输入时不用设置速率

GPIO_InitStructure.GPIO_Pin = ADC4_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

GPIO_Init(ADC4_GPIOX,&GPIO_InitStructure);

}

配置多通道ADC功能

void ADC_Multichannel_Config(void){ADC_InitTypeDef ADC_InitStructure; ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值 /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC工作模式:ADC1和ADC2工作在独立模式

ADC_InitStructure.ADC_ScanConvMode =ENABLE; //模数转换工作在扫描模式

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在连续转换模式

ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_None; //外部触发转换关闭

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐

ADC_InitStructure.ADC_NbrOfChannel = M; //顺序进行规则转换的ADC通道的数目

ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器 /* ADC1 regular channel11 configuration */ //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间 //ADC1,ADC通道x,规则采样顺序值为y,采样时间为239.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1,ADC_SampleTime_239Cycles5 );

ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2,ADC_SampleTime_239Cycles5 );

ADC_RegularChannelConfig(ADC1, ADC_Channel_4,3,ADC_SampleTime_239Cycles5 );

ADC_RegularChannelConfig(ADC1, ADC_Channel_8,4,ADC_SampleTime_239Cycles5);

// 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)

ADC_DMACmd(ADC1, ENABLE);

/* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1

/* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); //复位指定的ADC1的校准寄存器 /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); //复位指定的ADC1的校准寄存器

/* Start ADC1 calibaration */ADC_StartCalibration(ADC1); //开始指定ADC1的校准状态

/* Check the end of ADC1 calibration */while(ADC_GetCalibrationStatus(ADC1)); //获取指定ADC1的校准程序,设置状态则等待}

配置DMA通道,使能ADC转换结果从外设到内存

void DMA_Configuration(void) {/* ADC1 DMA1 Channel Config */

DMA_InitTypeDef DMA_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输

DMA_DeInit(DMA1_Channel1); //将DMA的通道1寄存器重设为缺省值

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR; //DMA外设ADC基地址

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_Value; //DMA内存基地址

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //内存作为数据传输的目的地

DMA_InitStructure.DMA_BufferSize = N*M; //DMA通道的DMA缓存的大小

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //数据位宽度16位

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度16位

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循环缓存模式

DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存

DMA_Init(DMA1_Channel1, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数DMA通道

开始启动ADC转换功能

void ADC_Start(void){ ADC_GPIO_Config(); ADC_Multichannel_Config(); DMA_Configuration(); ADC_SoftwareStartConvCmd(ADC1, ENABLE); //开始ADC转换 DMA_Cmd(DMA1_Channel1, ENABLE); //启动DMA通道}

使用冒泡排序法,对各通道的连续五次采样结果取平均值

u16 ADC1_AveragValue(u16 ADC_Value[N][M]){ u16 ADC1_Value[N]; u8 i = 0; u8 j = 0; u16 temp = 0; u16 ADC1_Av = 0; for (i = 0;i < N;i++) { ADC1_Value[i] = ADC_Value[i][0]; } /*冒泡排序*/ for(i=0; iADC1_Value[j+1]) { temp=ADC1_Value[j]; ADC1_Value[j]=ADC1_Value[j+1]; ADC1_Value[j+1]=temp; } } } /*去掉最大值和最小值*/ for (i = 0; i

转换采样结果

(float)ADC1_AveragValue(ADC_Value)/4096*3.3)

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    145

    文章

    15885

    浏览量

    342773
  • STM32
    +关注

    关注

    2232

    文章

    10650

    浏览量

    347870
  • dma
    dma
    +关注

    关注

    3

    文章

    533

    浏览量

    98915
  • AD采样
    +关注

    关注

    0

    文章

    23

    浏览量

    15645

原文标题:STM32如何实现用DMA完成多通道的AD采样功能?看完这篇彻底懂了~

文章出处:【微信号:Mouser-Community,微信公众号:贸泽电子设计圈】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    【资料分享】基于STM32AD通道采样问题

    基于STM32AD通道采样问题使用DMA实现AD两个通道
    发表于 03-12 11:07

    DMA实现STM32ADC通道采集读数问题

    最近几天一直在做用DMA实现STM32ADC通道采集,所有配置都是按着要求来的,ADC和DMA
    发表于 03-26 18:38

    关于STM32 ADC通道连续扫描采样

    关于STM32ADC通道连续扫描采样DMA循环传输。通过ADC
    发表于 08-19 19:48

    STM32通道DMA—ADC采样 精选资料推荐

    title: STM32通道DMA—ADC采样tags: STM32date: 2019-02
    发表于 08-04 07:19

    通过CubeMx实现ADC通道扫描采集DMA方式

    项目简介任务:通过CubeMx实现ADC通道扫描采集DMA方式(无中断)采集内部温度传感器的温度通道
    发表于 08-11 08:14

    MM32F103 ADC+DMA 通道采样

    MM32F103 ADC+DMA 通道采样请问软件如何配置?
    发表于 08-27 14:48

    STM32通道DMA—ADC如何进行采样

    STM32通道DMA—ADC如何进行采样
    发表于 10-13 06:58

    怎么实现通道ADC通过DMA数据采集?

    怎么实现通道ADC通过DMA数据采集?
    发表于 11-18 06:46

    stm32 定时器触发ADC通道采样+DMA提取数据相关资料下载

    stm32g0 定时器触发ADC通道采样+DMA提取数据stm32g0 定时器触发ADC
    发表于 02-15 06:46

    应用笔记(三)| 运用DMA 功能实现高级定时器和ADC 的同步触发采样

    前言在做 BLDC 电机控制时,需要 ADC 的采样时刻和定时器产生的 PWM 波形相配合,才能获取准确的采样值, 本文介绍了 CW32F030 系列芯片通过运用
    发表于 07-08 17:02

    STM32的ADC1采集多条通道 可以不使用DMA功能吗?

    STM32的ADC1采集多条通道,可以不使用DMA功能吗?
    的头像 发表于 03-14 14:46 5170次阅读
    <b class='flag-5'>STM32</b>的ADC1采集多条<b class='flag-5'>通道</b> 可以不使用<b class='flag-5'>DMA</b><b class='flag-5'>功能</b>吗?

    STM32实现用DMA完成通道AD采样资料下载

    电子发烧友网为你提供STM32实现用DMA完成通道AD采样资料下载的电子资料下载,更有其他相关
    发表于 03-29 16:47 9次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>实现用</b><b class='flag-5'>DMA</b><b class='flag-5'>完成</b>多<b class='flag-5'>通道</b>AD<b class='flag-5'>采样</b>资料下载

    stm32 定时器触发ADC多通道采样+DMA提取数据

    stm32g0 定时器触发ADC多通道采样+DMA提取数据stm32g0 定时器触发ADC多通道
    发表于 12-16 16:56 62次下载
    <b class='flag-5'>stm32</b> 定时器触发ADC多<b class='flag-5'>通道</b><b class='flag-5'>采样</b>+<b class='flag-5'>DMA</b>提取数据

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

    。于是想到了ADC采样的数据用DMA功能存储,并通过串口打印。但是串口打印依然要占用单片机时间,那能不能串口数据的输出也采用 DMA
    发表于 12-28 19:25 32次下载
    <b class='flag-5'>STM32</b>单片机<b class='flag-5'>实现</b><b class='flag-5'>DMA</b>+ADC+UART<b class='flag-5'>功能</b>

    AT32讲堂004 | AT32 MCU DMA通道的灵活配置

    概述在使用Artery部分系列MCU时(如AT32F413\AT32F415\AT32F403A\AT32F407),可以使用DMA弹性映射功能。此功能使得
    的头像 发表于 05-10 09:57 1466次阅读
    AT32讲堂004 | AT32 <b class='flag-5'>MCU</b> <b class='flag-5'>DMA</b><b class='flag-5'>通道</b>的灵活配置