基于STM32的嵌入式系统原理与应用-第9章 ADC原理及应用_第1页
基于STM32的嵌入式系统原理与应用-第9章 ADC原理及应用_第2页
基于STM32的嵌入式系统原理与应用-第9章 ADC原理及应用_第3页
基于STM32的嵌入式系统原理与应用-第9章 ADC原理及应用_第4页
基于STM32的嵌入式系统原理与应用-第9章 ADC原理及应用_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第9章ADC原理及应用基于STM32的嵌入式系统原理与应用ONTENTS目录C9.1ADC的工作原理9.2ADC的功能框图9.3ADC单通道采集案例9.1ADC的工作原理ADC的工作原理ADC是一种将模拟量(如电压值、光敏电阻阻值、热敏电阻阻值等)转换为数字量的外设。ADC,模拟数字转换器Analog-to-DigitalConverterADC主要特性ADC的工作原理(1)可配置12位、10位、8位或6位分辨率,通常为12位,意味着最大可以计数到4095,能够提供高精度的模拟量转换。(2)在转换结束、注入转换结束、模拟看门狗事件或溢出事件发生时,ADC可以产生中断,通知处理器处理转换结果或异常情况。(3)支持单次转换模式和连续转换模式,满足不同的应用场景需求。(4)扫描模式允许ADC自动从通道0转换到通道“n”,适用于需要顺序采集多个通道数据的场景。(5)数据对齐功能确保内置数据的一致性,便于处理器正确读取和处理转换结果。(6)每个通道的采样时间可以独立设置,以适应不同信号的采样需求。(7)支持外部触发器,可以为规则转换和注入转换配置极性,增加转换的灵活性和可控性。(8)支持不连续采样模式,允许在需要时启动或停止采样,节省功耗。(9)对于具有两个或更多ADC的器件,支持双重/三重模式,可以同时或交替使用多个ADC进行转换。(10)在双重/三重模式下,可以配置DMA数据存储,以及转换间的延迟,优化数据处理和转换效率。(11)ADC转换类型有多种,例如双积分、逐次逼近,具体可以参见数据手册。(12)ADC在全速运行时需要2.4V到3.6V的电源,而在慢速运行时则需要1.8V的电源。(13)ADC的输入范围:VREF-≤VIN≤VREF+。(14)在规则通道转换期间,ADC可以产生DMA请求。ADC模块的工作原理是将连续的模拟信号转换为离散的数字信号。这个过程包括采样、保持、量化与编码。01020304保持采样后,ADC会将采样得到的信号值保持一段时间,以便进行后续的转换处理。采样采样是ADC工作的第一步,也是将模拟信号引入ADC系统的过程。采样是将连续变化的模拟信号在时间上进行离散化的过程。编码在量化之后,每个量化的离散级别都被分配一个特定的二进制代码。编码阶段是将量化后的每个离散值转换成数字系统可以理解和处理的二进制形式。量化量化是指将采样并保持的模拟值转换为一系列固定步长的离散值的过程。因为数字系统只能表示有限数量的状态,所以这一步涉及到将无限精细的模拟信号映射到有限数量的数字级别上。ADC的工作原理02双积分ADC双积分ADC(Dual-SlopeIntegratingADC)通过两次积分过程来实现模数转换。首先,对输入模拟电压进行固定时间的积分,然后将积分电容放电至零。接着,对参考电压进行反向积分,直到积分电容上的电压再次回到零。这两个积分过程的时间与输入模拟电压和参考电压的大小有关,通过测量反向积分的时间,可以计算出输入模拟电压对应的数字量。计数式ADC计数式ADC(CountingADC)的工作原理类似于一个计数过程。在转换开始时,计数器清零,然后一个已知参考电压(通常为零或某一固定值)与输入模拟电压进行比较。如果输入电压大于参考电压,计数器开始计数,同时参考电压逐渐增加,直到与输入电压相等时停止计数。01逐次逼近ADC逐次逼近ADC(SuccessiveApproximationRegister,SARADC)工作原理可以与天平称重物相类比。在开始转换之前,SARADC会将模拟输入信号与参考电压进行比较,确定信号的大致范围。SARADC从最高位开始,逐位确定输入信号的数字表示。这个过程可以想象成使用天平称重物,首先估计重物的重量范围,然后逐步调整砝码直到天平达到平衡。03ADC的工作原理9.2ADC的功能框图ADC的功能框图1.电压输入范围ADC的电压输入范围主要由VREF-、VREF+、VDDA、VSSA、这四个外部引脚决定。一般来说,ADC的电压输入范围可以表示为VREF-≤VIN≤VREF+。在实际应用中,通常将VSSA和VREF-接地,而将VREF+和VDDA接3V3,这样ADC的输入电压范围就是0~3.3V。如下图9-5所示为电压输入模块在单个ADC框图中的位置。图9-5电压输入模块ADC的功能框图2.输入通道ADC的输入通道负责将外部的模拟信号引入到ADC内部进行转换。我们确定好了ADC的输入电压,通过ADC的输入通道,将电压输入到ADC。这些通道的设计和配置对于确保信号转换的准确性和可靠性具有至关重要的影响。通过选择合适的输入通道,可以灵活地采集各种模拟信号,如温度、压力、光照等传感器输出的信号,以便进行准确的模数转换。如下图9-6所示为输入通道模块在ADC框图中的位置。图9-6输入通道模块ADC的功能框图3.触发源ADC的触发源是指启动ADC转换的信号来源。这些触发源可以分为两大类:软件触发和硬件触发。如下图9-8所示为触发源模块在ADC框图中的设置。图9-8触发源模块ADC的功能框图4.转换时间转换时间对于ADC来说是一个关键参数,它决定了ADC完成一次模拟到数字转换所需的时间。在STM32中,ADC输入时钟(ADC_CLK)是由PCLK2(APB2时钟)经过分频产生的。分频因子由ADC通用控制寄存器(ADC_CCR)的ADCPRE[1:0]位设置,可选的分频系数包括2、4、6和8,没有1分频的选项。如果PCLK2的频率是84MHz(这是STM32F407的APB2时钟的最大频率),那么ADC_CLK的最大可能频率将是:(1)当ADCPRE[1:0]=00时,分频系数为2,ADC_CLK=84MHz/2=42MHz(但这里需要注意,由于最大值是36MHz,所以实际上ADC_CLK将被限制在36MHz。(2)当ADCPRE[1:0]=01时,分频系数为4,ADC_CLK=84MHz/4=21MHz。(3)当ADCPRE[1:0]=10时,分频系数为6,ADC_CLK=84MHz/6=14MHz。(4)当ADCPRE[1:0]=11时,分频系数为8,ADC_CLK=84MHz/8=10.5MHz。因此,尽管PCLK2的频率可以达到84MHz,但ADC_CLK的实际最大值受限于36MHZ。在实际应用中,通常会选择一个较低的分频系数以获得更快的转换速率,同时确保ADC_CLK不超过其最大值。典型值30MHZ是一个常用的选择,它提供了良好的转换速率和性能。如下图9-9所示转换时间模块。图9-9转换时间模块ADC的功能框图5.数据寄存器在前面工作准备就绪后,ADC转换完成的数据会根据转换组的不同而被保存到不同的寄存器中。具体来说,规则组转换的数据会被保存在ADC_DR寄存器里,而注入组转换的数据则会被存放在JDRX寄存器中。特别注意的是,ADC_DR寄存器用于存储ADC的采样数据,因此,在每一次ADC采样完成后,都需要及时读取该寄存器中的数据,否则该数据会被下一次的采样结果所覆盖。数据的读取可以通过中断方式来实现,也可以通过DMA(直接内存访问)方式来完成。如下图9-10所示数据寄存器模块。图9-10数据寄存器模块ADC的功能框图6.中断响应数据转换结束后,可以产生中断,中断分为四种:规则通道转换结束中断,注入转换通道转换结束中断,模拟看门狗中断和溢出中断。如下图9-13中断响应模块。图9-13中断响应模块ADC的功能框图7.电压转换当模拟电压信号经过ADC(模数转换器)时,会被转换成一个相对精度的数字值。然而,这个数字值在通过串口以16进制格式输出时,可能不易于直观理解。因此,我们有时需要将这个数字电压值重新转换回模拟电压值,以便与实际测量的模拟电压(例如,使用万用表测得的值)进行对比,从而验证ADC转换的准确性。

当ADC转换后的数值为X时,我们可以通过一个简单的数学等式将其转换回对应的模拟电压Y=(3.3×X)/(2^12)。这个等式表明,通过乘以3.3V并除以2^12(即4096),我们可以将ADC输出的数字值X转换回实际的模拟电压值Y。这样的转换对于验证ADC的性能、确保数据的准确性以及进行系统调试都非常重要。使我们能够直观地理解数字值与实际电压之间的关系,并确保我们的测量和处理过程是准确的。9.3ADC单通道采集案例ADC单通道采集案例9.3.1硬件设计本实验将ADC与TPAD连接,通过ADC1的通道5(PA5)来读取TPAD电压值。电容触摸按键TPAD是一种利用人体电容效应来检测触摸操作的技术,基本原理是测量触摸点处的电容变化。当手指接近触摸按键的表面时,因为人体具有一定的电容性,会与按键表面形成一个电容器。手指的接近会改变这个电容器的电容值,从而触发相应的电子信号。这种变化通过电路处理后被识别为触摸操作。TPAD并没有直接连接在MCU上,而是连接在多功能端口(P12)上面,通过跳线帽来选择是否连接到STM32。由于实验板上没有设置参考电压源,因此本实验我们仅将TPAD作为我们的被测电压使用,从原理图中可以看到,在未触摸状态下,初始电压接VCC3.3,由于存在上拉电阻R64原因,可能最后测得电压小于3.3V。原理图中通过多功能端口P12实现ADC与TPAD的连接,将TPAD与P12端口1连接,ADC与P12端口2连接,这样TAPD引脚就可以与ADC中PA5连接起来了。用到的硬件资源有STM32F407开发板、ADC模块、待测电压源(TPAD)、显示屏(TFTLCD)及指示灯等硬件资源。原理图9-14如下所示:

a)ADC模块

b)TPAD模块

c)ADC与TPAD连接部分图9-14硬件设计原理图9.3.2软件设计本实验不仅需要编写主程序main.c,还需要编写用于ADC外设的驱动程序实现和头文件声明的两个文件,可以分别命名bsp_adc.c和bsp_adc.h。其中bsp_adc.h是ADC外设的头文件,包含了各种宏定义、函数声明和结构体定义,用于配置和控制ADC的各种功能。它包含初始化ADC、配置通道、启动转换、获取转换结果等函数的声明。bsp_adc.c是ADC外设的驱动程序实现文件,实现了在bsp_adc.h中声明的函数和宏定义。在这个文件中,会包括具体的函数定义和相应的硬件操作指令,如设置寄存器、启用时钟、配置GPIO、处理中断等。通过bsp_adc.c文件,实现了对ADC硬件的底层控制和功能调用。下面对三个文件做详细说明。ADC单通道采集案例1.bsp_adc.h以下是ADC外设驱动程序的头文件(bsp_adc.h)内容。//使用了预处理器指令,确保在编译过程中只包含一次该头文件内容,避免重复定义#ifndef__ADC_H#define__ADC_H//包含了一个"sys.h"的头文件,是系统相关的定义和函数声明#include"sys.h"//初始化ADC通道,包括设置ADC的时钟、通道选择、采样率等voidAdc_Init(void);

//获取指定通道(ch)的ADC转换值,返回一个16位无符号整数(u16)u16Get_Adc(u8ch);

//获取指定通道(ch)的ADC转换值的平均值,通过多次采样计算得到,times参数指定采样的次数u16Get_Adc_Average(u8ch,u8times);//头文件结束,预处理器指令的结束标记,确保头文件内容在包含时不会被重复定义#endifADC单通道采集案例2.bsp_adc.cbsp_adc.c是ADC外设的驱动程序实现文件,下面对代码部分分开进行详细讲解。(1)头文件//头文件包含#include"bsp_adc.h"#include"delay.h"(2)ADC初始化函数Adc_Init这个函数用于初始化ADC1,并配置所需的GPIO端口(在这里是GPIOA的第5引脚)用于ADC操作。voidAdc_Init(void){

//定义用于初始化GPIO端口的结构体变量GPIO_InitTypeDefGPIO_InitStructure;

//定义ADC通用初始化结构体变量,用于配置ADC的通用参数

ADC_CommonInitTypeDefADC_CommonInitStructure;

//定义ADC初始化结构体变量,用于配置ADC的具体参数ADC_InitTypeDefADC_InitStructure;

//使能AHB1总线上的GPIOA的时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);

//使能APB2总线上的ADC1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);

//初始化GPIO//选择GPIO端口的第5个引脚,即PA5通道5GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;

//设置GPIO模式为模拟输入GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;

//不使用上拉或下拉电阻GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;

//根据以上设置初始化GPIOA端口的第5引脚GPIO_Init(GPIOA,

&GPIO_InitStructure);

ADC单通道采集案例

//ADC复位//使能ADC1的复位RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);

//禁用ADC1的复位,完成复位过程RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);

//配置ADC的通用参数

//设置ADC为独立模式ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;

//设置两次采样之间的延迟为5个时钟周期ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;

//禁用DMA访问模式ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;

//设置ADC预分频器为4分频,ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36MhzADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;

//使用上面配置的结构体初始化ADC的通用参数

ADC_CommonInit(&ADC_CommonInitStructure);

//配置ADC的具体参数

//设置ADC的分辨率为12位ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;

//禁用扫描转换模式ADC_InitStructure.ADC_ScanConvMode=DISABLE;

//禁用连续转换模式

ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;

//设置外部触发转换的边沿为无

ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;

//设置数据对齐为右对齐ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;

//设置转换数量为1ADC_InitStructure.ADC_NbrOfConversion=

1;

//使用上面配置的结构体初始化ADC1的具体参数

ADC_Init(ADC1,

&ADC_InitStructure);

//使能ADC1,开始ADC转换ADC_Cmd(ADC1,ENABLE);}

ADC单通道采集案例(3)读取ADC值Get_Adc以下代码是一个用于读取ADC值的函数,名为Get_Adc。它接收一个参数ch,代表要读取的ADC通道。函数的返回类型是u16,即16位无符号整数,表示ADC转换的结果。这个函数的作用是配置ADC的一个通道,启动转换,等待转换完成,然后返回转换结果。这个函数可以用于读取连接在指定ADC通道上的模拟传感器的值。u16Get_Adc(u8ch)

{

//配置了ADC1的常规通道。ch是传入的参数,表示要配置的通道号。

//1表示这个通道是单次转换中的第一个(也是唯一一个)通道。

//ADC_SampleTime_480Cycles表示采样时间为480个时钟周期。ADC_RegularChannelConfig(ADC1,ch,

1,ADC_SampleTime_480Cycles);

//启动ADC1的软件转换ADC_SoftwareStartConv(ADC1);

//这是一个循环,它会一直执行,直到ADC转换完成。

//ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)检查ADC1的转换结束标志(EOC,EndOfConversion)是否被设置。如果转换未完成,这个标志是0,循环继续;如果转换完成,标志被设置为1,循环结束。

while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));

//返回最近一次ADC1规则组的转换结果

returnADC_GetConversionValue(ADC1);

}ADC单通道采集案例(4)多次获取ADC值并取平均Get_Adc_Average以下代码定义了一个名为Get_Adc_Average的函数,其目的是对指定ADC通道进行多次采样,并计算这些采样值的平均值。函数接收两个参数:ch代表ADC通道号,times代表采样的次数。函数的返回类型是u16,即16位无符号整数,表示采样值的平均值。这个函数通过多次采样并计算平均值的方式获取通道ch的转换值,来提高ADC读数的准确性和稳定性。u16Get_Adc_Average(u8ch,u8times){

//定义一个32位无符号整数temp_val,用于累加每次采样得到的ADC值。使用32位整数是为了防止在多次累加过程中发生溢出。u32temp_val=0;

//定义一个8位无符号整数t,用作循环计数器。u8t;

for(t=0;t<times;t++)

{

//调用Get_Adc函数获取指定通道ch的ADC值,并将其累加到temp_val中。temp_val+=Get_Adc(ch);

//在每次采样之后,调用delay_ms函数延迟5毫秒。这是为了在给定的采样次数之间提供一定的时间间隔,以确保采样的稳定性。delay_ms(5);

}

//循环结束后,将累加得到的总ADC值temp_val除以采样次数times,计算平均值,并将其作为函数的返回值。

returntemp_val/times;}

ADC单通道采集案例3.main.c以下代码是完整的实验主程序。程序的主要功能是初始化ADC,并通过LCD显示屏实时显示ADC通道5的电压值,代码涵盖了初始化、数据采集、数据处理和结果显示等关键步骤,具体如下。#include"sys.h"#include"delay.h"#include"usart.h"#include"led.h"#include"lcd.h"#include"bsp_adc.h"voiddisplay_adc_value(u16adcx)

{

//计算电压值,并将其拆分为整数部分和小数部分进行显示。电压计算公式为(float)adcx*(3.3/4096),其中3.3是参考电压值,4096是12位ADC的最大值

floatvoltage=

(float)adcx*

(3.3f

/

4096);u16intPart=

(u16)voltage;

//整数部分

//小数部分,乘1000转为毫伏u16decPart=

(voltage-intPart)

*

1000;

//使用LCD_ShowxNum函数在LCD上显示ADC的原始值和计算后的电压值POINT_COLOR=BLUE;LCD_ShowxNum(134,

130,adcx

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论