嵌入式应用设计课程设计报告-linux数据采集课设报告.doc_第1页
嵌入式应用设计课程设计报告-linux数据采集课设报告.doc_第2页
嵌入式应用设计课程设计报告-linux数据采集课设报告.doc_第3页
嵌入式应用设计课程设计报告-linux数据采集课设报告.doc_第4页
嵌入式应用设计课程设计报告-linux数据采集课设报告.doc_第5页
免费预览已结束,剩余11页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

北 华 航 天 工 业 学 院课程设计报告(论文)设计课题:linux系统下系统的数据采集专业班级: 学生姓名: 指导教师: 王达伟 设计时间: 2011年12月 北华航天工业学院电子工程系10 嵌入式应用设计 课程设计任务书姓 名:专 业:电子信息工程班级:指导教师:王达伟职 称:讲师课程设计题目:linux系统下系统的数据采集设计要求:(1)根据技术指标确定硬件实现方案,画出系统的电路原理图(2)确定软件流程图,并编写程序(3)在超级终端显示测量电压值(4)提交设计报告技术指标:(1)输入电压范围0-2.5v(2)电压分辨率2.4mv所需仪器设备:计算机 嵌入式系统实验箱 虚拟机vmware和red hat9成果验收形式:上机验收参考文献:1 孟庆春,牛欣源著. linux教程.电子工业出版社.2 张玲,周旭著. linux操作系统原理与应用.西安电子科技大学出版社.3 魏永明,耿岳等译. linux设备驱动程序.中国电力出版社.时间安排第17周到18周完成设计题目指导教师:王达伟 教研室主任:王俊红2011年 12月28日 内 容 摘 要嵌入式系统是嵌入式计算机系统的总称。linux是嵌入式操作系统中的一种应用比较广泛的操作系统。嵌入式linux 是一种适用于嵌入式系统的源码开放的占先式实时多任务操作系统,是目前操作系统领域中的一个热点,其重点与难点是驱动程序的开发。开发嵌人式linux 下的设备驱动程序,可以更好地利用新硬件特性,提高系统访问硬件的效率,改善整个应用系统的性能。驱动程序修改非常方便,使应用系统非常灵活。linux的驱动开发中模块方式调试效率很高,它使用insmod工具将编译的模块直接插入内核,如果出现故障,可以使用rmmod从内核中卸载模块,不需要重新启动内核,这使驱动调试效率大大提高。a/d转换器是模拟信号源和cpu之间联系的接口,它的任务是将连续变化的模拟信号转换为数字信号,以便计算机和数字系统进行处理、存储、控制和显示。本设计是在linux环境下对s3c2410芯片的8通道10位a/d的操作与控制实现数据的转换采集。通过调整三个按钮。采集出的数据会随之变化。索引关键词:嵌入式 linux 驱动程序 a/d转换 数据采集 目 录一 概 述 1二 实验原理 1二 方案设计 3三 实验步骤 3 四 程序源代码 6五 结论及体会9 六 参考文献 101、 概述 本课程设计通过编写驱动程序以及测试程序并进行编译,在linux系统下实现模拟数据转换成数字数据并采集。linux 中的驱动设计是嵌入式linux 开发中十分重要的部分,驱动程序的作用是应用程序与硬件之间的一个中间软件层,为应用程序展现硬件的所有功能。linux 的驱动开发调试有两种方法,一种是直接编译到内核,再运行新的内核来测试;二是编译为模块的形式,单独加载运行调试。模块方式调试效率很高,它使用insmod 工具将编译的模块直接插入内核,如果出现故障,使用rmmod 从内核中卸载模块。不需要重新启动内核,这使驱动调试效率太大提高。a/d转换器是模拟信号源和cpu之间联系的接口,它的任务是将连续变化的模拟信号转换为数字信号,以便计算机和数字系统进行处理、存储、控制和显示。在工业控制盒数据采集及许多其他领域中,a/d转换是不可缺少的。2、 实验原理3.1 a/d 转换器 a/d转换器是模拟信号源和 cpu之间联系的接口,它的任务是将连续变化的模拟信号转换为数字信号,以便计算机和数字系统进行处理、存储、控制和显示。在工业控制和数据采集及许多其他领域中,a/d 转换是不可缺少的。 a/d 转换器有以下类型:逐位比较型、积分型、计数型、并行比较型、电压频率型,主要应根据使用场合的具体要求,按照转换速度、精度、价格、功能以及接口条件等因素来决定选择何种类型。常用的有以下两种: 1、双积分型的 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。因此适用于模拟信号变化缓慢,采样速率要求较低,而对精度要求较高,或现场干扰较严重的场合。例如在数字电压表中常被采用。2、逐次逼近型的 a/d 转换器 逐次逼近型(也称逐位比较式)的a/d 转换器,应用比积分型更为广泛,其原理框图如图1 所示,主要由逐次逼近寄存器sar、d/a 转换器、比较器以及时序和控制逻辑等部分组成。它的实质是逐次把设定的sar 寄存器中的数字量经d/a转换后得到电压vc与待转换模拟电压v。进行比较。比较时,先从sar的最高位开始,逐次确定各位的数码应是“1”还是“0”,其工作过程如下: 转换前,先将 sar 寄存器各位清零。转换开始时,控制逻辑电路先设定sar 寄存器的最高位为“1” ,其余位为“0” ,此试探值经 d/a 转换成电压 vc,然后将 vc 与模拟输入电压vx比较。如果 vxvc,说明 sar最高位的“1”应予保留;如果 vxvc,说明 sar 该位应予清零。然后再对sar寄存器的次高位置“1” ,依上述方法进行 d/a 转换和比较。如此重复上述过程,直至确定 sar 寄存器的最低位为止。过程结束后,状态线改变状态,表明已完成一次转换。最后,逐次逼近寄存器 sar 中的内容就是与输入模拟量 v 相对应的二进制数字量。显然 a/d转换器的位数 n 决定于 sar 的位数和 d/a 的位数。图 1(b)表示四位 a/d 转换器的逐次逼近过程。转换结果能否准确逼近模拟信号,主要取决于 sar和 d/a的位数。位数越多,越能准确逼近模拟量,但转换所需的时间也越长。 逐次逼近式的 a/d 转换器的主要特点是:转换速度较快,在 1100/s 以内,分辨率可以达 18 位,特别适用于工业控制系统。转换时间固定,不随输入信号的变化而变化。抗干扰能力相对积分型的差。例如,对模拟输入信号采样过程中,若在采样时刻有一个干扰脉冲迭加在模拟信号上,则采样时,包括干扰信号在内,都被采样和转换为数字量,这就会造成较大的误差,所以有必要采取适当的滤波措施。(a)逐次渐进式a/d转换原理图 (b)逐次逼近过程原理图图1 逐次逼近式a/d转换器3、 方案设计本课题是基于linux操作系统的数据采集,应用试验箱上面的adc模块,通过编写linux对应的adc模块驱动程序实现数据采集功能,并通过minicom显示在超级终端上面。课题完成过程中应完成以下任务:1、了解嵌入式系统实验箱核心板及adc模块的电路原理图及工作原理。2、 理解无操作系统情况下(把s3c2410作为一个32位的单片机),用片上集成的adc模块实现数据采集的工作过程。3、 熟悉linux文件系统,掌握linux字符设备驱动程序开发原理及的流程,理解用户应用程序调用内核设备驱动程序的过程。 4、使用通用的linux操作,编写简单的字符设备驱动程序,完成应用程序调用字符设备驱动程序,深入理解程序执行过程。5、编写adc模块的设备驱动程序,在实验箱上验证编写的设备驱动程序。利用minicom,显示结果显示在pc机的终端上。 4、 实验步骤1、准备工作1.1、虚拟机设置如下:a、将vmware联网改为桥接方式,顺序选中菜单vmsettingshardwarenetwaor adapter,在弹出对话框的右边将network connection,改为bridged;b、顺序选中菜单editvirtual network editorhost virtual network mapping,在弹出的对话框中选“host virtual network mapping”属性页,为vmnet0选为计算机网卡,如图2:图2主机虚拟网络映射方式设置c、将f盘共享;d、关闭防火墙,运行命令 #chkconfig iptables offe、重启nfs和portmap服务,运行命令#service nfs restart#service portmap restart1.2、nfs挂载配置如下:主机:ip:192.168.1.168 子网掩码:255.255.255.0 网关:192.168.1.1 dns:192.168.1.1linux:ip:192.168.1.169 子网掩码:255.255.255.0 网关:192.168.1.1 dns:192.168.1.11.3、将f盘的adc目录拷贝到linux下地/root/myjob目录下: 执行命令:cp /mnt/hgfs/f/adc rf /root/myjob2、编译adc驱动文件并挂载到试验箱的操作系统下2.1、进入/root/myjob/adc目录,修改makefile文件(在实验箱上运行的版本)kerneldir = /arm2410cl/kernel/linux-2.4.18-2410cl/#kerneldir=/usr/src/linux-2.4.20-8includedir = $(kerneldir)/include#cross_compile=cross_compile=/opt/host/armv4l/bin/armv4l-unknown-linux-其它地方不用修改,存盘退出2.2、回到/root/myjob/adc目录,编译程序,运行命令:#make2.3、挂载/root/myjob到试验箱步骤如下:a、进入试验箱操作系统,运行命令minicom同时重启试验箱:b、设置试验箱的ip、网关,运行命令:yaffsifconfig eth0 192.168.1.163 netmask 255.255.255.0yaffsroute add default gw 192.168.1.1c、运行完以上步骤即可挂载,运行命令yaffsmount t nfs o nolock 192.168.1.169:/root/myjob /mnt/nfs3、运行调试程序 1、插入模块,运行命令yaffsinsmod adc.o2、运行调试程序,运行命令yaffs./test_adc.o 运行结果如下:/mnt/nfslsadc cross-2.95.3.tar.bz2 demo.cbusybox-1.00-pre10 demo target/mnt/nfscd adc/mnt/nfs/adclsmakefile adc.c adc.o test_adc.c test_adc.o/mnt/nfs/adcinsmod adc.ousing adc.oadc initialized/mnt/nfs/adc./test_adc.odevice open sucess!channel 0 value: 2.252637channel 1 value: 3.280664channel 0 value: 2.252637channel 1 value: 3.2806645、 程序源代码1.驱动程序源代码使用vi编辑器或其他编辑器阅读理解源代码。其中adc_read,adc_write函数完成驱动的读写接口功能,do_write函数实现将用户写入的数据逆序排列,通过读取函数读取转换的数据。这里只是演示接口的实现过程和内核驱动对用户的数据的处理。adc_ioctl函数演示ioctl调用接口的实现过程。驱动代码sinosys-adc.c如下:#include #include #include #include /* printk() */#include #include #include #include #include #include #undef debug#ifdef debug#define dprintk(x.) printk(_function_(%d): ,_line_);printk(#x);#else#define dprintk(x.) (void)(0)#endif#define start_adc_ain(x) adccon = prescale_en | prscvl(255) | adc_input(x) ; adccon |= adc_start; #define device_name sinosys /*设备的目录名为sinosys*/#define adc_major 254 /*主设备号为254*/#define adc_minor 0 /*从设备号为0*/#define channel_iow(p, 0xa2,int) /*定义ioctl号*/#define max_channel 2 /*最大的通道数*/ static struct semaphore adc_lock; /*锁*/static wait_queue_head_t adc_wait; /*等待队列*/static unsigned int adc_ain; /*当前通道*/static void adcdone_int_handler(int irq, void *dev_id, struct pt_regs *reg)dprintk(adcdone_initn);wake_up(&adc_wait); /*唤醒等待队列*/*adc的原始读函数*/int s3c2410_adc_read(int ain)int ret = 0;if (down_interruptible(&adc_lock) /*加锁*/return -erestartsys;start_adc_ain(ain); /*启动adc转换过程*/sleep_on_timeout(&adc_wait, hz/100); /*把程序加到等待队列中*/ /*超时值为hz/100(10ms)*/ret = adcdat0 ; /*苏醒到代表adc转换结束,以读取adc的值*/up(&adc_lock); /*解锁*/adc_wait = null;dprintk(ain%d = 0x%04x, %dn, ain, ret, adccon & 0x80 ? 1:0);return (ret & 0x3ff); /*返回adc中的转换值*/static ssize_t adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)int retval ;retval = s3c2410_adc_read( adc_ain ); /*调用adc原始读函数*/dprintk(the value of channel %d : %xn, adc_ain, retval);retval = put_user(retval, (int *)buffer); /*把数据传回用户空间*/if (!retval)retval = sizeof(unsigned long);return retval;/*io口控制函数*/static ssize_t adc_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg)switch(cmd)case channel:dprintk(change to adc channel %dn,(int)arg);if (int)arg max_channel) adc_ain = (int) arg;break;default:dprintk(error cmd numbern);break;return 0;static ssize_t adc_open(struct inode *inode, struct file *file)mod_inc_use_count;printk(device open sucess!n);adc_ain = 0;return 0;static ssize_t adc_release(struct inode *inode, struct file *filp)mod_dec_use_count;printk(device releasen);return 0;static struct file_operations adc_fops = owner: this_module,read: adc_read,ioctl: adc_ioctl,open: adc_open,release: adc_release,;#ifdef config_devfs_fsstatic devfs_handle_t devfs_adc_dir, devfs_adcraw;#endifint _init s3c2410_adc_init(void)init_mutex(&adc_lock); /*初始化锁*/init_waitqueue_head(&adc_wait); /*初始化等待队列*/* normal adc */adctsc = 0; /xp_pst(nop_mode); /*设定adc寄存器初值*/if (request_irq(irq_adc_done, adcdone_int_handler, sa_interrupt,adc, null) 0) /*申请中断*/goto irq_err;#ifdef config_devfs_fs /*建立sinosys设备目录*/devfs_adc_dir = devfs_mk_dir(null, device_name, null);devfs_adcraw = devfs_register(devfs_adc_dir, adc, devfs_fl_default,adc_major, adc_minor, s_ifchr | s_irusr | s_iwusr,&adc_fops, null);#elseint result;set_module_owner(&adc_fops);result = register_chrdev(adc_major, scullc, &adc_fops);if (result 0) return result;/ if (adc_major = 0) adc_major = result; /* dynamic */#endifprintk(device_name initializedn);return 0;irq_err:return 1;module_init(s3c2410_adc_init); /*定义模块的初始化函数为s3c2

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论