嵌入式系统设计实验四(AD接口)(共10页).doc
精选优质文档-倾情为你奉上实验四_1 A/D接口实验4.1、实验目的了解在linux环境下对S3C2410芯片的8通道10位A/D的操作与控制。4.2、实验内容学习A/D接口原理,了解实现A/D系统对于系统的软件和硬件要求。阅读ARM芯片文档,掌握ARM的A/D相关寄存器的功能,熟悉ARM系统硬件的A/D相关接口。利用外部模拟信号编程实现ARM循环采集全部前4路通道,并且在超级终端上显示。4.3、预备知识Ø 有C语言基础。Ø 掌握在Linux下常用编辑器的使用。Ø 掌握Makefile 的编写和使用。Ø 掌握Linux下的程序编译与交叉编译过程。4.4、实验设备及工具硬件:UP-TECH S2410/P270 DVP嵌入式实验平台、PC机Pentium 500以上, 硬盘10G以上。软件:PC机操作系统REDHAT LINUX 9.0MINICOMARM-LINUX开发环境4.5、实验原理1、A/D转换器A/D转换器是模拟信号源和CPU之间联系的接口,它的任务是将连续变化的模拟信号转换为数字信号,以便计算机和数字系统进行处理、存储、控制和显示。在工业控制和数据采集及许多其他领域中,A/D转换是不可缺少的。A/D转换器有以下类型:逐位比较型、积分型、计数型、并行比较型、电压频率型,主要应根据使用场合的具体要求,按照转换速度、精度、价格、功能以及接口条件等因素来决定选择何种类型。常用的有以下两种:Ø 双积分型的A/D转换器双积分式也称二重积分式,其实质是测量和比较两个积分的时间,一个是对模拟输入电压积分的时间T0,此时间往往是固定的;另一个是以充电后的电压为初值,对参考电源Vref反向积分,积分电容被放电至零所需的时间T1。模拟输入电压Vi与参考电压VRef之比,等于上述两个时间之比。由于VRef 、T0固定,而放电时间T1可以测出,因而可计算出模拟输入电压的大小(VRef与Vi符号相反)。由于T0、VRef为已知的固定常数,因此反向积分时间T1与输入模拟电压Vi在T0时间内的平均值成正比。输入电压Vi愈高,VA愈大,T1就愈长。在T1开始时刻,控制逻辑同时打开计数器的控制门开始计数,直到积分器恢复到零电平时,计数停止。则计数器所计出的数字即正比于输入电压Vi在T0时间内的平均值,于是完成了一次A/D转换。由于双积分型A/D转换是测量输入电压Vi在T0时间内的平均值,所以对常态干扰(串摸干扰)有很强的抑制作用,尤其对正负波形对称的干扰信号,抑制效果更好。双积分型的A/D转换器电路简单,抗干扰能力强,精度高,这是突出的优点。但转换速度比较慢,常用的A/D转换芯片的转换时间为毫秒级。例如12位的积分型A/D芯片ADCETl2BC,其转换时间为lms。因此适用于模拟信号变化缓慢,采样速率要求较低,而对精度要求较高,或现场干扰较严重的场合。例如在数字电压表中常被采用。Ø 逐次逼近型的A/D转换器逐次逼近型(也称逐位比较式)的A/D转换器,应用比积分型更为广泛,其原理框图如图2.4.1所示,主要由逐次逼近寄存器SAR、D/A转换器、比较器以及时序和控制逻辑等部分组成。它的实质是逐次把设定的SAR寄存器中的数字量经D/A转换后得到电压Vc与待转换模拟电压V。进行比较。比较时,先从SAR的最高位开始,逐次确定各位的数码应是“1”还是“0”,其工作过程如下:转换前,先将SAR寄存器各位清零。转换开始时,控制逻辑电路先设定SAR寄存器的最高位为“1”,其余位为“0”,此试探值经D/A转换成电压Vc,然后将Vc与模拟输入电压Vx比较。如果VxVc,说明SAR最高位的“1”应予保留;如果Vx<Vc,说明SAR该位应予清零。然后再对SAR寄存器的次高位置“1”,依上述方法进行D/A转换和比较。如此重复上述过程,直至确定SAR寄存器的最低位为止。过程结束后,状态线改变状态,表明已完成一次转换。最后,逐次逼近寄存器SAR中的内容就是与输入模拟量V相对应的二进制数字量。显然A/D转换器的位数N决定于SAR的位数和D/A的位数。图2.4.1(b)表示四位A/D转换器的逐次逼近过程。转换结果能否准确逼近模拟信号,主要取决于SAR和D/A的位数。位数越多,越能准确逼近模拟量,但转换所需的时间也越长。l 逐次逼近式的A/D转换器的主要特点是:转换速度较快,在1100/s以内,分辨率可以达18位,特别适用于工业控制系统。转换时间固定,不随输入信号的变化而变化。抗干扰能力相对积分型的差。例如,对模拟输入信号采样过程中,若在采样时刻有一个干扰脉冲迭加在模拟信号上,则采样时,包括干扰信号在内,都被采样和转换为数字量,这就会造成较大的误差,所以有必要采取适当的滤波措施。图4.1逐次逼近式A/D转换器2、A/D转换的重要指标Ø 分辨率(Resolution)分辨率反映A/D转换器对输入微小变化响应的能力,通常用数字输出最低位(LSB)所对应的模拟输入的电平值表示。n位A/D能反应1/2n满量程的模拟输入电平。由于分辨率直接与转换器的位数有关,所以一般也可简单地用数字量的位数来表示分辨率,即n位二进制数,最低位所具有的权值,就是它的分辨率。值得注意的是,分辨率与精度是两个不同的概念,不要把两者相混淆。即使分辨率很高,也可能由于温度漂移、线性度等原因,而使其精度不够高。Ø 精度(Accuracy)精度有绝对精度(Absolute Accuracy)和相对精度(Relative Accuracy)两种表示方法。l 绝对误差:在一个转换器中,对应于一个数字量的实际模拟输入电压和理想的模拟输入电压之差并非是一个常数。我们把它们之间的差的最大值,定义为“绝对误差”。通常以数字量的最小有效位(LSB)的分数值来表示绝对误差,例如:1LSB等。绝对误差包括量化误差和其它所有误差。l 相对误差是指整个转换范围内,任一数字量所对应的模拟输入量的实际值与理论值之差,用模拟电压满量程的百分比表示。例如,满量程为10V,10位A/D芯片,若其绝对精度为1/2LSB,则其最小有效位的量化单位:9.77mV,其绝对精度为4.88mV,其相对精度为0.048%。l 转换时间(Conversion Time)转换时间是指完成一次A/D转换所需的时间,即由发出启动转换命令信号到转换结束信号开始有效的时间间隔。转换时间的倒数称为转换速率。例如AD570的转换时间为25us,其转换速率为40KHz。l 电源灵敏度(power supply sensitivity)电源灵敏度是指A/D转换芯片的供电电源的电压发生变化时,产生的转换误差。一般用电源电压变化1时相当的模拟量变化的百分数来表示。l 量程量程是指所能转换的模拟输入电压范围,分单极性、双极性两种类型。例如,单极性 量程为0+5V,0+10V,0+20V;双极性 量程为-5+5V,-10+10V。l 输出逻辑电平多数A/D转换器的输出逻辑电平与TTL电平兼容。在考虑数字量输出与微处理的数据总线接口时,应注意是否要三态逻辑输出,是否要对数据进行锁存等。l 工作温度范围由于温度会对比较器、运算放大器、电阻网络等产生影响,故只在一定的温度范围内才能保证额定精度指标。一般A/D转换器的工作温度范围为(0700C),军用品的工作温度范围为(-55+1250C)Ø ARM自带的十位A/D转换器ARM S3C2410芯片自带一个路10位A/D转换器,并且支持触摸屏功能。ARM2410开发板只用作3路A/D转换器,其最大转换率为500K,非线性度为正负.5位,其转换时间可以通过下式计算:如果系统时钟为50MHz,比例值为49,则为A/D转换器频率50 MHz/(49+1) = 1 MHz转换时间1/(1 MHz / 5cycles) = 1/200 kHz(相当于5us)= 5 us表4.1采样控制寄存器的设置寄存器 地址读/写 描述 复位值ADCCON 0x R/W ADC 控制寄存器 0x3FC4 表4.2采样控制寄存器的位描述ADCCON 位 描述 初始设置 ECFLG15 End of conversion flag (read only). 0 = A/D conversion in process 1 = End of A/D conversion0 PRSCEN14 A/D converter prescaler enable. 0 = Disable 1 = Enable 0 PRSCVL13:6 A/D converter prescaler value. Data value: 1 255 Note that division factor is (N+1) when the prescaler value is N. 0xFF SEL_MUX5:3Analog input channel select. 000 = AIN 0 001 = AIN 1 010 = AIN 2 011 = AIN 3 100 = AIN 4 101 = AIN 5 110 = AIN 6 111 = AIN 7 (XP) 0STDBM2 Standby mode select. 0 = Normal operation mode 1 = Standby mode 1 READ_START1 A/D conversion start by read. 0 = Disable start by read operation 1 = Enable start by read operation 0 ENABLE_START0 A/D conversion starts by setting this bit. If READ_START is enabled, this value is not valid. 0 = No operation 1 = A/D conversion starts and this bit is cleared after the start-up. 0 该寄存器的0位是转换使能位,写1表示转换开始。1位是读操作使能转换,写表示转换在读操作时开始。3、4、5位是通道号。13:6位为AD转换比例因子。14位为比例因子有效位,15位为转换标志位(只读)。表4.3A/D转换结果数据寄存器的设置寄存器 地址读/写 描述 复位值 ADCDAT0 0xC R ADC转换数据寄存器 -ADCDAT0:转换结果数据寄存器。该寄存器的十位表示转换后的结果,全为1时为满量程3.3伏。Ø A/D转换器在扩展板的连接A/D转换器在扩展板的接法如图4.2所示,前三路通过电位器接到3.3v电源上。图4.2 A/D转换器在扩展板上的接法4.6、程序分析(关键代码分析)ad驱动对用户来说只是下面的一个文件结构。在用户程序里只需要用到open、 read、 write、 release等内核函数即可。本实验采用的是模块方式加载,可以在实验箱的/mnt/yaffs/ad/ 中找到AD的驱动程序。static struct file_operations s3c2410_fops = owner:THIS_MODULE,open:s3c2410_adc_open,read:s3c2410_adc_read,write:s3c2410_adc_write,release:s3c2410_adc_release,;下面我们对驱动部分重要函数进行说明。ad驱动在内核里的代码我们放到了本次实验的src文件下,s3c2410.h_chip.h里为arm2410头文件s3c2410.h初始化ADC的部分。所有代码也可以到内核里面去阅读。关于驱动知识的基本介绍请见第4章第一小节,本节只作为应用实验的简单例子。static int s3c2410_adc_open(struct inode *inode, struct file *file)init_MUTEX(&adcdev.lock);init_waitqueue_head(&(adcdev.wait);adcdev.channel=0;adcdev.prescale=0xff;MOD_INC_USE_COUNT;DPRINTK( "adc openedn");return 0; /AD通道和比例因子初始化static ssize_t s3c2410_adc_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)int data;if(count!=sizeof(data)/error input data sizeDPRINTK("the size of input data must be %dn", sizeof(data);return 0;copy_from_user(&data, buffer, count);adcdev.channel=ADC_WRITE_GETCH(data);adcdev.prescale=ADC_WRITE_GETPRE(data);DPRINTK("set adc channel=%d, prescale=0x%xn", adcdev.channel, adcdev.prescale);return count; /告诉内核驱动读哪一个通道的数据和设置比例因子#define START_ADC_AIN(ch, prescale) do ADCCON = PRESCALE_EN | PRSCVL(prescale) | ADC_INPUT(ch) ; ADCCON |= ADC_START; while(0)/PRESCALE_EN左移14使位比例因子有效;PRSCVL左移6位设置比例因子;/ADC_INPUT左移3位选择通道;/ADCCON |= ADC_START; ADCCON 0为置1,准备采集数据static ssize_t s3c2410_adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)int ret = 0;if (down_interruptible(&adcdev.lock)return -ERESTARTSYS;START_ADC_AIN(adcdev.channel, adcdev.prescale);interruptible_sleep_on(&adcdev.wait);ret = ADCDAT0;ret &= 0x3ff; /把数据寄存器内容放入变量retDPRINTK("AIN%d = 0x%04x, %dn", adcdev.channel, ret, ADCCON & 0x80 ? 1:0);copy_to_user(buffer, (char *)&ret, sizeof(ret);/把ret变量的内容传给用户缓冲区up(&adcdev.lock);return sizeof(ret); /由内核采集通道数据后把数据放回用户区main.c的代码如下:/* by threewater<threewaterup-> * 2004.06.18 */#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/ioctl.h>#include <pthread.h>#include <fcntl.h>#include "s3c2410-adc.h"#define ADC_DEV "/dev/adc/0raw"static int adc_fd = -1;static int init_ADdevice(void) if(adc_fd=open(ADC_DEV, O_RDWR)<0) printf("Error opening %s adc devicen", ADC_DEV); return -1; static int GetADresult(int channel) int PRESCALE=0XFF; int data=ADC_WRITE(channel, PRESCALE); write(adc_fd, &data, sizeof(data); read(adc_fd, &data, sizeof(data); return data;static int stop=0;static void* comMonitor(void* data) getchar(); stop=1; return NULL;int main(void) int i; float d; pthread_t th_com; void * retval; /set s3c44b0 AD register and start AD if(init_ADdevice()<0) return -1; /* Create the threads */ pthread_create(&th_com, NULL, comMonitor, 0); printf("nPress Enter key exit!n"); while( stop=0 ) for(i=0; i<=2; i+)/采样02路A/D值 d=(float)GetADresult(i)*3.3)/1024.0; printf("a%d=%8.4ft",i,d); usleep(1); printf("r"); /* Wait until producer and consumer finish. */ pthread_join(th_com, &retval); printf("n"); return 0;4.7、实验步骤1、阅读理解源码进入/root/share/exp/basic/04_ad目录,使用vi编辑器或其他编辑器阅读理解源代码。2、编译应用程序运行make产生ad可执行文件(如果已经被别人make过,则先make clean)rootbc /# cd /arm2410cl/exp/basic/04_ad/rootbc 04_ad# makearmv4l-unknown-linux-gcc -c -o main.o main.carmv4l-unknown-linux-gcc -o ./bin/ad main.o -lpthreadarmv4l-unknown-linux-gcc -o ad main.o -lpthreadrootbc 04_ad# lsad hardware.h main.o Makefile.bak s3c2410-adc.hbin main.c Makefile readme.txt src3、下载调试换到minicom终端窗口,使用NFS mount宿主机(虚拟linux)的/root/share到开发板(实验箱)/host目录。rootbc root# minicom/mnt/yaffs mount -t nfs 172.16.38.133:/root/share /host/mnt/yaffsinsmod ad/s3c2410-adc.o/mnt/yaffscd /host/exp/basic/04_ad/host/exp/basic/04_ad./adPress Enter key exit!a0= 0.0032 a1= 3.2968 a2= 3.2968我们可以通过调节开发板上的三个黄色的电位器,来查看a0、a1、a2的变化。4.8、思考题1. 逐次逼近型的A/D转换器原理是什么?2 A/D转换的重要指标包括哪些?3 ARM的A/D功能的相关寄存器有哪几个,对应的地址是什么?4 如何启动ARM开始转换A/D,有几种方式?转换开始时ARM是如何知道转换哪路通道的?如何判断转换结束?专心-专注-专业