ARM接口技术——ADC
ADC简介
ADC
ADC(Analog to Digital Converter)即模数转换器,指一个能将模拟信号转化为数字信号的电子元件。
ADC分辨率
ADC的分辨率一般以输出二进制数的位数来表示,当最大输入电压一定时,位数越高,分辨率越高;
n位的ADC能区分输入电压的最小值为满量程输入的1/2^n;
比如一个12位的ADC,最大输入电压为1.8v,那么该ADC能区分的最小电压为1.8v/2^12≈0.00044v;
当转换的结果为m时,则实际的电压值为m*(1.8v/2^12);
SOC下的ADC实验
实验分析
实验使用的是一个滑动变阻改变电压的模拟信号输入;
SOC芯片使用的是Exynos4412,它集成了ADC转换器,无需再加装ADC转换器,只需要把模拟信号输入与ADC功能的引脚相连即可。
(Exynos4412没有集成DAC模块,如果需要输出模拟信号,要自己添加DAC芯片,或者使用PWM的方法)
电路原理图:
外围电路:
VDD1V8_EXT就是SOC外围电路的电源1.8V,5号导线位置是一个滑动变阻器,滑动可以改变XadcAIN3端的电压值(0-1.8V)。
XadcAIN3与SOC核心板ADC模块连接。
核心板:
Exynos4412大部分引脚都是有复用功能,而提供的这4个ADC引脚是专用输入模拟信号的引脚,只有一个名字XadcASINn,所以不需要对引脚功能进行设置;
我们使用的是XadcASIN3。
芯片手册ADC模块的说明:
Overview:
主要有三个关键信息:
它的模拟精度可以配置成10为和12位;
ADC最大转换速度是1MSPS;
输入的电压范围为0-1.8V。
ADC的转换速度:
ADC的转换需要一个时钟,以说明为例,66MHz的时钟分频成1MHz给ADC,ADC每5个周期转换一次,所以转换频率是200MSPS,转换一次的时间是5us。
(实际使用的是PCLK = 100MHz)
前面提到ADC的最大转换速度是1MSPS,对应的时钟频率是5MHz,所以给ADC的时钟频率不能超过5MHz,使用的是PCLK,那么需要至少分频20。
芯片手册ADC相关寄存器
寄存器摘要:
本实验主要使用3个寄存器,分别是ADC配置寄存器、ADC存放数据的寄存器和ADC通道选择寄存器(前面提到有4个ADC通道)。
1). ADCCON
- RES位用于选择转换精度,我们选择12位,RES=1;
- ECFLG用于查看转换是否完成,这里用于读;
- PRSCEN用于打开时钟分频,PRSCEN=1;
- PRSCVL用于设置分频的大小,我们使用的时钟与例子相同,所以19分频是极限值,我们设大一点,PRSCVL=25;
- STANDBY用于设置功耗模式,我们就设置为正常工作,STANDBY=0;
- READ_START和ENABLE_START用于设置ADC的触发方式。
- READ_START设为1,ADC会自动进行一次转换,但是它不会进行下一次转换,而是被读了之后,才会自动进行一次转换;
- ENABLE_START设为1,ADC就会开始一次转换,转换完以后,它会自动变成0,进行下次转换需要写1。
2). ADCDAT
存放了ADC转换的结果,只需要读即可,需要注意的是读取时高位要清0,因为它是无效位,可能会有随机值。
3). ADCMUX
芯片只有1ADC转换器,但是有多个模拟输入引脚,它使用的是分时复用;
所以需要告诉ADC转换哪个模拟输入的引脚,ADCMUX = 0011。
实验代码
#include "exynos_4412.h" void ADC_Init(unsigned int channel) { /* 设置ADC转换精度 */ ADCCON |= (1<<16); /* 打开分频器 */ ADCCON |= (1<<14); /* 设置20分频 */ ADCCON = ADCCON & (~(0xFF<<6)) | (19<<6); /* 关闭待机模式 */ ADCCON = ADCCON & (~(1<<2)); /* 关闭读触发AD转换的方式 */ ADCCON = ADCCON & (~(1<<1)); /* 设置AD转换通道 */ ADCMUX = channel; } int main() { unsigned int value; ADC_Init(3); while(1) { ADCCON |= 1; /* ADC开始一次转换 */ while(!(ADCCON & (1<<15))); value = ADCDAT & 0xFFF; /* 读取相对电压 */ value *= 0.44; /* 转换成实际电压,单位为mV */ printf("%d mV\n", value); /* 重定向到UART的printf,在另一个文件实现 */ } return 0; }
实验现象
END