【电子电路基础实验】模数转换器(ADC)与采样

本文探讨了ADC(模数转换器)的特性,着重比较了定时器触发和自激采样方式。作者通过实例分析了XPT2046 ADC的工作原理,介绍了采样速率、位数及通道切换时间等关键参数,并展示了不同采样方式下如何影响系统的性能,如定时器触发的稳定性对傅里叶变换的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  今天天气晴,万里无云,ADC与采样是模拟世界与数字世界的桥梁,今天自然是个探索它们的好日子。
请添加图片描述

前言

  以下对于采样的简单描述摘录自《自动控制原理与设计(第六版)》(Gene F.Franklin,J.David Powell,Abbas Emami-Naeini,著;李中华等,译)第八章“数字控制”。

  1. 数字系统处理可测量对象输出的采样(sample)信号,而非连续信号。
    请添加图片描述
  2. 模数转换器, analog-to-digital converter, A/D对一个物理量进行采样,比如最常见的电压,并将电压转换成一个通常为10-16位的二进制数。
  3. 对连续信号进行采样,是模拟信号y(t)转换为采样值y[kT]的过程(k∈Z, y[kT]通常简写为y[k]),每隔T秒的时间间隔重复进行一次。T即为采样周期(sample period),1/T为采样速率(sample rate),单位是赫兹(Hz)。
    请添加图片描述
  4. 通常在数字采样系统中有两种采样方式。
      其一是使用定时器触发采样过程,计算机每隔T秒提供一个脉冲或中断,随之触发一次采样过程,这种方式下采样周期T是固定的。
      其二是“自激(free running)采样”,这种情况下,采样过程在每一个代码执行周期运行一次,若不存在逻辑分支,采样周期本质上是由代码决定的(当然我个人认为程序不存在逻辑分支这点很难满足)。
  5. 一般来说,采样速率应大约为系统闭环带宽的20倍或更高,才能保证数字控制器与连续控制器的性能相匹配。数字控制器的最佳性能是,当采样率大于25倍闭环带宽时才能达到。
    请添加图片描述

一、ADC特性与自激(free running)采样

  我手里面开发板上的ADC并不是前面图中的ADC0804,而是XPT2046,这颗芯片对市场宣传是电阻触摸屏控制器,但是它本质上是多路ADC转换器,这开发板的设计师还是机智,这么弄肯定又省钱了。但是此行的主要目更多是要考虑一些ADC的关键性能指标,所以操作芯片的代码直接就ctrl+c,ctrl+v,在此基础上进一步分析。

  1. adc的采样率:本例典型值125kHz。区别于“前言”中提到的采样速率,这里指的是ADC转换速率有多快,而不是多长时间间隔对信号采集一个数。这个参数部分决定了一次完整的AD转换要花多长时间。
  2. adc的位数:本例典型值12bits。
  3. 通道切换时间。因为这是一个多通道ADC,所以要考虑这个指标。

  对于“adc采样率”指标,只讨论125kHz采样率的意义并不是太大。这颗芯片采用spi接口通信,每次转换都要先发送指令码指定工作参数,然后adc才启动转换,将数据通过spi接口发送到单片机,要考虑的并不仅仅只是adc的转换速度。
请添加图片描述
请添加图片描述
  另外,关于通道切换时间的问题。本例中也不存在通道切换时间的问题,观察上面的时序图,手册上指出A2,A1,A0用来指定接下来ADC要转换哪个通道,也就是说,每次启动转换之前都必须指定通道,也就不存在所谓通道切换的问题。

  这种情况直接看代码的执行时间比较靠谱。从上面的时序来看adc采样并不需要任何分支结构,demo里面采样函数里面也确实没有,因而可以大胆地相信仿真结果,采集一次adc的时间为定值440.54us。现在采样率只有2269Hz了。

extern unsigned int xpt2046_read_adc_value(unsigned char cmd);

void main(){
	unsigned int adc_value = 0;	
	float adc_vol;//ADC电压值
	unsigned char adc_buf[3];
	while(1){
		#error "STC89C52ERC,11.0592MHz晶振.下面的ADC采样函数执行时间 = 定值440.54us"				
		adc_value=xpt2046_read_adc_value(0x94);//测量电位器
		
		#error "下面的代码运行时间也是固定的,为4240.45us"
		adc_vol=5.0*adc_value/4096;//将读取的AD值转换为电压
		adc_value=adc_vol*10;//放大10倍,即保留小数点后一位
		adc_buf[0]=gsmg_code[adc_value/10]|0x80;
		adc_buf[1]=gsmg_code[adc_value%10];
	   	adc_buf[2]=0x3e;//显示单位V
		smg_display(adc_buf,6);			
	}		
}

  自激采样的采样过程发生在主循环中,也就是上面代码所展示的情况,此时的采样周期T实际上是440.54+4240.45 = 4681us,采样速率f = 1/T = 205Hz。

  自激采样在程序简单,没有程序分支时很好用,非常稳定。比如上面的程序,采集完电压之后就做一个数码管显示,实际上就是一个单纯的电压表。

二、定时器触发ADC采样

  考虑对一个信号进行离散傅里叶变换,这时候就会对采样周期T的时间长度以及T的稳定性提出要求。有一种说法是时间实际上是我们看待高维空间的方式,引入时间是实际上进行了升维处理,得以从上帝视角看待问题。而傅里叶变换将一段时间的实信号投影到一个无限维的傅里叶空间中,从直觉上来讲,对采样周期T的长度以及T的稳定性提出要求并不过分。
请添加图片描述
  基于定时器触发的思路是像下面这个样子的。使用这个方法,需要注意协调adc的采样时间,定时器的定时间隔以及主循环中数据处理与决策的运行时间。
请添加图片描述
  按照上图可以写出一个粗略的伪代码框架。

void main(){
    "定时器,adc初始化";
    "启动采样器";
	while(1){
    	if("收到数据采样完成消息"){
    		"数据处理";
    		"更新关键参数";
    		"延时或立即启动下一轮采样"
    	}
    	"决策与其他处理";	
	}		
}

void T0_interrupt(void) interrupt 1{
	"启动采样器并等待采样完成";
	"将数据装入缓冲"
	if("数据采样完成")
		"发送采样完成消息"
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值