嵌入式系统虚拟仪表设计

嵌入式系统虚拟仪表设计

ID:18761741

大小:2.37 MB

页数:39页

时间:2018-09-22

上传者:jjuclb
嵌入式系统虚拟仪表设计_第1页
嵌入式系统虚拟仪表设计_第2页
嵌入式系统虚拟仪表设计_第3页
嵌入式系统虚拟仪表设计_第4页
嵌入式系统虚拟仪表设计_第5页
资源描述:

《嵌入式系统虚拟仪表设计》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

专业综合实践报告——嵌入式系统虚拟仪表设计学生姓名学 号教学院系电气信息学院专业年级自动化2011级指导教师完成日期2015年3月20日 摘要针对传统仪表和现有仪表存在的不足,本文提出了一种新型的虚拟仪表设计方案,采用arm处理器为核心的硬件平台和以嵌入式linux系统为核心的软件平台,并在此基础上采用开放源代码的图形界面库qt开发仪表终端应用程序。该虚拟仪表可读性好,读数精度高,在可移植性、可维护性和成本方面都得到了良好的改善,具有较大的科研价值和商业使用价值本文所介绍的车载虚拟仪表的基本设计思想是将司钻监控系统上安装的各种传感器采集到的数据进行智能化的处理,然后在运行于嵌入式linux系统的使用qt设计的虚拟仪表盘上进行显示,以便于监测各系统的工作状况,如悬重钻压钻速泥浆返回流量泥浆泵冲速立管压力转盘转速转盘扭矩游车高度等,并在某状态出现异常或存在危险时向操作员提示报警。【关键词】:虚拟仪器、司钻监测系统、Linux系统 目录一.绪论11.1虚拟仪器的发展11.2专业综合实践的主要内容1二.嵌入式系统虚拟仪表开发环境32.1嵌入式系统虚拟仪表设计目标32.2开发环境32.2.1QtCreator简介32.2.2Fedora 简介3三.基于ARM处理器的便携式仪表人机接口的设计53.1设计原理及说明53.1.1A/D转换器.............................................................................................................53.1.2A/D转换重要指标.................................................................................................53.2接口总体设计............................................................................................................................63.3ADC及触摸屏接口特殊寄存.....................................................................................................73.3.1ADC控制寄存器....................................................................................................73.3.2ADC开始延时寄存................................................................................................83.3.3ADC转换数据寄存器83.4AD转换程序9四.嵌入式系统虚拟仪表开发224.1QtCreator开发224.2QtCreate编程244.3虚拟仪表运行界面29五.基于Linux操作系统的程序编译和烧写305.1Linux操作系统及其常用命令305.2Linux内核配置315.3终端编译33六.课程设计收获与体会35参考文献36 一.绪论1.1虚拟仪器的发展现代仪器仪表技术是计算机技术和多种基础学科紧密结合的产物。随着微电子技术、计算机技术、软件技术、网络技术的飞速发展,新的测试理论、测试方法、测试领域以及新的仪器结构不断出现,在许多方面已经冲破了传统仪器的概念,电子测量仪器的功能和作用发生了质的变化。在此背景下,1986年美国国家仪器公司(NationalInstruments,NI)提出了虚拟仪器(VirtualInstrument,VI)的概念。尽管迄今为止虚拟仪器还没有一个统一的定义,但是一般认为:虚拟仪器是在PC基础上通过增加相关硬件和软件构建而成的、具有可视化界面的可重用测试仪器系统。作为一种以计算机软件为核心的新型仪器系统,虚拟仪器具有功能强、测试精度高、测试速度快、自动化程度高、人机界面优异、灵活性强等优点,通常被认为是第三代自动测试系统的同义语。使用虚拟仪器系统可以避免仪器编程过程中的大量重复性劳动,从而大大缩短复杂程序的开发时间,并且客户可以用不同的模块来构造自己的虚拟仪器系统,选择统一的测试策略。由于虚拟仪器的功能和性能已被不断提高,如今在许多应用中它已成为传统仪器的主要替代方式。而虚拟仪器的各种优点让用户可放心地舍弃旧的传统测量设备,接受更新型、以计算机为基础的虚拟仪器系统。由于计算机的性能价格比不断改进,使虚拟仪器的价格更为大众化,用户不必再受限于传统仪器的使用限制和昂贵的价格,进一步降低了使用成本,减少了系统的开发费用和系统的维护费用。此外,新型笔记本电脑又把虚拟仪器的便携性和强大功能推向一个新的水平。所有这些必将加快虚拟仪器的发展,使它的功能和应用领域不断增强和扩大。在测量、检测、电信、监控、教育等方面的应用已广泛开展。1.2专业综合实践的主要内容35 司钻英文名称为driller,指的是石油钻井中带班工人的简称,在本设计中司钻系统则是指一套全自动的油井采集监控系统。本系统包括以下功能:嵌入式系统AD数据采集,嵌入式系统电机控制,嵌入式系统虚拟仪表设计,嵌入式系统绞车数据采集,嵌入式系采集统数据显示,嵌入式系统采集曲线显示,嵌入式系统串口通信,嵌入式系统按键输入,嵌入式系统led控制,嵌入式系统音频输出。在此系统中本人主要负责嵌入式系统虚拟仪表设计。本设计要求完成虚拟实验室中虚拟信号发生器和虚拟信号采集器的设计。35 二.嵌入式系统虚拟仪表开发环境2.1嵌入式系统虚拟仪表设计目标本文设计了一种基于QtCreator的虚拟仪表设计。它的主要设计目标是:系统的主要工作是对大量的过程状态参数实时监测、数据存储、数据处理、进行实时数据分析等。因此要求硬件上必须要有实时时钟和优先级中断信息处理电路。2.2开发环境2.2.1QtCreator简介QtCreator是跨平台的QtIDE,QtCreator是Qt被Nokia收购后推出的一款新的轻量级集成开发环境(IDE)。此IDE能够跨平台运行,支持的系统包括Linux(32位及64位)、MacOSX以及Windows。根据官方描述,QtCreator的设计目标是使开发人员能够利用Qt这个应用程序框架更加快速及轻易的完成开发任务。QtCreator包括项目生成向导、高级的C++代码编辑器、浏览文件及类的工具、集成了QtDesigner、QtAssistant、QtLinguist、图形化的GDB调试前端,集成qmake构建工具等。QtCreator 主要是为了帮助新 Qt 用户更快速入门并运行项目,还可提高有经验的 Qt 开发人员的工作效率。使用强大的C++代码编辑器可快速编写代码语法标识和代码完成功能输入时进行静态代码检验以及提示样式上下文相关的帮助代码折叠括号匹配和括号选择模式高级编辑功能使用浏览工具管理源代码集成了领先的版本控制软件,包括Git、Perforce和Subversion开放式文件,无须知晓确切的名称或位置搜索类和文件跨不同位置或文件沿用符号在头文件和源文件,或在声明和定义之间切换为 Qt跨平台开发人员的需求而量身定制集成了特定于Qt的功能,如信号与槽(Signals&Slots)图示调试器,对Qt类结构可一目了然集成了QtDesigner可视化布局和格式构建器只需单击一下就可生成和运行Qt项目。2.2.2Fedora 简介Fedora是一个知名的Linux发行版,是一款由全球社区爱好者构建的面向日常应用的快速、稳定、强大的操作系统。它允许任何人自由地使用、修改和重发布,无论现在还是将来。它由一个强大的社群开发,这个社群的成员以自己的不懈努力,提供并维护自由、开放源码的软件和开放的标准。Fedora项目由Fedora基金会管理和控制,得到了RedHat,Inc.的支持。Fedora是一个独立的操作系统,可运行的体系结构包括x86(即i386-i686),x86_64和PowerPC。Fedora(第七版以前为FedoraCore)是一款基于 Linux 的操作系统,也是一组维持计算机正常运行的软件集合。Fedora由FedoraProject社区开发、红帽公司赞助,目标是创建一套新颖、多功能并且自由和开源的操作系统。Fedora35 项目以社区的方式工作,引领创新并传播自由代码和内容,是世界各地爱好、使用和构建自由软件的社区朋友的代名词。Fedora基于RedHatLinux,在RedHatLinux终止发行后,红帽公司计划以Fedora来取代RedHatLinux在个人领域的应用,而另外发行的RedHatEnterpriseLinux(RedHat企业版Linux,RHEL)则取代RedHatLinux在商业应用的领域。Fedora的功能对于用户而言,它是一套功能完备、更新快速的免费操作系统,而对赞助者RedHat公司而言,它是许多新技术的测试平台,被认为可用的技术最终会加入到RedHatEnterpriseLinux中。Fedora是一个基于Linux的操作系统,旨在为用户提供稳定、安全且易于使用和管理的自由和开源软件。Fedora发行版是Fedora项目的各种自由软件创造中最大的一个。由于其与生俱来的优势,"Fedora"这个单词通常可以用于表达Fedora项目或Fedora发行版二者之中的任意一个。Fedora项目以不同方式发行Fedora:(1)FedoraDVD/CD–包含了所有主要软件包的DVD或CD套装;(2)Live光盘–CD或DVD大小的光盘镜像,可用于创建LiveCD或从USB设备启动,并可选安装到硬盘;(3)最小CD–用于通过HTTP,FTP或NFS安装。您可以通过FedoraLiveUSBCreator或UNetbootin创建LiveUSB版本的Fedora。同时,Fedora项目发布自定义的Fedora版本,称作Fedoraspins。这些版本包含特定的软件包集合,以满足特定种类的用户之需要。Fedoraspins由一些对Fedora有特殊兴趣的小组开发。EnterpriseLinux额外软件包(英文:ExtraPackagesforEnterpriseLinux,EPEL)是由来自FedoraProject的志愿者发起的社区力量,为了创建由高质量的附加软件组成的、用于补足RHEL和其他兼容版本的软件仓库。软件包管理主要由yum实用程序提供。Fedora同样提供图形界面(例如pirut,pup和puplet),用于在更新可用时提供视觉通知。apt-rpm是yum的替代品,对于Debian类发行版的用户来说可能更熟悉。这里,APT被用于管理软件包。额外的软件仓库可以被添加到Fedora,以便安装Fedora软件仓库未提供的软件包。二.基于ARM处理器的便携式仪表人机接口的设计35 3.1设计原理及说明3.1.1A/D转换器  A/D转换器是模拟信号源和CPU之间联系的接口,它的任务是将连续变化的模拟信号转换为数字信号,以便计算机和数字系统进行处理、存储、控制和显示。在工业控制和数据采集及许多其他领域中,A/D转换是不可缺少的。  A/D转换器有以下类型:逐位比较型、积分型、计数型、并行比较型、电压-频率型,主要应根据使用场合的具体要求,按照转换速度、精度、价格、功能以及接口条件等因素来决定选择何种类型。常用的有以下两种:   1)双积分型的A/D转换器  2)逐次逼近型的A/D转换器3.1.2A/D转换的重要指标  (1)分辨率(Resolution)      指数字量变化一个最小量时模拟信号的变化量,定义为满刻度与2”的比值。分辨率又称精度,通常以数字信号的位数来表示。     (2)转换速率(Conversion Rate) 指完成一次从模拟到数字的A/D转换所需的时间的倒数。积分型AfD韵转换时间是毫秒级,属低速A/D,逐次逼近型A/D是微秒级,属中速A/D,全并行/串并行型A/D可达到纳秒级。采样时间则是另外一个概念,是指两次转换的间隔。为了保证转换正确完成,采样速率( Sample Rate)必须小于或等于转换速率。因此有人习惯上将转换速率在数值上等同于采样速率也是可以接受的。(3)量化误差(Quantizing Error) 由AfD的有限分辨率而引起的误差,即有限分辨率A/D的阶梯状转移特性曲线与无限分辨率AfD(理想A/D)的转移特性曲线(直线)之间的最大偏差。通常是1个或半个最小数字量的模拟变化量,表示为1LSB、1/2LSB。    (4)偏移误差(Offset Error)   输入信号为零时输出信号不为零的值,可外接电位器调至最小。     (5)满刻度误差(Full Scale Error)   满度输出时对应的输入信号与理想输入信号值的差。     (6)线性度(Linearity)   实际转换器的转移函数与理想直线的最大偏移,不包括以上三种误差。     其他指标还有:绝对精度( Absolute Accuracy)、相对精度(Relative Accuracy)、微分非线性、单调性和无错码、总谐波失真( Total Harmonic Distotortion,THD)和积分非线性。     3.2接口总体设计35 本文设计的高速高精度数据采集系统有硬件和软件两部分组成。而硬件部分主要完成数据采集、存储功能,软件部分则完成对硬件控制、对采集数据进行处理。Micro2440开发板由核心板Micro2440和底板Micro2440SDK组成,因为本手册描述的是整个开发板的使用说明,因此以下我们简称为Micro2440开发板。Micro2440核心板其实是一个最小系统板,它具有最基本的系统配置:*CPU-三星S3C2440,运行于400Mhz*NORFLASH–2M,很多公司为了节省成本并不提供NORFLASH,这对开发和量产是很不利的*NANDFLASH-256M(可根据用户需求更改为64M-1G)*SDRAM–64M,由2片16-bit宽度的32MSDRAM组成*1个电源指示等和4个用户指示灯*专业复位芯片*在板JTAG*专业电压调节芯片SamsungS3C2440芯片内部总共有8路A/D转换通道,但其转换器只有一个。在常见的设计中,一般AIN4、AIN5、AIN6、AIN7被用作了四线电阻触摸的YM、YP、XM、XP通道;本开发板引出了剩余的AIN0-3,它们位于CON4接口,为了方便测试,其中AIN0直接和一个可调电阻W1连接。模块图:图3.1AD转换器的功能模块图AD转换时间当GCLK频率为50MHz和预分频器(预定标器)值为49,总共10位转换时间如下:AD转换器频率=50MHz/(49+1)=1MHz转换时间=1/(1MHz/5cycles)=1/200KHz=5us35 注:AD转换器设计在最大2.5MHz时钟下工作,所以转换率最高达到500KSPS。AD转换方式(1)AD转换的数据可以通过中断或查询的方式来访问。使用中断方式整个转换时间(从AD转换器开始到转换数据读取)可能会因为中断服务程序的返回时间和数据访问时间而延长。使用查询方式,通过查看ADCCON[15]位(转换标志结束位),ADCDAT寄存器的读取时间可以确定。(2)提供另外的开启AD转换的方法。在ADCCON[1]置1(AD转换开始读取模式),只要转换数据被读取,AD转换同时开始。3.3ADC及触摸屏接口特殊寄存器3.3.1ADC控制寄存器表3.1ADC控制寄存器3.3.2ADC开始延时寄存器表3.2ADC开始延时寄存器35 3.3.3ADC转换数据寄存器表3.3ADC转换数据寄存器0表3.4ADC转换数据寄存器135 3.4AD转换程序4.1AD数据转换程序(查询方式)AD转换的数据可以通过中断或查询的方式来访问。使用中断方式整个转换时间(从AD转换器开始到转换数据读取)可能会因为中断服务程序的返回时间和数据访问时间而延长。使用查询方式,通过查看ADCCON[15]位(转换标志结束位),ADCDAT寄存器的读取时间可以确定。提供另外的开启AD转换的方法。在ADCCON[1]置1(AD转换开始读取模式),只要转换数据被读取,AD转换同时开始。35 noyes开始初始化AD采样通道选择转换是否完成返回启动转换图3.2AD数据转换程序流程图AD数据转换程序:#include"def.h"#include"option.h"#include"2440addr.h"#include"2440lib.h"#include"2440slib.h"#defineREQCNT100//May08,2002SOP#defineADC_FREQ2500000//设定AD的转换频率,应该至少小于PCLK的1/5(10.14Mhz)2.5MHz#defineLOOP10000//延迟的循环次数volatileU32preScaler;//通道设置存储/==================================================================================35 intReadAdc(intch)//读ADC函数,ch决定那个通道被选择,通道数(ch为0-7){inti;staticintprevCh=-1;//定义静态整形变量prevCh存储AD转换通道//ADC设置使能端、设置预分频值为49、选择通道位,选中的通道上的电压被连接到ADrADCCON=(1<<14)|(preScaler<<6)|(ch<<3);//setupchannelhttp:分频使能,写入分频值,选择通道//ADCCON第14位置1,AD转换预分频器始能。//将preScaler赋给ADCCON第6~13位,给AD预分频器赋值。//将Ch值赋给ADCCON第3~5位选择模拟输入通道。if(prevCh!=ch)//判断通道是否切换{rADCCON=(1<<14)|(preScaler<<6)|(ch<<3);//重新设置设置通道ch和预分频值preScalerfor(i=0;i#include#include#include35 #include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include//;自己定义的头文件,因原生内核并没有包含#include"s3c24xx-adc.h"#undefDEBUG//#defineDEBUG#ifdefDEBUG#defineDPRINTK(x...){printk(__FUNCTION__"(%d):",__LINE__);printk(##x);}#else#defineDPRINTK(x...)(void)(0)#endif//;定义ADC转换设备名称,将出现在/dev/adc#defineDEVICE_NAME"adc"staticvoid__iomem*adc_base; /*定义了一个用来保存经过虚拟映射后的内存地址*/35 //;定义ADC设备结构typedefstruct{ wait_queue_head_twait; intchannel; intprescale;}ADC_DEV;staticADC_DEVadcdev;//;声明全局信号量,以便和触摸屏驱动程序共享A/D转换器DECLARE_MUTEX(ADC_LOCK);//;ADC驱动是否拥有A/D转换器资源的状态变量//staticvolatileintOwnADC=0;/*用于标识AD转换后的数据是否可以读取,0表示不可读取*/staticvolatileintev_adc=0;/*用于保存读取的AD转换后的值,该值在ADC中断中读取*/staticintadc_data;/*保存从平台时钟队列中获取ADC的时钟*/staticstructclk*adc_clk;//;定义ADC相关的寄存器#defineADCCON(*(volatileunsignedlong*)(adc_base+S3C2410_ADCCON))//ADCcontrol#defineADCTSC(*(volatileunsignedlong*)(adc_base+S3C2410_ADCTSC))//ADCtouchscreencontrol#defineADCDLY(*(volatileunsignedlong*)(adc_base+S3C2410_ADCDLY))//ADCstartorIntervalDelay#defineADCDAT0(*(volatileunsignedlong*)(adc_base+S3C2410_ADCDAT0))//ADCconversiondata0#defineADCDAT1(*(volatileunsignedlong*)(adc_base+S3C2410_ADCDAT1))//ADCconversiondata1#defineADCUPDN(*(volatileunsignedlong*)(adc_base+0x14))//StylusUp/Downinterruptstatus#definePRESCALE_DIS(0<<14)35 #definePRESCALE_EN(1<<14)#definePRSCVL(x)((x)<<6)#defineADC_INPUT(x)((x)<<3)#defineADC_START(1<<0)#defineADC_ENDCVT(1<<15)//;定义“开启AD输入”宏,因为比较简单,故没有做成函数//#defineSTART_ADC_AIN(ch,prescale) #definestart_adc(ch,prescale)do{ ADCCON=PRESCALE_EN|PRSCVL(prescale)|ADC_INPUT((ch)); ADCCON|=ADC_START;}while(0)/*设置ADC控制寄存器,开启AD转换*//*staticvoidstart_adc(intch,intprescale){   unsignedinttmp;   tmp=PRESCALE_EN|PRSCVL(prescale)|ADC_INPUT(ch); //(1<<14)|(255<<6)|(0<<3);//0100000011000000  //此处writl()的原型是voidwritel(u32b,volatilevoid__iomem*addr),addr是经过地址重映射后的地址   writel(tmp,ADCCON); //AD预分频器使能、模拟输入通道设为AIN0   tmp=readl(ADCCON);   tmp=tmp|ADC_START; //(1<<0);  //0100000011000001    writel(tmp,ADCCON);   //AD转换开始}问题:此函数被调用时为什么地址映射错误?答案应该需要使用专用的函数iowrite32操作。*///;ADC中断处理函数staticirqreturn_tadc_irq(intirq,void*dev_id)35 { //;如果ADC驱动拥有“A/D转换器”资源,则从ADC寄存器读取转换结果 if(!ev_adc)  {  /*读取AD转换后的值保存到全局变量adc_data中,S3C2410_ADCDAT0定义在regs-adc.h中,          这里为什么要与上一个0x3ff,很简单,因为AD转换后的数据是保存在ADCDAT0的第0-9位,          所以与上0x3ff(即:1111111111)后就得到第0-9位的数据,多余的位就都为0*/  adc_data=ADCDAT0&0x3ff;  /*将可读标识为1,并唤醒等待队列*/  ev_adc=1;  wake_up_interruptible(&adcdev.wait); } returnIRQ_HANDLED;}//;ADC读函数,一般对应于用户层/应用层的设备读函数(read)staticssize_tadc_read(structfile*filp,char*buffer,size_tcount,loff_t*ppos){  /*试着获取信号量(即:加锁)*/ if(down_trylock(&ADC_LOCK))  {  return-EBUSY; } if(!ev_adc) /*表示还没有AD转换后的数据,不可读取*/    {     if(filp->f_flags&O_NONBLOCK)        {             /*应用程序若采用非阻塞方式读取则返回错误*/35         return-EAGAIN;        }     else /*以阻塞方式进行读取*/        {             /*设置ADC控制寄存器,开启AD转换*/        start_adc(adcdev.channel,adcdev.prescale);             /*使等待队列进入睡眠*/        wait_event_interruptible(adcdev.wait,ev_adc);        }    } /*能到这里就表示已有AD转换后的数据,则标识清0,给下一次读做判断用*/  ev_adc=0;    /*将读取到的AD转换后的值发往到上层应用程序*/  copy_to_user(buffer,(char*)&adc_data,sizeof(adc_data));    /*释放获取的信号量(即:解锁)*/  up(&ADC_LOCK);  returnsizeof(adc_data); }//;打开ADC设备的函数,一般对应于用户态程序的openstaticintadc_open(structinode*inode,structfile*filp){ intret;  /*normalADC*/ ADCTSC=0; //;初始化中断队列 init_waitqueue_head(&(adcdev.wait)); adcdev.channel=0;//;缺省通道为“0” adcdev.prescale=0xff; /*申请ADC中断服务,这里使用的是共享中断:IRQF_SHARED,为什么要使用共享中断,因为在触摸屏驱动中35      也使用了这个中断号。中断服务程序为:adc_irq在下面实现,IRQ_ADC是ADC的中断号,这里注意:     申请中断函数的最后一个参数一定不能为NULL,否则中断申请会失败,这里传入的是ADC_DEV类型的变量*/ ret=request_irq(IRQ_ADC,adc_irq,IRQF_SHARED,DEVICE_NAME,&adcdev); if(ret)     {         /*错误处理*/       printk(KERN_ERR"IRQ%derror%d ",IRQ_ADC,ret);       return-EINVAL;    } DPRINTK("adcopened ");  return0;}staticintadc_release(structinode*inode,structfile*filp){ DPRINTK("adcclosed "); return0;}staticstructfile_operationsdev_fops={ owner:THIS_MODULE, open:adc_open, read: adc_read, release:adc_release,};staticstructmiscdeviceadc_miscdev={ .minor=MISC_DYNAMIC_MINOR, .name=DEVICE_NAME, .fops=&dev_fops,};staticint__initdev_init(void){35  intret; /* 1,从平台时钟队列中获取ADC的时钟,这里为什么要取得这个时钟,因为ADC的转换频率跟时钟有关。    系统的一些时钟定义在arch/arm/plat-s3c24xx/s3c2410-clock.c中*/ adc_clk=clk_get(NULL,"adc"); if(!adc_clk){  printk(KERN_ERR"failedtogetadcclocksource ");  return-ENOENT; } /*时钟获取后要使能后才可以使用,clk_enable定义在arch/arm/plat-s3c/clock.c中*/ clk_enable(adc_clk); /* 2,将ADC的IO端口占用的这段IO空间映射到内存的虚拟地址,ioremap定义在io.h中。     注意:IO空间要映射后才能使用,以后对虚拟地址的操作就是对IO空间的操作,  S3C2410_PA_ADC是ADC控制器的基地址,定义在mach-s3c2410/include/mach/map.h中,0x20是虚拟地址长度大小*/ adc_base=ioremap(S3C2410_PA_ADC,0x20); if(adc_base==NULL){  printk(KERN_ERR"Failedtoremapregisterblock ");  ret=-EINVAL;     gotoerr_noclk; } /*  3,把看ADC注册成为misc设备,misc_register定义在miscdevice.h中  adc_miscdev结构体定义及内部接口函数在第2步中讲,MISC_DYNAMIC_MINOR是次设备号,定义在miscdevice.h中*/  ret=misc_register(&adc_miscdev);  if(ret)     {35          /*错误处理*/     printk(KERN_ERR"Cannotregistermiscdevonminor=%d(%d) ",MISC_DYNAMIC_MINOR,ret);     gotoerr_nomap;    }   printk(DEVICE_NAME"tinitialized! ");  return0; //以下是上面错误处理的跳转点err_noclk:  clk_disable(adc_clk);  clk_put(adc_clk);err_nomap:  iounmap(adc_base);  returnret;}staticvoid__exitdev_exit(void){  free_irq(IRQ_ADC,&adcdev); //;释放中断 iounmap(adc_base); /*释放虚拟地址映射空间*/ if(adc_clk)  /*屏蔽和销毁时钟*/ {  clk_disable(adc_clk);  clk_put(adc_clk);  adc_clk=NULL; } misc_deregister(&adc_miscdev);35 }//;导出信号量“ADC_LOCK”,以便触摸屏驱动使用35 二.嵌入式系统虚拟仪表开发4.1QtCreator开发1、建立工程图4.1选择工程类型图4.2工程名和路径35 图4.3工程的文件类型图4.5一个完整工程和Qt开发工具栏1、虚拟仪表界面搭建35 图4.6司钻监测系统虚拟仪表界面4.2QtCreate编程Mainwindow.cpp#include"mainwindow.h"#include"ui_mainwindow.h"#include#include#include#includeMainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui->setupUi(this);/******************************************************//******************************************************/35 //////////////dial量程////////////////ui->Dial_2->setScaleArc(0.0,360.0);ui->Dial_2->scaleDraw()->setSpacing(8);ui->Dial_2->setWrapping(false);ui->Dial_2->setReadOnly(true);ui->Dial_2->setRange(0.0,300.0);ui->Dial_2->setScale(-1,2,20);ui->Dial_2->setScaleTicks(0,4,8);QwtDialSimpleNeedle*needle=newQwtDialSimpleNeedle(QwtDialSimpleNeedle::Arrow,true,Qt::blue,QColor(Qt::gray).light(130));ui->Dial_2->setNeedle(needle);ui->Dial->setRange(0.0,200.0);ui->Dial->setScale(-1,2,20);QwtDialSimpleNeedle*needle1=newQwtDialSimpleNeedle(QwtDialSimpleNeedle::Arrow,true,Qt::red,QColor(Qt::gray).light(130));ui->Dial->setNeedle(needle1);ui->Dial_3->setRange(0.0,300.0);ui->Dial_3->setScale(-1,2,20);QwtDialSimpleNeedle*needle2=newQwtDialSimpleNeedle(QwtDialSimpleNeedle::Arrow,true,Qt::black,QColor(Qt::gray).light(130));ui->Dial_3->setNeedle(needle2);QTimer*timer=newQTimer(this);connect(timer,SIGNAL(timeout()),this,SLOT(update()));timer->start(50);//////dial指针转动///////////////////*staticdoubleoffset=0.8;doublespeed=ui->Dial_2->value();if((speed<40.0&&offset<0.0)||(speed>160.0&&offset>0.0)){offset=-offset;}35 staticintcounter=0;switch(counter++%12){case0:case2:case7:case8:break;default:ui->Dial_2->setValue(speed+offset);}*//////////////////////////////////////////////******************************************************//******************************************************///////////////slider量程//////////////////////////QwtSlider*slider=NULL;//ui->Slider=newQwtSlider(parent,Qt::Horizontal,//QwtSlider::TopScale,QwtSlider::Trough);ui->Slider->setHandleSize(30,16);ui->Slider->setRange(0.0,10.0,1.0,0);//ui->Slider_2=newQwtSlider(parent,Qt::Horizontal,//QwtSlider::NoScale,QwtSlider::Trough|QwtSlider::Groove);ui->Slider_2->setRange(0.0,15.0,0.5,5);/*ui->Slider_3=newQwtSlider(parent,Qt::Horizontal,QwtSlider::BottomScale,QwtSlider::Groove);*/ui->Slider_3->setHandleSize(12,25);ui->Slider_3->setRange(1000.0,3000.0,10.0,10);ui->Slider_4->setRange(0.0,100.0,1.0,5);ui->Slider_4->setScaleMaxMinor(5);}MainWindow::~MainWindow(){deleteui;35 }voidMainWindow::changeEvent(QEvent*e){QMainWindow::changeEvent(e);switch(e->type()){caseQEvent::LanguageChange:ui->retranslateUi(this);break;default:break;}}voidMainWindow::update(){//qsrand(time(0));//srand((unsigned)time(NULL));date1=rand()%3+6;date2=rand()%5+8;date3=rand()%200+2700;date4=rand()%10+70;date5=rand()%5+90;date6=rand()%10+85;date7=rand()%50+290;/*说明:8个随机数可用ADC驱动程序中adc_data代替,如果adc_data分时复用,那么虚拟仪表就可以显示具体数据*/staticdoubleoffset=0.8;doublespeed=ui->Dial_2->value();if((speed<40.0&&offset<0.0)||(speed>160.0&&offset>0.0)){offset=-offset;}staticintcounter=0;switch(counter++%12){case0:35 case2:case7:case8:break;default:ui->Dial_2->setValue(speed+offset);ui->Dial->setValue(speed+offset);ui->Dial_3->setValue(speed+offset);}//ui->Dial_2->setOrigin(date7);ui->Slider->setValue(date1);ui->Slider_2->setValue(date2);ui->Slider_3->setValue(date3);ui->Slider_4->setValue(date4);ui->Slider_5->setValue(date5);ui->Slider_6->setValue(date6);}Mainwindow.h#ifndefMAINWINDOW_H#defineMAINWINDOW_H#includenamespaceUi{classMainWindow;}classMainWindow:publicQMainWindow{Q_OBJECTpublic:MainWindow(QWidget*parent=0);~MainWindow();intdate1;intdate2;intdate3;intdate4;intdate5;intdate6;intdate7;protected:voidchangeEvent(QEvent*e);35 publicQ_SLOTS:voidupdate();private:Ui::MainWindow*ui;};#endif//MAINWINDOW_HMain.cpp#include#include"mainwindow.h"intmain(intargc,char*argv[]){QApplicationa(argc,argv);MainWindoww;//->setRange(0.0,260.0);w.show();returna.exec();}4.3虚拟仪表运行界面图4.7虚拟仪表运行35 二.基于Linux操作系统的程序编译和烧写在所有的操作系统中,Linux是一个发展最快、应用最为广泛的操作系统。Linux本身的种种特性使其成为嵌入式开发中的首选。在进入市场的头两年中,嵌入式Linux设计通过广泛应用获得了巨大的成功。随着嵌入式Linux的成熟,提供更小的尺寸和更多类型的处理器支持。很多嵌入式Linux还改造了原来的Linux版本。如:RTLinux通过改造内核实现了实时的Linux;RTAI、Kurt和Linux/RK也提供实时能力;还有uCLinux去掉了Linux的MMU(内存管理单元),能够支持没有MMU的处理器等。与嵌入式裸机编程相比linux操作系统编程有以下特点:转换速度较快,在1—100/µs以内,分辨率可以达18位,特别适用于工业控制系统。转换时间固定,不随输入信号的变化而变化。例如,对模拟输入信号采样过程中,若在采样时刻有一个干扰脉冲迭加在模拟信号上,则采样时,包括干扰信号在内,都被采样和转换为数字量,这就会造成较大的误差,所以有必要采取适当的滤波措施。Linux操作系统开发可以说是裸机系统开发的升级。它可以模拟出相当于实物的操作界面,并且它具有更多的功能。裸机开发也可以说是linux系统开发的基础,二者相辅相成。裸机开发的学习为学习linux系统想开发做了很好的铺垫。5.1Linux操作系统及其常用命令Linux常用命令:基本命令:ls以默认方式显示当前目录文件列表ls-a显示所有文件包括隐藏文件ls-l显示文件属性,包括大小,日期,符号连接,是否可读写及是否可执行cd〈目录〉切换到当前目录下的子目录cd/切换到根目录cd..切换到到上一级目录rm〈file〉删除某一个文件rm-rfdir删除当前目录下叫dir的整个目录(包括下面的文件或子目录)cp〈source〉〈target〉将文件source复制为targetcp/root/source.将/root下的文件source复制到当前目录mv〈source〉〈target〉将文件source更名为targetcat〈file〉显示文件的内容,和DOS的type相同find/path-name〈file〉在/path目录下查找看是否有文件filevi〈file〉编辑文件filemanls读取关于ls命令的帮助35 startx运行Linux图形有环境shutdown-hnow关闭计算机reboot重新启动计算机扩展命令tar压缩、解压文件解压文件tar文件:tarxfxxx.targz文件:tarxzvfxxx.tar.gzbz2文件:tarxjvfxxx.tar.bz2压缩文件tar文件:tarcfxxx.tar/pathgz文件:tarczvfxxx.tar.gz/pathbz2文件:tarcjvfxxx.tar.bz2/pathmount-text2/dev/hda1/mnt把/dev/hda1装载到/mntmount-tiso9660/dev/cdrom/mnt/cdrom将光驱加载到/mnt/cdrommount-tnfs192.168.1.1:/sharedir/mnt将nfs服务的共享目录sharedir加载到/mnt/nfsumount/dev/hda1将/dev/hda1设备卸载,设备必须处于空闲状态ifconfigeth0192.168.1.1netmask255.255.255.0设置网卡1的地址192.168.1.1,掩码为255.255.255.0,不写netmask参数则默认为255.255.255.0ping163.com测试与163.com的连接ping202.96.128.68测试与IP:202.96.128.68的连接5.2Linux内核配置1、将所需要的内核包解压到/opt/friendlyARM/mini2440/下;2、执行命令“#cpconfig_mini2440_l80.config”来使用缺省配置文件“congfig_l80”,然后执行makemenuconfig出现配置内核界面:图4.1配置内核界面35 1、在主菜单里选择退出,使之生成相应配置的头文件,输入命令makezImage,开始编译内核:图4.2内核编译2、编译结束后,会在arch/arm/boot目录下生产Linux内核映像文件:zImage:图4.3生成文件5、通过MiniTools将内核烧写到开发板上。35 5.3终端编译1、复制工程文件所在位置,打开终端,输入命令“cd+空格+文件位置”,得到界面:2、输入命令“make”得到界面:图4.4程序编译图4.5生成映像文件35 3、将生成的映像文件y拷进U盘,插入开发板内,通过超级终端烧写进开发板。35 二.课程设计收获与体会虽说这次课程设计时间不是很长,但是感觉自己收获颇丰,不仅学习到了一些新知识,回顾了以前的一些快要遗忘的知识点,而且使自己的学习目标更加明确,学习方法更加完善,也体会到软件开发的趣味,更加清楚地认识到了自己在软件开发及学习上的一些不足之处。三周的学习很短暂,对嵌入式技术、对Linux都有了新的认识。通过这次的实训,我了解到,要真真正正的掌握计算机程序还不是一件简单容易的事儿,但真正掌握后,它带给我们的将是无穷的便捷与科技。35 参考文献[1]丁林松,黄丽琴.基于嵌入式Linux的Qt图形程序实战开发.人民邮电出版社,2011,(7):459-460[2]韦东山.嵌入式Linux应用开发完全手册.人民邮电出版社,2011.3[3]李刚,李海兰.一种高速高精度数据采集系统设计.天津大学-ADI联合实验室论文,2006[4]王典洪,汪萍,赵娟.基于ARM的多路高精度数据采集系统设计与研究.中国矿业大学硕士论文,2009[5]张莉君,庄晓奇,欧阳才校.基于S3C2440的多路高精度数据采集系统设计.机床与液压,2010,(1):72-74[6]闫锋欣,曾泉人,张志强.C++GUIQt4编程.电子工业出版社,2011,3[7]郑阿奇.Qt4开发实践.电子工业出版社,2009.535

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
关闭