完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
2个回答
|
|
一、ADC基础知识
1.1 ADC 简介 ADC 模数转换器,Analog-to-Digital Converter的缩写,通常是指将连续变化的模拟信号转换为离散的数字信号的电子元件。 1.2 为什么需要 ADC 微控制器MCP是离散的数字器件,而实际的物理信号时连续模拟的,如温度、湿度、压力、速度等等。 通过传感器将带测量的模拟信号转换成电信号,而这个电信号也是连续的模拟量。 所以为了便于MCU处理数据,我们通过模拟-数字转换器ADC将传感器的连续的模拟电信号转换成离散的数字电信号。 数据采集系统如下图所示,ADC为核心。 数据采集系统由模拟信号采集,A/D转换、数字信号处理三大部分组成。 1.3 ADC的历史由来 二元权重取水法 如18世纪的二元权重取水法,就运用了模拟量转数字量的思想。 用8倍,4倍,2倍,1倍不同粗细的管子在在池子边上凿开许多眼。取水的时候把水量转化成数据,然后堵上一些管子,留下一些管子,放指定长的时间,就得到了一定分数的水。这也是一个模拟量变成数字量的过程。显然,给水的精度就是最细的那根管子放单位时间的水量。比这个更小的水量就忽略不记了,即把它当作误差了。 天平称重 联系现实,我们用天平称量重量也用到这种思想。 我们在做某些化学实验需要称量一定重量的物品,我们会使用到天平秤。称量时我们使用到砝码去称量所需物品的重量。我们需要多少克的物品,我们就放相应重量的砝码。(这里假设我们只用一种重量的砝码) 例如:只使用5g的砝码,称量40g的NaCl,这时我们就需要8个5g的砝码。 由上例,如果我们需要42g的NaCl,用5g的砝码就测量不出来。显然用5g砝码称量5的倍数的重量的物品才精确。 这时我们引出精度的概念,我们称量物品的精度就是最小重量的砝码确定的。如果我们使用1g的砝码,我们就能够准确称量1的倍数的重量的物品。 1-bit ADC 1bit ADC就是运用一个比较器来判断电压大小。 例:电压范围是0-3.3V,参考电压Uref=1.68V。输入电压Uin》Uref,就得到逻辑1,输入电压Uin《Uref,就得到逻辑0。 2-bit ADC 我们把输入电压给到3个电压比较器的比较端,3个电压比较器分别使用3个不同的参考电压Uref作为阈值。于是,我们电压就在这4个区间之中的一个区间中。我们把这4个区间识别成00、01、10、11。 提问:如果电压在Rank2,那么Uout1=?Uout2=?Uout3=? Uout1=1,Uout2=1,Uout3=0 输出了 3个bit 的数据,而我们需要 2bit 的数据,这时我们就还需一个编码电路把这 3bit 的输出 转化为对应的 2bit 的输出才形成我们的2bit ADC。 可见,一个完整的2bit ADC就由3个比较器,1个编码电路组成的。 结构原理最简单的ADC(n-bit ADC):FLASH ADC 由这种利用电压比较器的思想做出来的ADC就是FLASH ADC。 这种比较器优点是很快速。 缺点是电路复杂。精度越高,电路越复杂。 比如说我们要一个12bit精度,我们就需要2^12-1=4095的比较器放在一起工作。这样占用空间就大,连接复杂。 由上可见,FLASH ADC想法很简单,但是却实现困难。我们就转换思路,想想有没有其他方式实现ADC。 Counting ADC 如图:将600KHz的CLOCK100分频,作为脉冲取样频率(6kHz)。仅当脉宽PULSE WIDTH MODULATOR为逻辑1的时候,与门输出1。后面的计数器COUNTER就在这个时间宽度内数一数有多少个逻辑1,即有多少个窄高脉冲。这个计数值就量化了这个脉冲信号的宽度。脉冲信号的宽度与输入脉冲的幅度相关。于是就实现了对模拟输入电压的数字量化。 逐次渐进型(SA)ADC 类比猜数字游戏,给一个数字7让你猜。你猜是8,提示高了。你猜是6,提示猜低了。你猜7,对了。 逐次渐进型ADC就是类似于猜数字的思想。 猜一个数,我们先用DAC将数字还原成一个模拟电压值,与输入电压值比较。比较器告诉我们是大了,还是小了。然后我们在产生一个数,比较器再告诉我们是大了还是小了。猜的次数越多,就越逼近真实值。 逐次渐进型ADC就是一次次的去猜模拟电压,不断逼近真实的模拟电压。 例如下图:假设X = 45,去猜数字X。 下图是4bits的逐次渐进型ADC的一次猜数字过程。 逐次渐进型ADC用时间换取了空间,通过多次进行比较(时间) 去换取 多个比较器并行起来去比较(空间)。 在输入端加个电容,可以用来加强输入电压的稳定性。 1.4 A/D转换器的一些技术指标 分辨率(Resolution,可以理解为猜数的次数n,n越大越精确) 分辨率Resolution = 2n。 分辨率是指数字量变化一个最小量时模拟信号的变化量,定义为满刻度与2^n的比值。通常以数字信号的位数来表示。显然A/D转换器的位数越多,分辨最小模拟电压的值就越小。 如一个最大输入电压为5V的8位A/D转换器,所能分辨的最小输入电压变化量为5V / 28 = 19. 53mV。而同样输入电压大小的10位A/D转换器,分辨的最小输入电压变化量为5V / 210= 4. 88mV。 转换时间 转换时间是指完成一次转换所用的时间。即从发出转换控制信号开始,直到输出端得到稳定的数字输出为止所用的时间,通常为微秒级。 一般约定,转换时间大于1ms的为低速,1ms~ 1μs的为中速,小于1μs的为高速,小于1 ns的为超高速。 转换速率(Conversion Rate) 转换时间的倒数称为转换速率。即每秒转换的次数。 例如ADC0809的转换时间为100μs,则转换速率为每秒1万次。 相对精度。 相对精度是指A/D转换器实际输出数字量与理论输出数字量之间的最大差值。通常用最低有效位LSB的倍数来表示。 1.5 ADC转换基本原理 AD转换中通常要完成采样保持和量化编码两个内容。(采样保持的时间取决于量化编码的算法) 采样保持 图解:f(t)作为输入,采样器在一个高脉冲到来时进行采样(即闭合开关)。 量化编码(模/数转换的核心) 1.量化:将取样电压表示为最小数量单位(∆)的整数倍 2.编码:将量化的结果用代码表示出来(二进制,十进制) 3.量化误差:当采样电压不能被∆整除时,将引入量化误差 常见的量化编码技术有:计数式转换、双积分式转换、逐次逼近式转换、并联式转换等。 图解:输入0-1V的信号,用3位二进制数表示。常见思路,量化得到 ∆=1/8;编码就是对每一段区间的电压用二进制代码标识。量化误差是∆。 二、STM32的ADC 2.1 引入例子ADC0809(粗略了解) IN7-IN0:8路模拟量输入线。 D7-D0:8位数字量输出线。 ADDC- ADDA:3位地址线,用来选通8路模拟通道中的一路。 ALE:地址锁存允许,在ALE的上升沿,ADDC、ADDB、ADDA三位地址信号被锁存到地址锁存器。 START:启动转换的信号,正脉冲有效。地址锁存后,在该引脚加一正脉冲,该脉冲的上升沿使所有内部寄存器清零,从下降沿开始进行A/D转换。如果在转换过程中,接到新的启动信号,则原来的转换进程被中止。 CLOCK:时钟信号,输入线。时钟越高,转换的速率越快。 EOC:转换结束信号,高电平有效,输出。当该信号为低电平时,表明ADC 0809已准备开始转换,或正在转换进行之中,不能提供一个有效的稳定的数据。当EOC变为高电平时,表示转换己经结束,A/D转换器可提供有效数据。EOC可作为被查询的状态信号,亦可用于申请中断。ADC 0809转换一次共需64个时钟CLOCK周期。 OE:输出允许。当OE为高电平时打开输出三态缓冲器,使转换后的数据进入数据总线。 VREF(+) 、VREF(-): 基准电压输入。-般应用情况下,VEF(+)接+5V, 而VEF(:)与GND相连。 2.2 stm32f103 ADC基本特性 ●STM32F103单片机一般有3个ADC,每个ADC是 12位分辨率 的逐次逼近型的ADC。 ●每个ADC共有16个外部通道(单片机的ADC输入引脚),ADC1有两个内部通道:内部温度通道、参考电压 VREFINT 通道。 ●ADC供电要求: 2.4V 到 3.6V ●ADC输入范围: VREF- ≤ VIN ≤ VREF+ ●自校准 ●单次和连续转换模式 ●从通道0到通道n的 自动扫描模式 ●采样间隔可以按通道分别编程 ●ADC转换时间: STM32F 103xx增强型产品: APB2时钟为56MHz,4分频时为1μs APB2时钟为72MHz,6分频时为1.17μs ●规则通道转换期间有DMA请求产生。 ●转换结束、注入转换结束和发生模拟看门狗事件时产生中断 ●规则转换 和 注入转换 均有外部触发选项 ●双重 模式(带2个或以上:ADC的器件) 2.3 stm32f103 ADC框图 电压输入范围。 ADC电源:VDDA接3.3V,VSSA接GND ADC参考电压:2.4V ≤ VREF+ ≤ VDDA ; VREF- = VSSA 注意:VDDA不能高于3.3V。输入电压范围ADCx_IN应是0 ~ 3.3V。 输入通道。 ADCx_IN0 ~ ADCx_IN15 这16个外部通道(即输入口)可以采集模拟电压信号。 看框图标号2的旁边还有两个内部通道:一个是内部温度通道,另一个是内部参考电压 VREFINT 通道。(只有ADC1有) 转换顺序。 16个输入通道可以分为两组:注入通道,规则通道。 规则通道(最多16个):平民通道,规规矩矩。 注入通道(最多4个):VIP通道,可以插队。规则通道在执行转换时,注入通道有需要转换时,可以抢断规则通道的转换,优先进行转换。 常规转换扫描模式: 我们定义一个规则组(即定义了通道扫描的顺序),根据规则组顺序扫描。 注入转换扫描模式(VIP模式): 在常规转换扫描的过程中,注入组来了个触发信号,就打断常规组的转换扫描然后进行注入组的转换扫描,注入组完成转换扫描之后,产生中断信号,回到常规转换扫描。 ADC触发源:软件触发,事件触发。 软件触发:ADC_CR2:ADON、SWSTART、JSWSTART 外部事件触发:内部定时器/外部IO 选择: ADC_ CR2 :EXTSEL[2:0]和JEXTSEL[2:0] 激活: ADC_ CR2 :EXTTRIG和JEXTTRIG 时钟源ADCCLK 。 ADCCLK,最大为14MHz。 ADCCLK 由APB2提供,经分频2/4/6/8 得到ADCCLK。 通常来说,APB2为72MHz,由于ADCCLK 最大为14M,我们可以6分频得到比较高的ADCCLK=72/6=12MHz。 根据组的不同,将数据存储在不同的16位数据寄存器当中。 规则组就对应放到规则组寄存器,注入组对对应放到注入组寄存器。 因为ADC分辨率时12位,只是用到数据寄存器的12位,所以会有左对齐,右对齐的问题。 规则数据寄存器只有一个,多通道采集的时候处理不当可能会出现数据覆盖问题,故规则多通道采集时多会使用DMA。 中断。 如果开启中断,且对应的中断标志位置位可以触发中断。 转换结束标志EOC(End Of Convert),注入转换结束标志JEOC,模拟看门狗事件标志AWD。 总结 2.4 ADC工作模式 单次转换模式 单次转换模式里,ADC只执行一次转换。 此模式可通过设置ADC_CR2寄存器上的ADON位(只适用于规则通道) 或 通过外部触发启动(适用于规则通道或注入通道)启动,这时CONT位为0。 连续转换模式 在连续转换模式中,当前面ADC转换一结束马上就启动另一次转换。 此模式可通过设置ADC_CR2寄存器上的ADON位 或 通过外部触发启动,此时CONT位是1。 中断模式 略 单次/连续转换与单/多通道扫描结合 应用: 单通道单次转换 ■ 对一个通道进行一次转换,然后ADC停止 ■ 应用举例:启动系统功能之前测量电压 多通道单次转换 ■ 对多个通道进行逐个的独立转换,然后ADC停止 ■ 可对多达16个通道的转换配置不同采样时间和顺序 无需中途停止ADC来配置下一个通道的采样时间 节省CPU负载 ■ 应用举例:启动系统之前测量多个参数 电压、温度、压力等 机器人操作臂的坐标 物体所受扭力和形变的方向以及受力 单通道连续转换 ■ 对一个规则通道进行连续转换 ■ 通常可用于后台,无需CPU干涉的连续转换; 配合DMA的循环模式,进一-步减少CPU负载 ■ 应用举例:监测电池电压,测量并调节炉温等 多通道连续转换 ■ 对多个通道进行连续的独立转换 ■ 可对多达16个通道的转换配置不同采样时间和顺序 ■ 应用举例:多电池充电器中监测多个电压和温度的信息 多通道示波器-扫描通道,获取数据通过DMA送到SRAM里面,通过液晶显示屏显示数据。 2.5 相关寄存器 通道配置寄存器 ADC规则序列寄存器1(ADC_SQR1) ADC规则序列寄存器2(ADC_SQR2) ADC规则序列表存器3(ADC_SQR3) ADC注入序列表存器(ADC_JSQR) L[3:0]:定义转换的个数,取值000~1111,16个不同的数据代表不同的转换个数。 SQx[4:0]:定义通道的编号。规则组有16个,注入通道有4个。 同上。 控制寄存器1 SACN:开启或关闭扫描 JEOCIE:允许产生注入通道转换结束中断 EOCIE:允许产生规则通道转换结束中断 DUALMOD:双模式选择,使用1个ADC(ADC1) 或 使用2个ADC(ADC1、ADC2) AWDCH:看门狗通道通道选择位 控制寄存器2 ADCON:开启/关闭AD转换器 CONT:设置是否连续转换 CAL、RSTCAL:AD校准 ALIGN:设置数据格式对齐方式;左对齐置1,右对齐置0 DMA:开始/关闭DMA SWSTART、JSWSTART:软件触发 EXTTRIG、JEXTTRIG:外部事件触发 软件触发位: ADON、SWSTART、JSWSTART 外部事件触发位: 选择: ADC_CR2 :EXTSEL[2:0]和JEXTSEL[2:0] 激活: ADC_CR2 :EXTTRIG和JEXTTRIG ADC采样事件寄存器 这两个寄存器用于设置通道0~17的采样时间,每个通道占用3个位。 采样时间短可能会有噪声影响。 ADC数据寄存器 规则序列中的AD转化结果都将被存在这个寄存器里面,而注入通道的转换结果被保存在ADC_JDRx里面。 读取数据时,注意该寄存器的数据对齐方式 - 左对齐/右对齐。 (对齐方式可以通过ADC_ CR2的ALIGN位设置左对齐还是右对齐) ADC状态寄存器 2.6 ADC转换时间计算 转化时间于时钟频率息息相关。对于每个要转换的通道,采样时间建议尽量长一点,以获得较高的准确度,但是这样会降低ADC的转换速率。 ADC的转换时间可以由下式计算: Tconv =采样时间+12.5个周期。 其中: Tconv为总转换时间; 采样时间可以配置每个通道的SMP位选择; 12.5个周期是固定值,不可改变。(逐次逼近式的原则导致) 理论最短的转换时间(ADCCLK=14MHz): Tconv = 1.5+12.5 = 14周期 = 14* 1/14=1us 常用最短的转换时间(ADCCLK=12MHz): Tconv = 1.5+12.5 = 14周期 = 14* 1/12us=1.17us |
|
|
|
三、STM32 ADC编程
准备: 新建文件adc.h,adc.c,添加库文件stm32f10x_adc、stm32f10x_dma,添加adc驱动源文件adc.c ADC初始化结构体 typedef struct { uint32_t ADC_Mode;//ADC模式:配置ADC_CR1寄存器的位[19:16] : DUALMODE[3:0]位 FunctionalState ADC_ScanConvMode; //是否使用扫描模式。ADC_CR1位8: SCAN位 FunctionalState ADC_ContinuousConvMode; //单次转换OR连续转换: ADC_CR2的位1: CONT uint32_t ADC_ExternalTrigConv; //触发方式: ADC_CR2的位[19:17]: EXTSEL[2:0] uint32_t ADC_DataAlign; //对齐方式: 左对齐还是右对齐: ADC_CR2的位11: ALIGN uint8_t ADC_NbrOfChannel;//规则通道序列长度: ADC_SQR1的位[23:20]: L[3:0] }ADC_InitTypeDef; 3.1 测量3.3V引脚电压 烧写代码后,通过杜邦线分别连接PA1~ 3.3V, PA1 ~ GND ,然后通过串口观察ADC值。切忌不要作死接5V。 编程思路: ①开启时钟(PAADC1),初始化端口(设置PA1为模拟输入)。 APB2PeriphClockCmd(); GPIO_Init(); ②复位ADC1,设置ADC1预分频系数。 ADC_ Deinit(ADC1) RCC_ ADCCLKConfig(RCC PCLK2 Div6); ③初始化ADC1(设置ADC1的工作模式以及规则序列的相关信息)。 void ADC_Init(ADC_TypeDef*ADCx, ADC_IntTypeDef ADC InitStruct) ④使能ADC并校准(类比万用表)。 ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); //使能复位校准 while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束 ADC_StartCalibration(ADC1); //开启AD校准 while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束 ⑤配置规则通道参数: ADC_RegularChannelConfig(); ⑥开启软件转换: ADC_SoftwareStartConvCmd(ADC1), ⑦等待转换完成,读取ADC值。 ADCGetConversionValue(ADC1); 代码: adc.h #ifndef ADC_H #define ADC_H #include “stm32f10x.h” void ADC_GPIO_Init(void); void ADC_Configuration(void); u16 get_ADC(u8 channel); #endif adc.c #include “adc.h” void ADC_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );//使能GPIOA通时钟 //PA1 作为模拟通道输入引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚 GPIO_Init(GPIOA, &GPIO_InitStructure); } void ADC_Configuration(void) { ADC_InitTypeDef ADC_InitStructure; ADC_GPIO_Init(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE ); //使能ADC1通道时钟 RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目 ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器 ADC_Cmd(ADC1, ENABLE); //开启ADC1 ADC_ResetCalibration(ADC1); //使能复位校准 while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束 ADC_StartCalibration(ADC1); //开启AD校准 while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束 } u16 get_ADC(u8 channel) { //设置指定ADC的规则组通道,一个序列,采样时间 ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_239Cycles5); //ADC1,ADC通道,采样时间为239.5周期 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束 return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果 } main.c #include “stm32f10x.h” #include “bsp_systick.h” #include “usart.h” #include “adc.h” int main(void) { usart1_Init(9600); ADC_Configuration(); u16 adc_Value = 0 ; float temp; printf(“start!n”); while(1) { adc_Value = get_ADC(ADC_Channel_1);//指定ADC_Channel_1,获取ADC的值 printf(“adc_Value:%dn”,adc_Value);//通过串口打印获取ADC的值 temp=(float)adc_Value*(3.3/4096);//转换ADC的值,得到具体的电压 printf(“temp:%fn”,temp);//通过串口打印获取电压的值 SysTick_Delay_ms(500); } } 现象: |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1683 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1582 浏览 1 评论
1013 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
703 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1627 浏览 2 评论
1892浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
675浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
538浏览 3评论
557浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
526浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-4 01:01 , Processed in 1.037557 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号