一.基本概念讲解
A/D是我们的模拟量到数字量的转换,依靠的是模数转换器(Analog to Digtial Converter),简称ADC;D/A是数字量到模拟量的转换,依靠的是数模转换器(Digtial to Analog Converter),简称DAC。他们的道理是完全一样的。只是转换的方向完全不同。
什么是模拟量?就是指变量在一定的范围内可以连续变化的量。也就是在一定的范围内可以取任意的指。比如我们的温度计。从0度到100度,可以取任意值。可以是1度,可以是0.01度,也可以是0.0001度等。总之0到100度之间有无限个中间值。所以,称之为连续变量的量。这个就是我们称之的模拟量。如下左图
而我们的温度计被我们人为的刻上了符号,每两个大型的刻度间隔是10度。这个实际上就是我们的对模拟量数字化,由于有一定的间隔,不是连续的,所以,我们专业的说法叫做离散的。我们的ADC就是把连续的信号用离散的数字表达处理啊。我们的ADC就是模拟量转换成数字量的一种机制。
注:
模拟量可以是电压、电流等电信号,也可以是压力、温度、湿度、位移、声音等非电信号。但在A/D转换前,输入到A/D转换器的输入信号必须经各种传感器把各种物理量转换成电压信号。
A/D转换后,输出的数字信号可以有8位、10位、12位、14位和16位等。
二.A/D转换器的主要技术指标
① 分辨率:数字量变化一个小量时模拟信号的变化量,定义为满刻度与 2n 的比值。分辨率又称精度,通常以数字信号的位数来表示。,它表示对模拟信号进行数字化能够达到多细的程度。通常用数字量的位数表示,如8位、12位、16位分辨率等。若分辨率为8位,能够表示的大数字是255。若是我们输入的电压位12V,那么其分辨率位12 / 255 = 0.047v(约等于0.047v)也就是说模拟量的输入必须以0.047为单位变大或变小,其输出的数字量才会有变化,例如:11.953~12.000的模拟量其输出数字量都为255.分辨率越高,转换时对输人量的微小变化的反应越灵敏。
②量程:即所转换的电压范围。单极性工作的芯片有以0V为基准的0~+10V,0~-10V等;双极性工作的芯片有以0V为基准的±5V,±10V等。
③转换时间和转换率:完成一次A/D转换所需要的时间称为转换时间,转换时间的倒数称为转换率。不同形式、不同分辨率的器件,其转换时间的长短相差很大,可为几微妙到几百毫秒。在选择器件时,要根据应用的需要和成本,对这项指标加以考虑,有时还要同时考虑数据传输过程中转换器件的一些结构和特点。
MSPS--Million Samples per Second
采样时间则是另外一个概念,是指两次转换的间隔。为了保证转换的正确完成,采样速率(Sample Rate)必须小于或等于转换速率。因此有人习惯上将转换速率在数值上等同于采样速率也是可以接受的
例如:
我们有一把塑料尺子,它的量程是10厘米,上面有100个刻度,能够都出来的小的单位是1毫米有效值,那么我们就说我们这个尺子的分辨率为1毫米。
三.电路图分析
我们观察到开发板上有一个电位器(滑动变阻器),上面的编号为VR1,我们就可以通过搜索VR1来观察滑动变阻器的阻值情况。
在《FS4412-DevBoard-V5.pdf》搜索VR1(或者直接搜索ADC),观察到下图。
当我们的滑动变阻器变化的时候,通过检测XadcAIN3引脚电压变化转换车成数字。
我们在芯片手册《FS4412_CoreBoard_V2.pdf》中,同样搜索到的内容如下:
三.芯片手册大致翻译
56 ADC
56.1 ADC 概述
10 位或 12 位 CMOS 再循环式模拟数字转换器,它具有 4 通道输入,并可将模拟量转换为 10 位或 12位二进制数。 5MHz A/D 转换时钟时,大 1MSPS(Million Samples per Second)。 A/D 转换操作具有样本保持的功能,同时也支持降功耗模式。
特性
ADC 接口包括如下特性:
Ø 10bit/12bit 输出位可选。
Ø 微分误差±2.0LSB。
Ø 积分误差±4.0LSB。
Ø 大转换速率: 1 Msps。
Ø 功耗少,电压输入 3.3v。
Ø 模拟量输入范围: 0~3.3v。
Ø 支持片上样本保持功能。
Ø 通用转换模式。
56. ADC 选择
Exynos 4412 SCP 有2个ADC 设备块,分别是ADC和MTCADC_ISP。我们可以选择其中一个ADC块设备,通过设置SFR(special function register)寄存器中的ADC_CFG[16]来选择。
56.4.2 A/D 转换时间
当一个PLCK 时钟频率是66MHZ,并且分频值是65,选择的是12位的分辨率的时候。
我们的计算公式如下:
完成一次 A/D 转换需要 5 个时钟周期。 A/D 转换器的大工作时钟为 5MHz,所以大的采样率可以达到 1Mbit/s。
56.4.3 ADC 转换模式
转换模式中AIN0~AIN3是类似的。若是需要初始化这个模式,通过设置ADCCON(ADC控制寄存器)即可. 转换的数据可以通过ADCDAT这个寄存器来读。
ADC编程步骤:
设置预分配器
根据上述公式,我们选择预分配位255,终得到的结果位
ADCCON[14] = 1; //使能分配器
ADCCON[6:13] = 0xff //选择分配系数
时钟频率 100 MHZ /(255 + 1) = 25 / 64 MHZ
(2) 设置精度(选择分辨率 8位,12位等)
ADCCON[16] = 1 //选择12bit 的A/D转换
注:量化位数是12位,那么数字表示的范围是0~4096
假如我们输入小的电压范围位0~1.8V,那么我们
低有效位1LSB 表示大小 1.8V / 4096 。
当我们量化的位数越大的时候,每位能给你识别的电压越小,精度越高。
(3) 选择通道
ADCMUX[3:0] = 0011
(4)使能,启动A/D转换
注:由图所知,我们的可以选择ADCCON [0]和ADCCON[1].
ADCCON[0] 使能A/D转换开始。我们知道当我们的A/D转换开始后,若是
我们读了之后,这位会被自动的清除。故我们每次都需要设置。
ADCCON[1] A/D转换由读来开始。通过读来使能开始,我们知道了,当我们
读了一次之后,我们的A/D转换才开始,若是不读的话,我们的
A/D转换不会启动。
//ADC转换后的数值
ADCCON[2] = 0 //选择正常模式
ADCCON[1] = //使能读功能,可以读ADCDAT中的信息
temp = ADCDAT[0 : 11] //读取一次后,转换开始。若是不读取,A/D转换不会启动。
(1) 获得转换后-的数值
While(!(ADDCCON[15] == 1)) //每次读取结束后ADDCCON的值会自动设置位1表示结束
Temp = ADCDAT[0 : 11]
代码简介:
void adc_init()
{
//enable prescaler
REG_WRITE(ADCCON,REG_READ(ADCCON) | (1 << 14));
//prescaler 256
REG_WRITE(ADCCON,(REG_READ(ADCCON) & ~(0Xff << 6)) | (0xff << 6));
//设置精度 12bit
REG_WRITE(ADCCON,REG_READ(ADCCON) | (1 << 16));
//选择通道3
REG_WRITE(ADCMUX,(REG_READ(ADCMUX) & ~(0Xf)) | (0x3));
//normal 模式
REG_WRITE(ADCCON,REG_READ(ADCCON) & ~(1 << 2));
//设置通过的读的方式使能adc转换
REG_WRITE(ADCCON,REG_READ(ADCCON) | ( 1 << 1));
//读一次之后,启动我们的ADC
adcval = REG_READ(ADCDAT);
}
int adc_read()
{
int val;
while(!(REG_READ(ADCCON) & (1 << 15)));
val = REG_READ(ADCDAT) & 0xfff;
return val;
}
int main()
{
adc_init();
while(1)
{
adcval = adc_read();
delay_ms(500);
uart_printf("adc = %d\r\n",adcval);
}
return 0;
}