- 5.31 MB
- 2022-05-16 18:34:56 发布
- 1、本文档共5页,可阅读全部内容。
- 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
- 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
- 文档侵权举报电话:19940600175。
基于ARM9嵌入式微处理器的远程仓库管理系统姓名:专业:电气工程及其自动化学号:0501010318班级:电气05–3班指导老师:
摘要仓库管理是物流当中的一个重要环节,也在企业的整个管理流程中起着非常重要的作用,如果不能保证及时准确的进货、库存控制和发货,将会给企业带来巨大损失,这不仅表现为企业各项管理费用的增加,而且会导致客户服务质量难以得到保证,最终影响企业的市场竞争力.传统的人工仓库作业模式和数据采集方式早已不能满足仓库管理的快速、准确要求,因此,在20世纪70年代,通用计算机开始应用到仓库管理上,它带来了仓库管理的一次革命,但随之也带来了新的问题:建设成本巨高,后期维护量大,硬件系统不可靠。随着嵌入式技术的发展,人们似乎又找到了更加适合用于仓库管理的系统。嵌入式系统以体积小,功耗低,运算能力强等优点著称,它一般被设计成某一场合专用的系统。本文设计的远程仓库管理系统,客户机是以运行WindowsCE操作系统的手持式设备,服务器采用运行WindowsServer2003的PC机。客户机的硬件平台以ARM9(S3C2410)微处理器作为核心,通过以太网与服务器建立连接组成一个远程仓库管理系统。该系统可以实现到货检验、入库、出库、调拨、移库、库存盘点等各个作业环节。关键词:远程仓库管理系统,嵌入式系统,ARM9微处理器,WindowsCE.netii
ABSTRACTWarehousemanagementsystemtakeanimportantpartinlabourexchange ,butalsotheentirebusinessprocessmanagementplaysanimportantrole,ifitcannotguaranteetimelyandaccuratepurchasing,inventorycontrolandshipping,willbeagreatlosstobusinesses,notonlytheperformanceofthemanagementcostsforenterprisesincreases,andcustomerservicequalitywillleadtodifficulttobeassuredthattheultimateimpactofthemarketcompetitivenessofenterprises.Traditionalartificialstorageanddataacquisitionmodeofoperationhaslongwarehousemanagementcannotmeettherapidandaccuraterequest,therefore,inthe20thcentury,70"s,begantoapplygeneral-purposecomputers,warehousemanagement,warehousemanagementwhichhasbroughtarevolution,butwiththeithasalsobroughtnewproblems:theconstructionofhugehigh-cost,post-maintenance,andunreliablehardware.Withthedevelopmentofembeddedtechnology,thereseemstohavefoundamoresuitablesystemforwarehousemanagement.Embeddedsystemsaresmall,lowpowerconsumption,computingpower,saidthestrongadvantages,itisgenerallydesignedasaforumdedicatedsystem.Inthispaper,thedesignofaremotewarehousemanagementsystem,clientoperatingsystemisrunningWindowsCEhandhelddevices,serversrunningWindowsServer2003usingthePC.ClienthardwareplatformasacoreARM9microprocessors,serversviaEthernettoconnectaremotewarehousemanagementsystem.Thesystemenablesdeliveryinspection,storage,alibrary,allocate,transferdatabase,inventoryandotheroperationalaspectsofinventory.Keywords:RemoteWarehouseManagementSystem,EmbeddedSystem,ARM9Device,WindowsCE.netii
目录第1章绪论11.1仓库管理系统的概述11.2仓库管理系统研究背景与意义11.3国内外同类软件的研究现状与发展趋势2第2章需求分析32.1设计目标32.2需求描述32.2.1功能需求32.2.2数据需求32.3可行性分析42.3.1远程数据库系统原理可行性分析42.3.2硬件平台的选择5第3章系统分析63.1整体硬件连接图63.2服务器软件环境分析73.2.1SQLServerMobile服务器代理73.2.2IIS6.0的应用73.2.3Microsoft®SQLServer™2000简介83.3客户端软件环境分析83.3.1SQLServerMobile客户端代理83.3.2ADO.NET的应用83.3.3客户端环境的操作系统定制9第4章服务器的实现114.1配置IIS服务对SQLServerMobile3.0的支持114.1.1配置服务器网络114.1.2创建共享文件夹114.1.3配置SQLServerMobileWeb同步向导124.2重新注册SQLServer13第5章客户端硬件设计155.1MagicARM2410教学实验开发平台概述155.2核心控制电路165.3存储器电路185.3.1NORFlash存储器185.3.2SDRAM存储器195.3.3NANDFlash存储器205.4时钟电路215.5复位电路212
5.6电源电路225.7以太网接口电路225.8JTAG调试接口电路245.9电源模块24第6章客户端软件设计256.1客户端软件功能模块256.2程序流程图266.3客户机界面276.4串口通信模块296.4.1接口电路设计296.4.2串口API函数使用316.4.3VB.net调用DLL文件356.4.4打印机驱动模块366.5本地数据库的访问366.5.1创建和组装本地数据库376.5.2与目标数据库建立连接376.5.3对记录集的添加、删除、查找和修改386.6远程数据库的访问436.6.1数据库的同步合并446.6.2向服务器申请或提交数据45参考文献47附录A打印机指令封装模块代码482
第1章绪论仓库管理系统属于管理信息系统(ManagementInformationSystem)的一种,在强调管理,强调信息的现代社会中它变得越来越普及。高效可靠的仓库管理系统软件不仅可以提高企业的管理质量,而且可以提高生效效益。随着计算机技术和嵌入式系统技术的发展,仓库管理系统的终端硬件平台出现了很大的变化,可以是通用计算机、专用的嵌入式计算机或者掌上电脑等。多功能、低成本、高可靠的仓库管理系统产品将是未来的一个趋势。1.1远程仓库管理系统的概述本设计是一套功能齐全,使用简单的企业仓库管理软件产品。远程仓库管理系统采用客户机/服务器架构,服务器采用通用计算机,负责存储和管理仓库产品信息。客户机采用基于ARM9微处理器(S3C2410)为核心的硬件平台,负责仓库产品信息的管理,如入货,出货和日常管理等。通过简单的采购管理,销售管理,库存管理等功能,让用户能够通过最轻松方便的数据录入,获得最快速最完善的报表输出,从而大大提高企业内部管理的效率,让企业管理者能够轻轻松松地做好企业的管理。l实现基于嵌入式系统的客户机通过以太网与数据库服务器互联;l实现通过无线WiFi系统实现与数据库服务器的无线连接;l管理员可以通过可以机实现对仓库信息的管理和查询;l基于帐户和密码的安全的仓库系统访问模式;l通过客户机可以实现采购管理、销售管理、仓库管理、报表打印、基本资料、系统设置、权限管理等功能。1.2远程仓库管理系统的研究背景随着我国经济的飞速发展,各种类型规模的公司企业迅速崛起,许多从事生产和经营管理的企业都有自己生产和销售的产品,而这些产品都需要储存在仓库中,对于每个企业来说,随着企业规模的不断扩大,产品数量的急剧增加,所生产的产品种类也会不断地更新与发展,有关产品的各种信息量也会成倍增长,计算机技术应用于仓库信息管理早在上个世界七十年代已经开始了。这些年来掀起了一股嵌入式系统应用热潮,其原因有几个方面:一是芯片技术的发展;另一方面的原因就是对产品可靠性、成本、更新换代要求需要。这使得嵌入式系统逐渐从纯硬件实现和使用通用计算机实现的应用中脱颖而出,成为近年来令人关注的焦点。本设计中的远程仓库管理系统的概述针对目前国内仓库的功能要求而设计的,其客户机终端使用的是轻便的嵌入式系统,可以是本设计中的专用嵌入式计算机,也可以是PDA、PPC、POS机等可以运行Windows58
CE操作系统的设备,管理人员可以方便地把客户机安装在仓库里任何有网络接口的地方,使用PDA、PPC、POS机等手持式设备的则更加方便,用户通过随身携带的手持式设备可随时随地通过无线WiFi网络连接到服务器。1.1远程仓库管理系统的研究意义面对庞大的产品信息量,如何有效地管理库存产品,对这些企业来说是非常重要的,仓库管理系统的重点是销售信息能否及时反馈,从而确保企业运行效益。而库存管理又涉及入库、出库的产品、经办人员及客户等方方面面的因素,如何管理这些信息数据,是一项复杂的系统工程,充分考验着仓库管理员的工作能力,工作量的繁重是可想而知的,所以这就需要由库存管理系统来提高库存管理工作的效率,这对信息的规范管理、科学统计和快速查询,减少管理方面的工作量,同时对于调动广大员工的工作积极性,提高企业的生产效率,都具有十分重要的现实意义。1.2同类型设备的研究现状与发展趋势1.2.1国外发展状况与发展趋势计算机在管理中的应用开始于1954年,当时美国首先用计算机处理工资单。40多年来,计算机在处理管理信息方面发展迅速。例如,60年代美国计算机在管理中应用项目不到300项,到了1975年达到2670项。而用于企业仓库管理的计算机系统更是普及,但由于通用计算机本身的特性使得它在客户机/服务器架构的远程仓库管理系统中的使用遇到了瓶颈,如成本、可靠性、维护性、功能性等。于是,随着嵌入式系统技术的发展,开发者开始把目光转向专用的嵌入式计算机。高性能的32位ARM微处理器的出现更是引起了一股嵌入式系统应用的潮流,它具有低功耗、低成本、运算能力强、可靠性强等优点,许多厂家开始研制专用于各种环境嵌入式工业计算机。但将其应用于基于客户机/服务器架构的远程仓库管理系统还是属于较少,因为整个系统的研发除了需要硬件平台的支持外还依赖于软件平台的操作系统、开发环境、开发工具、通信协议等的支持。1.2.2国内发展状况与发展趋势仓库管理对企业来说是一项繁琐复杂的工作,每天要处理大量的单据数据,为及时结清每笔业务,盘点库存和货物流动情况,保证企业生产用料以及货物安全,库管人员要花费大量人力物力和时间来做数据记录统计工作。但由于我国的计算机技术发展落后,信息化的仓库管理系统普及非常迟。我国在全国范围内推广计算机在管理中的应用,是在70年代末开始的,虽然起步较晚,但近几年发展却较快,特别是通用计算机的出现和普及在一段时间内为信息处理提供了非常好的手段,对于推动我国管理信息处理的现代化起了重要的作用。目前国外的新的趋势是使用基于客户机/服务器架构的嵌入式远程仓库管理系统,我国的企业仓库管理将面临着有一次的升级。但是,国内严重缺乏嵌入式系统的研发能力,通常只能买来国外的产品作二次加工,国内企业想使用先进的仓库管理系统还是需要购买外国人的产品。58
第1章远程仓库管理系统分析1.1远程仓库管理系统简介1.1.1基本要求本设计中,以基于ARM9嵌入式微处理器的设备作为客户机,以PC机作为数据库服务器,使用SQL数据库实现一个仓库管理系统。客户机与服务器通过以太网进行连接。客户机分为两类,一类是供仓库管理人员管理出货入货和查询库存产品信息专用的,另一类是仅供销售人员等查询库存产品信息使用的;服务器存放仓库所有产品的信息。管理人员使用管理工作人员专用客户机对出货入货的商家和产品信息进行登记同时打印出货入货票据,销售人员等使用库存产品查询客户机查询库存产品数量等信息。系统的架构如图2.1所示。图2.1系统的架构图1.1.2系统组成本设计的硬件实现主要以MagicARM2410教学实验系统为智能终端,通过以太网与SQLServer服务器连接,实现远程数据库访问;通过RS232串行通信数据线与串口打印机连接,实现数据的打印。而在真正的产品中,通常使用的是台式智能终端或无线的手持式智能终端,其硬件连接图如图2.2所示。58
图2.2硬件连接原理图1.1.1系统特点本设计在计算机网络,数据库和先进的开发平台上,利用现有的软件,配置一定的硬件,开发一个具有开放体系结构的、易扩充的、易维护的、具有良好人机界面的仓库管理系统,实现产品信息管理,出货入货管理,远程数据库同步,数据安全备份,使用者权限管理等功能。(1)数据录入和处理的准确性和实时性数据的输入是否准确是数据处理的前提,错误的输入会导致系统输出的不正确和不可用,从而使系统的工作失去意义。数据的输入来源是主要是手工输入。在系统中,数据的输入往往是大量的,因此系统要有一定的处理能力,以保证迅速的处理数据。(2)数据的安全性本系统为企业仓库管理部门设计,涉及到各种重要信息,因此系统设有安全管理机制,对不同的操作人员可以设置不同的管理权限,对不同的浏览者可以设置开放不同的数据表。(3)数据的备份和灾难恢复58
定期对数据库中的数据进行全部或新增部分的备份工作,以保证在硬件出现故障或人为原因导致无法运行时是可以快速及时的还原到原来的正常状态。1.1.1适用场合1.2远程仓库管理系统方案选择1.2.1可移动的嵌入式硬件平台今天,微处理器已经无处不在,无论是录像机、智能洗衣机、移动电话等家电产品,还是汽车引擎控制,以及数控机床、导弹精确制导等都要嵌入各类不同的微处理器。简单的单片机已经不能满足复杂的信号处理要求,但台式PC机的中央处理器的体积,功耗等也满足不了嵌入式设备的要求,因此,嵌入式微处理器应运而生。Xscale是ARM体系结构的一种内核,基于ARMv5TE,由Intel公司开发,在架构扩展的基础上同时也保留了对于以往产品的向下兼容,相比于ARM处理器,XScale功耗更低,系统伸缩性更好,同时核心频率也得到提高,达到了400Mhz甚至更高。但XScale的价格偏高,使用在一般的消费电子上会使成本增大。ARM9系列处理器是英国ARM公司设计的主流嵌入式处理器,主要包括ARM9TDMI和ARM9E-S等系列。目前使用广泛的是三星公司生产的S3C2440,通过全新的设计,采用了更多的晶体管,使它成为了一种高性能、低功耗和低成本的32位微处器,它被广泛应用于嵌入式系统中,已经在手持电话、机顶盒、数码像机、GPS、个人数字助理以及因特网设备等方面有了广泛的应用。应此在本设计中选择使用ARM9微处理器。1.2.2如何实现远程数据库系统MicrosoftSQLServer2005MobileEdition(下面中简称SQLServerMobile)将MicrosoftSQLServer扩展到基于WindowsCE的移动设备,并为开发者的快速应用程序开发提供了一个一致的编程模型。SQLServerMobile不同于WindowsCE操作系统本身的属性数据库,它是一个真正意义上的关系数据库,它具有强大的数据存储功能、优化的查询处理器,以及可靠、可伸缩的连接能力。在MicrosoftVisualStudio2005中,提供了ADO.NET来编写SQLServerMobile数据库应用程序,ADO.NET为开发者使用VisualBasic.NET语言和VisualC#语言提供编写WindowsCE数据库应用程序一致的、高性能的高层接口。我们可以使用System.Data.SqlServerCe命名空间实现在智能设备上进行SQLServerMobile数据库的创建与管理。SQLServerMobile客户端并不能像SQLServer客户端一样通过在连接字符串中指定SQLServer服务器的IP而直接连接到SQLServer服务器,而需要通过SQLServerMobile58
代理来间接进行连接。SQLServerMobile客户端已经包含了SQLServerMobile客户端代理,而在SQLServerMobile服务器端,则需要用户另外安装SQLServerMobile作为服务端代理。SQLServerMobile数据库引擎(SQLServerMobileEngine)管理SQLServer数据库在WindowsCE设备上的存储。SQLServerMobile客户端代理(SQLServerMobileClientAgent)通过复制对象、远程数据访问对象和引擎对象来通过应用程序编程控制与MicrosoftSQLServer连接。SQLServerMobile服务器代理(SQLServerMobileServerAgent)处理来自SQLServerMobile客户端代理的HTTP请求。SQLServerMobile客户端代理驻留在基于WindowsCE的设备上,并应用HTTP或HTTPS与驻留在Web服务器上的SQLServerMobile服务器代理进行通信;而SQLServerMobile服务器代理驻留在运行IIS的计算机上,并通过复制或远程数据访问与MicrosoftSQLServer进行通信。SQLServerMobile与SQLServer进行通信的原理如图2.3所示。图2.3SQLServerMobile与SQLServer进行通信原理图1.1服务器环境分析服务器环境由SQLServerMobile服务器代理、MicrosoftInternet信息服务(IIS)和SQLServer组成。SQLServerMobile服务器代理主要处理由SQLServerMobile客户端代理发出的请求。之所以需要IIS,是因为SQLServerMobile需要IIS来提供HTTP协议,客户端通过HTTP协议连接到服务器并通过RDA和复制技术尽心数据的交互。Microsoft®SQLServer™2000是企业级解决方案中的数据库系统,在SQLServerMobile中它提供对客户机上的存储,备份和管理等。1.1.1SQLServerMobile服务器代理通常,SQLServerMobile作为应用程序的一部分应用。在这种应用程序中,数据是在台式机上的MicrosoftSQLServer和支持的设备上的SQLServer58
Mobile之间进行分发的。但是,SQLServerMobile也可以用作个人信息管理(PIM)工具或者所支持设备上的其他应用程序的独立数据库。SQLServerMobile通常用作完整Microsoft.NETCompactFramework应用程序部署的一部分,但也可以单独安装在智能设备上。远程数据访问(RDA)与合并复制确保可以将来自SQLServer数据库的数据传递到支持的设备上的SQLServerMobile。可以脱机操作这些数据,并在以后将其同步到服务器。其体系结构如图2.4所示。图2.4SQLServerMobile体系结构1.1.1利用Internet信息服务建立连接Internet信息服务器(IIS)提供了集成Web服务器功能。在与SQLServerMobile一起使用时,IIS可以提供一种协议。通过这种协议,设备可以连接到服务器以便通过RDA或复制技术来传输与交换数据。用户编程时只需要把提交的信息交给SQLServerMobile客户端代理,客户端代理与服务器代理成功建立连接后就会把信息发送到应用程序池。IIS6.0包括许多新功能,它们旨在帮助企业、IT专业人士和Web管理员实现其网站(他们可能拥有位于单个IIS服务器或多个服务器上的数千个网站)在性能、可靠性、可伸缩性和安全性方面的目标。1.1.2Microsoft®SQLServer™2000Microsoft®SQLServer™2000数据库组件是基于结构化查询语言(SQL)的可伸缩的关系数据库,集成了对Internet应用程序的可扩展标记语言(XML)支持。Microsoft®SQLServer™2000的特性包括:lInternet集成l可伸缩性和可用性l企业级数据库功能l易于安装、部署和使用l数据仓库尽管SQLServer200058
被设计为用作通过网络连接的成千上万并发用户的数据存储引擎,它仍可作为一个独立的数据库,像应用程序一样直接在同一台计算机上运行。SQLServer2000卓越的可伸缩性和便于使用的诸多功能使其能够在单个计算机上高效运行,既不占用过多的系统资源,也不需要专门的用户来管理。这些功能还使SQLServer2000得以动态地获取支持上千用户所需的资源,同时将数据库的管理和调节工作减到最少。SQLServer2000关系数据库引擎动态调节自身以获取或释放适当的计算机资源,以支持在任何特定时间访问SQLServer2000实例时不断变化的用户负荷之需。SQLServer2000关系数据库引擎的强大功能可以避免因某个用户读取或修改其他用户当前使用的数据而引起的逻辑问题。1.1客户机环境分析客户端环境由SQLServerMobile客户端代理与应用程序组成。SQLServerMobile包括数据库引擎、SQLServerMobile客户端代理、查询处理器、编程框架等,SQLServerMobile客户机代理通过Replication对象,RemoteDataAccess对象和Engine对象来实现与服务器环境中的SQLServerMobile服务器代理进行HTTP通信,再与SQLServer连接。1.1.1SQLServerMobile客户端代理SQLServerMobile客户端代理是在运行WindowsCE备上与数据库服务器进行连接的主要组件。它可应用下列自定义的SQLServerMobile对象:lReplication对象lRemoteDataAccess对象lEngine对象在应用程序中使用这些对象,可用编程方式控制与SQLServer的连接。1.1.2利用ADO.NET管理本地数据库从基本角度来看,ADO.NET是一组类,这些类专门用来对数据进行访问,无论这些数据库是存储在数据库中,还是存储在XML中,松耦合的构架为搭建一个分布式的数据库环境创建了条件,ADO.NET可以访问Access数据库、SQLServer数据库、Orcal数据库,还可以被应用到桌面应用程序、Web应用程序、嵌入式设备应用程序中,而且无论你使用的是VB.NET还是C#,当然还包括托管C++。在应用程序中开发者需要的是简单、一致的应用程序编程接口(API),使应用程序能够访问和修改各种各样的数据源。数据源可能象文本文件一样简单,也可能象一堆异构数据库那样复杂,或者是尚未定型的某种数据。此外,API不应该预先设定访问和操作数据源的方式。客户端应用程序的开发主要使用了微软公司的ADO.NET(ActiveXDataObjects.NET)技术,它是一个用于存取数据源的COM组件。它提供了编程语言和统一数据访问方式OLE58
DB的一个中间层。允许开发人员编写访问数据的代码而不用关心数据库是如何实现的,而只用关心到数据库的连接。访问数据库的时候,关于SQL的知识不是必要的,但是特定数据库支持的SQL命令仍可以通过ADO.NET中的命令对象来执行。ADO.NET的对象模型如图2.5所示。图2.5ADO.NET对象模型1.1.1Windows®CE.NET环境客户端环境的操作系统选择Microsoft®Windows®CE.NET,它是WindowsCE3.0的后续产品,它不仅是一个功能强劲的实时嵌入式操作系统,而且提供了众多强大工具,允许用户利用它快速开发出下一代的智能化小体积连接设备。WindowsCE是微软公司嵌入式、移动计算平台的基础,它是一个开放的、可升级的32位嵌入式操作系统,是基于掌上型电脑类的电子设备操作系统,它是精简的Windows95,WindowsCE的图形用户界面相当出色。WindowsCE.NET5.0对WindowsCE先前版本的强大功能进行了进一步的扩充和丰富,它提供了:l对安全和可伸缩网络的支持l得到增强的实时处理能力l更为优秀的性能表现l更为丰富的多媒体和Web浏览功能l与个人计算机、服务器、Web服务以及其它设备更为出色的互操作性1.2软件开发环境分析本设计总客户机软件的开发环境是一台安装MicrosoftVisualStudio2005的通用计算机,通过MicrosoftVisualStudio2005,可以使用VisualBasic58
2005来开发客户机的应用程序。使用VisualBasic2005进行托管用应用程序的开发,还需要安装专门的.NETCompactFramework。在进行VisualBasic2005的安装组件选择时,可以进行.NETCompactFramework和SQLServer2005MobileEdition的安装。开发机的开发对象是客户机环境中的SQLServerMobile的应用程序,对于有网络连接支持的设备,可以直接用HTTP通信,如果没有网络连接,可以使用ActiveSync来建立于桌面Windows的连接,再与IIS服务器进行HTTP通信。开发环境的详细框架如图2.6所示。图2.6开发环境的框架图58
第1章数据库服务器设计1.1服务器运行的操作系统Windowsserver2003是微软公司开发的新一代网络服务器操作系统,与以前的同类操作系统相比,它更加安全、性能更加稳定,而操作和使用却更加轻松,因此,它不仅能够安装到服务器上设置成为主域控制服务器、文件服务器等各种服务器,也能安装在局域网的客户机上,作为客户端系统使用,当然也可以安装到个人电脑中,成为更加稳定、更加安全、更容易使用的个人操作系统。无论是服务器、客户机还是家庭用户,安装Windows2003都是非常轻松的。Windowsserver2003对硬件的要求并不是很高,建议系统的CPU主频不低于550MHz(支持最低主频为133MHz);建议系统内存在256MB以上(最小支持128MB,最大支持32GB);硬盘分区要具有足够的可用空间,最小要在2G以上;VGA或更高分辨率的监视器(建议使用SVGA800x600或更高)、键盘和鼠标。与微软的其他的操作系统一样安装过程采用图像化、向导化操作,这个过程比较简单所以不在这里描述。1.2配置IIS服务对SQLServerMobile3.0的支持在成功安装好服务器环境所需要的组件后,就可以开始服务器的配置了。1.2.1配置服务器网络当您使用远程数据访问(RDA)或复制功能时,SQLServerMobile将通过MicrosoftInternet信息服务(IIS)服务器连接到SQLServer,因吃我们必须确定服务器上安装了网络的文件和打印机共享协议和TCP/IP协议,如图3.1所示。图3.1添加网络协议58
1.1.1创建共享文件夹创建用于SQLServerMobile订阅服务器的快照文件夹,需要执行两个步骤。必须共享此文件夹,使其可以通过UNC路径访问;还必须分配适当的NTFS文件系统权限。在共享文件夹时,需要添加相应的用户,并将“读取”共享权限授予该用户,其设置对话框如图3.2所示。图3.2设置共享文件夹权限1.1.2配置SQLServerMobileWeb同步向导当您使用远程数据访问(RDA)或复制功能时,SQLServerMobile将通过MicrosoftInternet信息服务(IIS)服务器连接到SQLServer。SQLServerMobile包括一个连接向导(配置Web同步向导),使用该向导可以配置MicrosoftSQLServer和SQLServerMobile之间的连接,以进行数据同步。单击“开始”→“程序”→“MicrosoftSQLServer2005MobileEdition”→“配置Web同步向导”,就可以打开Web同步向导,如图3.3所示。58
图3.3配置Web同步向导点击下一步后,进入服务器选择对话框,这里的IIS计算机名一半是本地上运行IIS的服务器,虚拟目录用于存放工作文件,如图3.4所示。图3.4选择服务器Web同步配置完成后,打开IE浏览器,在地址栏上面输入虚拟目录的网路地址,如果配置成功,就会出现如图3.5所示的文字。58
图3.5Web同步配置1.1重新注册SQLServer成功配置配置Web同步之后,为了更新SQLServer的数据库信息,需要把原来的SQLServer服务器注册信息删除,然后重新注册SQLServer服务器。新建SQLServer注册如图3.6所示。图3.6重新注册SQLServer进入注册SQLServer后首先要求用户选择登陆方式,这一步很重要,它关系到远程访问是否能通过验证,通常情况下选择“用我的SQLServer登录名登陆”,如图3.7所示。58
图3.7SQL登录方式58
第1章客户机硬件设计1.1MagicARM2410教学实验开发平台概述嵌入式设备主要由硬件和软件组成,一套嵌入式产品的稳定性不仅依赖于软件的稳定性,对于硬件平台能否提供良好的做工稳定性也有一定的要求,在本设计的设计阶段,使用广州致远电子有限公司开发的MagicARM2410教学实验开发平台,他不仅能提供一个可靠稳定的硬件平台,而且提供了丰富的外设支持。广州致远电子有限公司开发的MagicARM2410教学实验开发平台,是一款可使用μC/OS-II、Linux和WinCE操作系统、支持QT、MiniGUI图形系统、集众多功能于一身的ARM9教学实验开发平台。MagicARM2410教学实验开发平台采用ARM920T内核的S3C2410A微处理器,扩展有充足的存储资源(SDRAM、NANDFlash、NORFlash和E2PROM等),具有10/100Mbps以太网接口、USBHOST接口、USBDevice接口、CAN接口、PCMCIA存储卡接口、IDE硬盘接口、CF卡接口、SD卡接口、IrDA接口、IIS数字音频接口,8英寸640×480真彩TFT液晶屏(带触摸屏),可使用JTAG仿真调试。模块化的功能设计,便于实验操作的工艺设计,保留有外设PACK和GPIO输出接口,可以实现目前几乎所有的嵌入式接口实验。MagicARM2410试验箱外观如图4.1所示。图4.1MagicARM2410试验箱外观58
本系统采用MagicARM2410开发平台作为硬件环境。系统中使用到的硬件电路分为5个主要模块,它们是核心板电路,以太网接口电路,JTAG调试接口电路,串口模块和电源模块。核心电路板的MCU采用Samsung公司的ARM920T处理器S3C210A,核心电路还扩展了2MBNORFlash,64MBNANDFlash及64MBSDRAM,它还包括复位、时钟等电路。核心电路图是系统的核心模块,它为系统软件提供了可靠、稳定的运行环境。以太网接口电路包括DM9000以太网控制器、网络变压器和RJ-45接口组成,是TCP/IP协议栈中物理层的实现。串口模块打印调试信息。JTAG模块用于下载和调试程序。电源模块为系统提供5V,3.3V,1.8V的稳定电压。系统硬件框架如图4.2所示。图4.2系统硬件结构示意图1.1核心控制电路核心板电路是能运行程序的最小系统电路。它包括微处理器S3C2410A,存储器电路,时钟电路,复位电路,及核心板使用的电源电路等。系统中采用的S3C2410A(S3C2410系列,以下称为S3C2410)微处理器是一款由SamsungElectronicsCo.Ltd为手持设备、POS机、数字多媒体播放设备设计的低功耗、高度集成的微处理器,采用272脚FBGA封装,内含一个ARM920T内核和丰富的外围资源。S3C2410集成了大量的功能单元,包括内部1.8V、存储器3.3V、外部I/O3.3V、16KB数据CACHE、16KB指令CACHE、MMU、内置外部存储器控制器(SDRAM控制和芯片选择逻辑)、LCD控制器、一个LCD专用DMA、4个带外部请求线的DMA、3个通用异步串行端口(IrDA1.0、16-ByteTxFIFOand16-ByteRxFIFO)、2通道SPI、一个多主I2C总线、一个I2S总线控制器、版本1.0的SD主接口、并与多媒体卡协议版本2.11兼容、两个USBHOST、58
一个USBDEVICE(VER1.1)、4个PWM定时器和一个内部定时器、看门狗定时器、117个通用I/O、24个外部中断、4种电源控制模式(包括标准、慢速、休眠、掉电)、8通道10位ADC和触摸屏接口、带日历功能的实时时钟、芯片内置PLL;设计用于手持设备和通用嵌入式系统;16/32位RISC体系结构,使用ARM920TCPU核的强大指令集;带MMU的先进的体系结构支持WinCE、EPOC32、Linux;指令缓存(CACHE)、数据缓存、写缓冲和物理地址TAGRAM,减小了对主存储器带宽和性能的影响;ARM920T核支持,并有支持ARM调试的体系结构;内部先进的位控制器总线(AMBA)(AMBA2.0,AHB/APB)。S3C2410X芯片结构图如图4.3所示。图4.3S3C2410芯片内部结构图58
S3C2410的系统管理有以下特点:小端/大端支持;地址空间:每个BANK128MB(全部为1GB);每个BANK可编程为8/16/32位数据总线;BANK0到BANK6为固定起始地址;BANK7可编程BANK起始地址和大小;一共8个存储器BANK;6个存储器BANK用于ROM、SRAM和其他;两个存储器BANK用于ROM、SRAM和同步DRAM;每个存储器BANK可编程存取周期;支持等待信号用以扩展总线周期;支持SDRAM掉电模式下的自刷新;支持不同类型的ROM用于启动(NOR/NANDFlash、EEPROM和其他)。本系统中,处理器被配置在小端格式。工作频率可设置在200MHz,AHB总线频率为100MHz。1.1存储器电路1.1.1NORFlash存储器核心板上扩展了1片存储容量为2MB的NORFlash(SST39VF1601),为了使SST39VF1601能够引导和下载系统,将其分配在Bank0存储块空间,使用S3C2410的nGCS0片选线,基地址为0x00000000。如图4.4所示,SST39VF1601是16位宽度存储器,对与S3C2410A来说相应与半字对齐,操作地址的最小变化值是0x00000002,因此将S3C2410A的ADDR1脚与SST39VF1601的A0脚相连,忽略S3C2410A的ADDR0引脚,其他地址按顺序依次递增相连。SST39VF1601的nRST引脚与系统复位信号nRESET引脚相连接,当系统复位时,SST39VF1601同时被复位,并返回到默认的读模式。SST39VF1601的nWP是写保护引脚,低电平时写禁止,高电平时允许写SST39VF1601。电路中使用两个电阻进行选择,如虚线框内电路。58
图4.4NORFlash存储器电路1.1.1SDRAM存储器FLASH存储器相比较,SDRAM不具有掉电保持数据的特性,但其操作都是由时钟作为同步,存取速度大大高于FLASH存储器,数据吞吐量更大,且具有读/写的属性。SDRAM在系统中主要用作程序的运行空间,当系统启动时,首先从复位地址0x00000000处读取启动代码,再完成系统的初始化后,启动程序将系统程序代码调入SDRAM中运行,以提高系统的运行速度。同时,系统及用户堆栈、运行数据也都放在SDRAM中。SDRAM的存储单元可以理解为一个电容,总是倾向于放电,为避免数据丢失,必须定时刷新。因此,要在系统中使用SDRAM,就要求微处理器具有刷新控制逻辑,或在系统中另外加入刷新控制逻辑电路。S3C2410A在片内具有独立的SDRAM刷新控制逻辑,可方便的与SDRAM接口。核心板扩展了2片16位总线宽度SDRAM(HY57V561620),存储容量64MB。SDRAM使用S3C2410A的nGCS6片选线,SDRAM的基地址为0x30000000,核心板使用两片HY57V561620组成32位总线宽度,即每进行一次读写可以操作4字节数据,对于S3C2410A来说相应于字对齐,操作地址的最小变化值为0x00000004。因此,S3C2410A的ADDR2引脚于HY57V561620的A0脚相连,忽略S3C2410A的ADDR0,ADDR1引脚。为了能够正确访问HY57V561620的高低字节数据,所以S3C2410A的nWBEx与HY57V561620的UDQM/LDQM相连。HY57V561620的BA0、BA1引脚是SDRAM的内部bank选择线,也就是代表了SDRAM的内存地址的最高位。如果SDRAM内存共有64MB也就需要26(226=64M)根地址线来寻址,所以BA0、BA1应连接S3C2410A58
的ADDR24、ADDR25引脚。另外,由于SDRAM的行地址和列地址是复用的,所以地址线的数目并部需要这么多。SDRAM的其他控制线按照HY57V561620的引脚功能――与S3C2410的SDRAM控制信号线相连接。SDRAM存储器电路如图4.5所示。图4.5SDRAM存储器电路1.1.1NANDFlash存储器NANDFlash具有良好的性价比和系统接口,且S3C2410支持NANDROM启动方式,所以核心板选用了三星公司的NANDFlash:K9F1208U0B-PCB0。该Flash是64MB的CMOS工艺制造的存储器。采用48脚TSOP封装,其工作电压为2.7V~3.6V,其I/O口为数据线和地址线的复用端口。通过对其内部的命令寄存器写入标准的命令序列,可对其进行编程、整片擦除、按扇区擦除以及其它操作。核心板使用K9F1208U0B-PCB0扩展了64M的NANDFlash存储器,K9F1208U0B-PCB0的I/O0~I/O7直接与S3C2410的DATA0~DATA7相连,通过数据总线发送地址、命令和数据。NANDFlash接口电路原理图如图4.6所示。58
图4.6NANDFlash存储器电路1.1时钟电路S3C2410可以使用外部晶振或外部时钟输入作为系统时钟,外部晶振的频率范围是10MHz~20MHz,核心板采用12MHz的外部晶振,所以S3C2410A的OM2,OM1引脚接为低电平,将外部时钟输入引脚接为高电平(3.3V),电路如图4.7所示。通过S3C2410的内部锁相环,可以将处理器时钟倍频至最高266MHz。图4.7核心板时钟电路1.2复位电路58
核心板的复位电路采用内置E2PROM存储器的专用电源监控复位芯片CAT1025JI-30,提高了系统的可靠性。系统复位电路如图4.8所示。图4.8核心板复位电路1.1电源电路由于ARM芯片的高速、低功耗、低工作电压导致了其噪声容限很低,对电源的纹波、瞬态响应、电源监控的可靠性等诸多方面提出了更高的要求。核心板使用的一组3.3V电源有外部提供,而S3C2410需要的1.8V电压是通过核心板上的LDO芯片(低压差电源芯片)得到的。核心板使用SPX1117M3-1.8将3.3电压转换为1.8V。使用时,其输出端需要一个至少10uF的钽电容来改善瞬态响应和稳定性。核心板的电源电路如图4.9所示。图4.9核心板电源电路1.2以太网接口电路以太网规范规定以太网需要两种接口部件:MAC(MediaAccessController,媒体访问控制器)和PHY(Physicaltransceiver,物理收发器)。MAC是一种纯数字的设备,负责数据流的同步处理。而PHY在很大程度上是一种模拟器件,负责将数据转换成在特定的媒体上(常用双绞线)传输所需的信号电平。本系统的以太网控制器(网卡)使用DAVICOM公司的10/100Mb/s自适应以太网芯片DM9000E(DM9000系列,以下称为DM9000)。DM9000是一个全集成、功能强大、性价比高的快速以太网MAC控制器,支持8位、16位、32位数据总线宽度,带有一个通用处理器接口、EEPROM接口、10/100Mb/sPHY和16KB的SRAM(13KB作为接收FIFO,3KB作为发送FIFO);包含一系列可被访问的控制状态寄存器,这些寄存器是字节对齐的,在硬件或软件复位时被设置成初始值;采用单电源供电,可兼容3.3V、5V的IO接口电平。DM9000同样支持MII(MediaIndependentInterface介质无关接口)接口。58
MagicARM2410实验箱主板上带有一路10/100M以太网接口电路,电路原理图如图4.10所示。DM9000的EEDO引脚和WAKEUP引脚的复位值决定了其数据位宽度。电路图中EEDO已接低电平,WAKEUP内部有60K下拉电阻,因此悬空该引脚时WAKEUP的复位值也是低电平。所以该电路中,DM9000的数据位宽度是16位,S3C2410的数据总线DATA0~DATA15与DM9000的SD0~SD15相连接。DM9000E的AEN是芯片选通引脚,与S3C2410的片选线nGCS3相连,该引脚为低时才能进行读写操作。所以DM9000的片选地址为0x18000000。S3C2410的地址线ADDR2与DM9000E的命令/数据使能端CMD相连,CMD引脚用于设置COMMAND模式,CMD为高时,选择数据端口,CMD为低时,选地址端口。DM9000默认工作基地址为300H。数据端口和地址端口的地址由下式决定:DM9000地址端口=片选地址+0x300H+0x00DM9000数据端口=片选地址+0x300H+0x04由上式可以得到DM9000的地址端口为0x18000300,数据端口为0x18000304。DM9000的INT与S3C2410的外部中断EINT0相连接,在系统中网卡的中断号为0,默认情况下,INT引脚为高电平时表示网卡中断产生。DM9000的RST与S3C2410的GPG2引脚相连,系统软件通过配置GPG2的电平,产生由高到低电平变化使DM9000硬件复位。IOR和IOW是DM9000的读写选择引脚,低电平有效,即低电平时进行读(IOR)写(IOW)操作。58
图4.10以太网接口电路1.1JTAG调试接口电路在现在系统中越来越强调可策性,调试、测试接口的设计也越来越受到重视。S3C2410中内置有一个JTAG调试接口,通过这个接口可以控制芯片的运行和获取内部信息。这部分的电路比较简单,电路原理如图4.11所示。图4.11JTAG调试接口电路58
1.1电源模块MagicARM2410开发平台上有一个专门的电源板给系统供电,电源板提供的电压有+12V和+5V,所以开发平台上还需要一个系统电源电路,它使用LDO芯片将5V电源转换得到两组3.3V电源,一组给核心板供电,另一组给主板供电。系统电源电路原理图如图4.12所示。图4.12系统电源电路58
第1章客户机软件设计1.1软件功能模块的划分客户机要实现的主要功能包括本地数据库的访问,远程数据库的访问,软件设置和打印模块。功能模块如图2.1所示。图5.1管理员客户机功能模块图本地数据库访问模块主要对本地数据库进行访问,可以执行各种信息的查找,添加,删除和修改操作,一般情况下仓库管理员对产品信息的管理工作是在脱机模式下进行的,到需要与服务器进行数据交换的时候在与服务器进行数据同步。权限认证模块是系统安全的保证,访问本地数据时,管理员需要提供创建本地数据库时使用的账号和密码;访问远程数据库时,管理员不仅要提本地数据库的供账号和密码,而且远程数据库服务器的登录名和密码,SQL服务器的用户名和密码。通过多重认证来保证数据使用的安全性。远程数据库访问模块,远程数据库访问主要实现的功能是数据的同步,以保证客户端的修改能反馈到服务器端。打印模块组要有两部分组成,一部分是串口设置模块,另一部分是驱动模块。串口设置模块主要实现对串口参数的设置,例如波特率,串口号,效验位,停止位和奇偶校验。驱动模块主要是对串口打印机命令的封装和串口类的调用。58
1.1客户机程序流程图由于管理员客户机和普通工作人员客户机是分开设计的,所以程序流程图也分为管理员客户机程序流程图和普通工作人员考核及程序流程图。管理员客户机功能比较丰富,其程序流程如图5.2所示,其中对本地数据库中的数据记录操作包括添加、删除、修改和查找,对数据库系统的操作有同步合并,申请或提交数据等等,系统要求高可靠的保密功能,所以用户登陆时需要权限验证。图5.2管理员客户机程序流程图58
1.1打印机通信模块设计串口通信模块的设计包括硬件电路设计和软件代码设计,下面将进行详细叙述。1.1.1接口电路设计在嵌入式系统的开发和应用中,经常需要使用上位机本身配置的串行口,通过串行通讯技术,和嵌入式设备进行连接通讯。串行口的典型代表是RS-232-C及其兼容插口,用9、11、18、25针来实现。RS-232-C是美国电子工业协会EIA(ElectronicIndustryAssociation)制定的一种串行物理接口标准。RS是英文“推荐标准”的缩写,232为标识号,C表示修改次数。RS-232-C总线标准设有25条信号线,常见的串行接口有9针和25针的,包括一个主通道和一个辅助通道,在多数情况下主要使用主通道,对于一般双工通信,仅需几条信号线就可实现,如一条发送线、一条接收线及一条地线。S3C2410共有3个UART接口,MagicARM2410实验箱将UART0、UART1用作RS232接口。但ZY2410的BSP只带了UTAR0的驱动,所以在本设计中使用UART0与PC机的串口相连接,作为调试信息的打印接口。UART0通过SP3232芯片跟S3C2410微处理器的串行口引脚连接,其电路如图5.3SP3232串行接口电路所示。图5.3SP3232串行接口电路九针串口的针脚功能如表5.1所示。表5.1九针串口引脚功能一览表针脚功能针脚功能58
1载波检测(DCD)6数据准备好(DSR)2接收数据(RXD)7发送请求(RTS)3发送数据(TXD)8发送清除(CTS)4数据终端准备好(DTR)9振铃指示(RI)5信号地线(SG)本设计中所使用的串口打印机配备的是二十五针的串行接口,因此实验箱跟打印机还不能直接连接,还需要通过自制一根简易的转换线连接。打印机的25针的串行接口的外形如图5.4所示。图5.4二十五针的串行接口的外形二十五针的串行接口的引脚功能很丰富,但实际应用中只需要用到几根,其功能如图5.5所示。图5.5二十五针的串行接口部分引脚功能图引脚号信号方向说明2RXD入打印机从主计算机接收数据3TXD出当使用X-ON/X-OFF握手时,打印机向上微机发送控制码5BUSY出该信号高电平时,表示打印机正“忙”不能接受数据,而当该信号低电平时,表示打印机“准备好”,可以接收数据)4BUSY出同BUSY(TTL电平时,此引脚为空引脚)7GND—信号地1.1.1串口API函数使用虽然VB.net也具备访问设备驱动程序的功能,但是由于其对操作系统的数据类型和程序接口没有很好的支持,所以使用VB.net直接访问驱动程序难度甚大,所以本设计选择利用VC++6.0编写DLL文件为VB.net应用程序提供函数接口,从而方便的实现了对串口驱动的访问。对串口驱动进行操作通过编写一个类来实现,由于串口有多个,使用类的方式通过实例化多个类就可以对多个串口同时进行操作(前提是PDD层的支持)。在串口操作类中,应实现打开串口、关闭串口、查询打开状态、发送数据和接收数据的公共成员函数以及能传出串口配置和公共成员变量。打开串口函数应能够按照一定的DCB58
格式配置串口再打开串口,接收数据的函数应在调用后立刻返回已接收的数据供应用程序使用。该串口操作类通过对串口驱动进行操作实现对串口硬件的操作。由于串口驱动程序为流设备驱动,于是它将由设备管理器进行加载。在WindowsCE中,可以通过CreateFile函数打开串口,如果串口打开成功的话,将会返回打开串口的句柄,否则将返回INVALID_HANDLE_VALUE。在实际使用串口时,还必须设置好串口的波特率,奇偶校验和数据位等参数。WindowsCE中提供了GetCommState和SetCommState函数,分别获取串口当前的参数和设置串口的参数。打开串口的代码如程序清单5.1所示,epcSerialOpen方法根据指定的参数打开串口,并创建此串口的读线程和写线程,以实现串口的异步读写。在使用系统的串口API函数时,还要使用到一个名为DCB的结构体,在GetCommState函数中,它属于输出参数,在SetCommState函数中,它属于输入参数。程序清单5.1串口控制类中的打开串口方法intCCeSerial::epcSerialOpen(EPortPort,EBaudrateBaudRate,EDataBitsDataBits,EStopBitsStopBits,EParityParity,BOOLbDTRShake,BOOLbRTSShake){intiErr;if(hCOM!=INVALID_HANDLE_VALUE){/*判断串口是否已打开,打开则返回*/return(COM_ERR_USING);}if((Port>ECOM9)||(PortEBaud115200)||(BaudRate(1024*8)){dwLength=1024*8;}if(dwOutTime<10){dwOutTime=10;}if(hCOM==INVALID_HANDLE_VALUE){__messageDispDebug(_T("串口未打开!"));return(FALSE);}58
if(hRcvThread!=NULL){__messageDispDebug(_T("串口接收线程已建立过!"));return(FALSE);}GetCommTimeouts(hCOM,&ctoTimeOut);ctoTimeOut.ReadIntervalTimeout=dwOutTime;*接收字符间最大时间间隔*/ctoTimeOut.ReadTotalTimeoutMultiplier=1;ctoTimeOut.ReadTotalTimeoutConstant=dwOutTime;*读数据总超时常量*/SetCommTimeouts(hCOM,&ctoTimeOut);dwRcvLength=dwLength;pfunRcvOnComRcv=pfunOnComRcv;pvRcvUserParam=pvUserParam;hExitThreadEvent=CreateEvent(NULL,TRUE,FALSE,NULL);/*创建串口接收线程退出事件*/hRcvThread=CreateThread(0,0,epcSerialComRcvTread,this,0,&dwThreadID);if(hRcvThread==NULL){CloseHandle(hExitThreadEvent);/*关闭线程退出事件句柄*/__messageDispDebug(_T("创建接收线程失败!"));return(FALSE);}return(TRUE);}1.1.1VB.net调用DLL文件虽然VB.net是个简单易用的开发环境,但是自身功能有限,限制了VB.net在某些方面的应用。微软提供了两种方式来增强VB的功能,一种是调用COM组件,另一种就是调用Dll函数,本设计中就是通过在VB.net中动态调用DLL达到调用串口动态链接库中的函数的母的。在VB.net中调用动态链接库的函数很简单,首先在类中使用Declare函数声明要调用的动态链接库和函数名,本设计中主要调用了打开串口关闭串口发送数据和接受数据四个函数其详细的代码清单如程序清单5.5所示。程序清单5.5声明调用动态链接库‘声明调用打开串口函数PublicDeclareFunctionepcSerialOpen1Lib"epcSerial"Alias"epcSerialOpen1"(ByValucPortAsByte,ByValucBaudRateAsByte,ByValucDataBitAsByte,ByValucStopBitAsByte,ByValucParityAsByte)AsInteger58
‘声明调用关闭串口函数PublicDeclareFunctionepcSerialCloseLib"epcSerial"Alias"epcSerialClose"(ByValucPortAsByte)AsBoolean‘声明调用发送数据函数PublicDeclareFunctionepcSerialSendDataLib"epcSerial"Alias"epcSerialSendData"(ByValucPortAsByte,ByValpucSendBufAsByte(),ByValdwLengthAsUInteger)AsBoolean‘声明调用接收数据函数PublicDeclareFunctionepcSerialCloseLib"epcSerial"Alias"epcSerialRcvData"(ByValucPortAsByte,ByValpucRcvBufAsByte(),ByValdwLengthAsInteger,ByValdwOutTimeAsInteger,ByValbClrComBufAsBoolean)AsInteger1.1.1打印机驱动模块本设计中使用的打印机属于微型的串口打印机,这种打印机的优点是不需要编写特定的驱动程序,打印机内部自带了控制器,用户只需要通过目标系统的标准RS232接口与打印机连接。然后按照厂家提供的打印指令表,即可控制打印机打印各种文字或图形。由上一节可知道,系统的串口API已经被封装成一个串口类,并且打包成以标准C语言为导出函数的动态链接库,控制打印机的操作只需要调用串口类然后发送相应的指令和编辑好的数据,其策划年供需流程图如图5.6所示。58
图5.6打印功能模块程序流程图1.1本地数据库访问模块设计在VisualBasic.NET2005中,提供了ADO.NET来编写SQLServerMobile数据库应用程序,而System.Data.SqlServerCe命名空间提供了从运行在支持的设备上的托管应用程序对SQLServerMobile数据库进行编程访问的能力,可以把它看成是对ADO.NET的再.NET上的实现。1.1.1创建和组装本地数据库SQLServerMobile数据库引擎 是用于存储、处理和保护数据的核心技术。通过使用SQLServerMobile数据库引擎,可以在支持的设备上创建、访问和修改SQLServerMobile数据库。数据库引擎还提供了受控访问和快速事务处理功能,可以满足的企业内需要使用大量数据的应用程序的要求。ADO.NET已经包含了数据库引擎组件,所以安装了ADO.NET的智能设备都可以使用58
SQLServerMobile引擎对象。由前面的程序流程图可知道,无论是管理员客户机还是普通工作人员客户机,在正常工作前都需要在本地建立一个数据库,所以本设计中使用了SQLServerMobile引擎对象SqlCeEngine的CreateDatabase方法创建本地数据库文件,详细方法如程序清单5.6所示。程序清单5.6创建本地数据库函数PublicFunctionCreat_DB(ByValstrDataBasePathAsString,ByValstrDataBasePassWordAsString)AsBooleanDimbsuccessAsBoolean=True‘创建SQLServerCE引擎对象DimengineAsNewSqlCeEngine("DataSource="&strDataBasePath&";Password="&strDataBasePassWord)Try‘创建新的数据库engine.CreateDatabase()MsgBox("创建数据库成功!")CatchexAsExceptionMsgBox(ex.ToString)bsuccess=FalseExitFunctionFinallyengine.Dispose()Creat_DB=bsuccessEndTryEndFunction1.1.1与目标数据库建立连接在System.Data.SqlServerCe命名空间中在代码和容纳数据的数据存储之间提供了基本连接的是Connection类。Connection对象表示与数据源的唯一会话。在打开Connection对象之前,必须定义有关数据源和连接类型的某些信息。Connection对象Open方法的ConnectionString参数,或Connection对象上的ConnectionString属性通常包含多数这样的信息。连接字符串是定义数量不等的参数的字符串。这些参数(某些参数是ADO.NET所需的,但另一些参数要视具体提供者而定)包含Connection对象完成其任务所必需的信息。连接数据库时首先创建一个SqlCeConnection对象然后再调用该对象的Open()方法,其实现如程序清单5.7所示。58
程序清单5.7创建SQLServerMobile连接对象DimconnAsNewSqlCeConnection("DataSource="&strDataBasePath&";Password="&strDataBasePassWord)conn.Open()1.1.1对记录集的添加、删除、查找和修改连接到数据源后,需要执行对数据源的请求,以获取结果集。ADO.NET将这一类型的命令功能封装在Command对象中。在System.Data.SqlServerCe命名空间中对应的是SqlCeCommand类。可使用Command对象向提供者请求任何类型的操作,条件是提供者能够正确解释命令字符串。数据提供者的常用操作是查询数据库,并将记录返回到Recordset对象中。Recordset将在本章的后面部分和其他章中详细论述;就现在而言,可以把它们看作是用来保持和查看结果集的工具。与许多ADO.NET对象一样,在引用某些Command集合、方法或属性时可能会产生错误,这取决于提供者的功能。表5.2列出了SqlCeCommand对象的四种执行SQL语句的方式:表5.2四种执行SQL语句的方式项说明ExecuteReader执行返回行的命令。ExecuteNonQuery执行SQL命令,如INSERT、DELETE和UPDATE语句。ExecuteScalar从数据库中检索单个值(例如一个聚合值)。ExecuteResultSet执行命令并返回结果集。一般情况下,对于不需要返回记录的SQL语句都应该使用ExecuteNonQuery方法,在本设计中删除记录,添加记录,修改记录都使用SqlCeCommand的ExecuteNonQuery方法。仓库管理系统中对本司数据库的操作都要经过几个相同的步骤:创建引擎对象,创建连接对象并与目标数据库建立连接,创建SQL语句执行对象并添加要执行的SQL语句。在删除,添加和修改这三个基本操作中都不需要返回值,这三个过程可以抽象成一个通用的函数,函数代码如程序清单5.8所示,型参strSQL代表执行的SQL语句,strDataBasePath代表目标数据库路径和名称,strDataBasePassWord代表目标数据库访问密码。程序清单5.8执行SQL语言的通用函数PublicSubExecute_SQL(ByValstrSQLAsString,ByValstrDataBasePathAsString,ByValstrDataBasePassWordAsString)‘创建SQLServerMobile连接对象DimconnAsNewSqlCeConnection("DataSource="&strDataBasePath&";Password="&strDataBasePassWord)‘创建SQL语句执行对象58
DimcmdAsNewSqlCeCommandTry‘打开本地数据库conn.Open()CatchexAsSqlCeExceptionMsgBox(ex.ToString())conn.Close()ExitSubEndTrycmd.Connection=conncmd.CommandText=strSQLTry‘执行SQL语句cmd.ExecuteNonQuery()CatchexAsSqlCeExceptionMsgBox(ex.ToString())conn.Close()cmd.Dispose()ExitSubEndTryconn.Close()cmd.Dispose()EndSub在成功连接到数据源后,接着要做的是组装数据库,因为使用数据库引擎建立的只是一个空的数据库文件,里面没有任何表格或数据。所以我们可以调用Execute_SQL函数,把建立数据表的SQL语句作为Execute_SQL()的实参。具体的SQL语句如程序清单5.9所示。程序清单5.9组装系统数据库的代码PublicGood_TableAsStringPublicOUTGood_TableAsStringPublicINGood_TableAsStringPublicDEPOT_infoAsString‘建立产品信息表对应SQL语句Good_Table="CREATETABLE产品信息(IDINTEGERIDENTITY(1,1)NOTNULLCONSTRAINTpk_GoodTablePRIMARYKEY,产品代码NVarChar(10)UNIQUE,产品名称NVarChar(15),存放位置NVarChar(10),生产厂家NVarChar(10),规格cmNVarChar(15),毛重gINTEGER,单位NVarChar(2),数量INTEGER,单价RMBFloat,备注NVarChar(20))"58
‘建立出货信息表对应SQL语句OUTGood_Table="CREATETABLE出货信息(IDINTEGERIDENTITY(1,1)NOTNULLCONSTRAINTpk_OutTablePRIMARYKEY,产品代码NVarChar(10),购买商NVarChar(15),经办人NVarChar(10),备注NVarChar(20),数量INTEGER,总价Float,时间NVarChar(25))"‘建立出货信息表对应SQL语句INGood_Table="CREATETABLE入货信息(IDINTEGERIDENTITY(1,1)NOTNULLCONSTRAINTpk_InTablePRIMARYKEY,产品代码NVarChar(10),供货商NVarChar(15),经办人NVarChar(10),备注NVarChar(20),数量INTEGER,总价Float,时间NVarChar(25))"‘建立出货信息表对应SQL语句DEPOT_info="CREATETABLE仓库信息(IDINTEGERIDENTITY(1,1)NOTNULLCONSTRAINTpk_DepotIDPRIMARYKEY,仓库名称NVarChar(20),所属公司NVarChar(20),仓库主管NVarChar(20),仓库地址NVarChar(20),备注NVarChar(20))"很多时候对数据库的操作是需要读取其返回数据集的,例如查找,这时候我们执行SQL语句就要调用SqlCeCommand对象的ExecuteReader方法,并且用SqlCeDataReader对象读取其返回值。与执行不带返回值的SQL语句一样,程序中会大量使用到相同的代码,所以把调用SqlCeCommand对象的ExecuteReader方法也封装成一个ExecuteReadSQL函数,其返回值为SqlCeDataReader类,调用ExecuteReadSQL后可以使用SqlCeDataReader的read方法读取返回的数据集,其程序清单5.10如所示。程序清单5.10查询所有产品信息PublicFunctionExecuteReadSQL(ByValstrSQLAsString,ByValstrDataBasePathAsString,ByValstrDataBasePassWordAsString)AsSqlCeDataReaderDimconnAsNewSqlCeConnection("DataSource="&strDataBasePath&";Password="&strDataBasePassWord)DimcmdAsNewSqlCeCommandDimdrAsSqlCeDataReaderTry‘打开连接对象conn.Open()CatchexAsSqlCeExceptionMsgBox(ex.ToString())conn.Close()ExitFunctionEndTrycmd.Connection=conncmd.CommandText=strSQL58
Try‘执行SQL语句dr=cmd.ExecuteReader()CatchexAsExceptionMsgBox(ex.ToString())conn.Close()cmd.Dispose()ExitFunctionEndTryExecuteReadSQL=drEndFunction修改入货信息是一个比较复杂的过程,它涉及到两个表的修改。当入货数量发生改变后,产品的数量也是要作吸纳过瘾修改的,当用户输入修改后的信息并提交后,系统如果检查到数量背修改了,则同时要测试产品数量修改后是否会出错,例如产品数量小于零。修改后的数据不合法则是不允许修改的。其程序清单5.11如所示。程序清单5.11修改入货信息DimRemain_AmountAsIntegerDimstrCodeAsStringDimstrPurchaserAsStringDimnPriceAsSingleDimstrPrincipalAsStringDimGstrTimeAsStringDimstrRemarkAsStringDimstrSQLAsString‘修改后要求的数量DimnAmountAsInteger‘入货表的原来的数量DimnOriginality_AmountAsIntegerDimdrAsSqlCeDataReaderstrCode=txtCode.TextstrPurchaser=txtPurchaser.TextstrPrincipal=txtPrincipal.TextGstrTime=txtTime.TextstrRemark=txtRemark.Text58
nAmount=Val(txtAmount.Text)nPrice=txtPrice.Text‘读取入货信息记录中该产品的原来的数量strSQL="SELECT*FROM入货信息WHEREID=‘"&txtID.Text&"‘"dr=ExecuteReadSQL(strSQL,LogicDlg.GstrPathName,LogicDlg.GstrPassWord)dr.Read()nOriginality_Amount=dr.Item("数量")‘读取产品信息记录中该产品的原来的数量strSQL="SELECT*FROM产品信息WHERE产品代码=‘"&txtCode.Text&"‘"dr=ExecuteReadSQL(strSQL,LogicDlg.GstrPathName,LogicDlg.GstrPassWord)dr.Read()Remain_Amount=dr.Item("数量")‘Remain_Amount即修改入货信息后,仓库中该产品的剩余数量Remain_Amount=Remain_Amount-nOriginality_Amount+nAmount‘检查修改入货产品的数量后,仓库中该产品的剩余数量大于等于零,若果数量是负数则报错If(Remain_Amount>=0)Then‘修改入货信息记录strSQL="UPDATE入货信息SET产品代码=‘"&strCode&"‘,供货商=‘"&strPurchaser&"‘,经办人=‘"&strPrincipal&"‘,备注=‘"&strRemark&"‘,数量=‘"&nAmount&"‘,总价=‘"&nPrice&"‘,时间=‘"&GstrTime&"‘WHEREID=‘"&txtID.Text&"‘"ExecuteNonSQL(strSQL,LogicDlg.GstrPathName,LogicDlg.GstrPassWord)‘修相应产品信息的数量strSQL="UPDATE产品信息SET数量=‘"&Remain_Amount&"‘WHERE产品代码=‘"&txtCode.Text&"‘"ExecuteNonSQL(strSQL,LogicDlg.GstrPathName,LogicDlg.GstrPassWord)ElseMsgBox("修改后的产品数量不合法!")EndIf‘释放所有数据库对象dr.Close()‘关闭对话框Close()1.1远程数据库访问模块设计远程数据访问(RDA)使用SQLServerMobile的三个组件:SQLServerMobile数据库引擎、SQLServerMobile客户端代理和SQLServerMobile58
服务器代理。RDA使用MicrosoftInternet信息服务(IIS)作为服务器上SQLServer数据库和设备上SQLServerMobile数据库之间的通信机制。SQLServerMobile数据库引擎、SQLServerMobile客户端代理和SQLServerMobile服务器代理协同工作才可以完成RDA,其框架如图5.7所示。图5.7RDA系统模型图SQLServerMobile中的远程数据访问(RDA)允许应用程序从远程SQLServer数据库表中访问数据,并将数据存储到本地SQLServerMobile数据库表中。随后,应用程序可以读取和更新本地SQLServerMobile数据库表。SQLServerMobile可以选择跟踪对本地表所做的所有更改。稍后,应用程序可以将本地表中更改的记录更新回SQLServer表中。表5.3列出了RDA的常用方法。表5.3RDA的常用方法方法说明Pull方法(RDA)从远程MicrosoftSQLServer数据库检索数据,并将该数据存储在位于本地SQLServerMobile数据库内的单个表中。通常称之为请求数据。Push方法(RDA)从本地跟踪的SQLServerMobile表向原始的远程SQLServer表发回更改。通常称之为提交数据。SubmitSQL方法(RDA)提交SQL语句,以在远程SQLServer数据库上执行。58
1.1.1数据库的同步合并通常情况下,用户间歇地将设备连接到网络。这些连接允许应用程序同步在订阅服务器上所做的更改与在发布服务器上所做的更改。通过调用SqlCeReplication类公开的同步方法,应用程序启动同步。同步过程分为四个步骤:1.提取更改并创建输入消息文件。2.运行SQLServer协调器进程并将更改应用到发布数据库。3.创建输出消息文件。4.读取输出消息文件并将更改应用到SQLServerMobile订阅数据库。通常这四个步骤都不需要开发者完成,数据库接口程序提供了SqlCeReplication类,数据库订阅者只要填写好相应的服务器信息就可以与远程数据库进行同步,其中strDataBasePath为目标数据库的路径和名称,strDataBasePassWord为目标数据库的密码,strSync_Url为数据库服务器的URL,strSync_InternetLogin为服务器Internet登录名,strSync_InternetPass为服务器Internet密码,strSync_Publisher为远程数据库发布名称,strSync_PublisherDatabase为SQL登录名,strSync_PublisherLogin为SQL密码,strSync_PublisherPass为远程服务器名称,strSync_Publication为远程服务器名称。其详细代码如程序清单5.12所示。程序清单5.12数据库同步合并代码SubSynch(ByValstrDataBasePathAsString,ByValstrDataBasePassWordAsString,_ByValstrSync_UrlAsString,ByValstrSync_InternetLoginAsString,_ByValstrSync_InternetPassAsString,ByValstrSync_PublisherAsString,_ByValstrSync_PublisherDatabaseAsString,ByValstrSync_PublisherLoginAsString,_ByValstrSync_PublisherPassAsString,ByValstrSync_PublicationAsString)‘创建合并复制对象DimreplAsNewSqlCeReplicationTryWithrepl.InternetUrl=strSync_Url.InternetLogin=strSync_InternetLogin.InternetPassword=strSync_InternetPass.Publisher=strSync_Publisher.PublisherDatabase=strSync_PublisherDatabase.PublisherLogin=strSync_PublisherLogin.PublisherPassword=strSync_PublisherPass.Publication=strSync_Publication.PublisherSecurityMode=SecurityType.DBAuthentication58
.Subscriber=Dns.GetHostName().SubscriberConnectionString="DataSource="&strDataBasePath&";Password="&strDataBasePassWord‘在SQLServerMobile订阅和SQLServer发行者之间调用合并复制.Synchronize()EndWithCatchexAsExceptionMsgBox(ex.ToString())Finallyrepl.Dispose()EndTryEndSub1.1.1向服务器申请或提交数据远程数据访问通常是通过将数据从MicrosoftSQLServer请求到SQLServer2005MobileEdition(SQLServerMobile)客户端数据库启动的。要把数据从服务器请求到客户端时,可以使用System.Data.SqlServerCe命名空间的SqlCeRemoteDataAccess类。若要从服务器中请求数据,可以在应用程序中以编程方式配置RDA。当使用上述任一方法设置和启动请求操作时,都将指定以下内容:l要从中请求数据的目标数据库l连接到Web服务器所需的Web服务器身份验证;l使用的SQLServer身份验证;l将被复制并传播到客户端的表;向服务器提交数据的过程与从服务器中请求数据的过程基本相同,本设计中把提交数据的代码封装成了一个函数,申请数据的函数的代码也大致相同,只需要把Push方法改成Pull方法,提交和申请需要提供的系统信息由:myTable为需要创建的表的表名,strDataBasePath为目标数据库的路径和名称,strDataBasePassWord为目标数据库的密码,strRemote_Url为数据库服务器的URL,strRemote_InternetLogin为服务器Internet登录名,strRemote_InternetPass为服务器Internet密码,strRemote_RemoteDatabase为远程数据库名称,strRemote_SQLUser为SQL登录名,strRemote_SQLPass为SQL密码,strRemote_ServerName为远程服务器名称,其代码如程序清单5.13所示。程序清单5.13向服务器提交数据PublicSubTablePush(ByValTable_NameAsString,ByValstrDataBasePathAsString,_ByValstrDataBasePassWordAsString,ByValstrRemote_UrlAsString,_58
ByValstrRemote_InternetLoginAsString,ByValstrRemote_InternetPassAsString,_ByValstrRemote_RemoteDatabaseAsString,ByValstrRemote_SQLUserAsString,_ByValstrRemote_SQLPassAsString,ByValstrRemote_ServerNameAsString)DimstrserverconnstrAsStringDimrdaAsNewSqlCeRemoteDataAccess()strserverconnstr="Provider=SQLOLEDB;DataSource="&strRemote_ServerName&";InitialCatalog="&strRemote_RemoteDatabase&";UserId="&strRemote_SQLUser&";Password="&strRemote_SQLPassrda.InternetLogin=strRemote_InternetLoginrda.InternetPassword=strRemote_InternetPassrda.InternetUrl=strRemote_Urlrda.LocalConnectionString="DataSource="&strDataBasePath&";Password="&strDataBasePassWordTryrda.Push(Table_Name,strserverconnstr,RdaBatchOption.BatchingOn)CatchexAsExceptionMsgBox(ex.ToString,MsgBoxStyle.Critical)rda.Dispose()EndTryrda.Dispose()EndSub1.1客户机界面设计客户机提供两种登录方式如图4.7所示。一种是使用本地上已存在的SQL数据库,另一种是在本地上创建新的SQL数据库。两种方式都要求输入数据库名称和密码,第一种方式中,用户输入的名称和密码即为新数据库的名称和访问密码;第二种方式中,用户输入的名称和密码用于打开本地的加密数据库。图5.8管理员客户机的登陆对话框58
成功登陆后就可以进入管理员客户机的主界面如图5.9所示,右上方的三个按钮对应着三个操作选项:库存记录、出货记录和入货记录。下方的是对数据记录的基本操作,包括添加、删除、查找和修改,系统功能包括数据库同步合并,信息打印和帮助。图5.9产品信息管理界面添加新产品信息对话框如图5.10所示,产品代码具有唯一性,不能输入已存在的产品代码,而数量、单价和毛重则都不能为空。图5.10添加产品信息对话框管理员修改了数据库后需要将修改信息反馈到服务器时,可以使用系统的远程数据库同步合并对话框如图5.11所示。为了保证数据的安全性,数据库服务器同步合并时需要申请者提供帐户,密码以及完整的服务器信息,确定用户权限以后,才能成功实现数据同步合并。58
图5.11同步合并远程数据库对话框为了方便用户使用数据库信息,本系统还提供了数据打印功能如图5.12所示。数据打印需要打印机的支持,本系统的打印模块是基于失眠上的标准串口打印机设计的,理论上可以兼容市面上的任何标准串口打印机。图5.12打印预览对话框58
参考文献[1]张冬泉.WindowsCE实用开发技术[M].北京:电子工业出版社,2007.[2]周立功.ARM&WinCE实验与实践[M].北京:北京航空航天大学出版社,2007.[3]汪兵.EVC高级编程及其应用开发[M].北京:中国水利水电出版社,2007.[4]求是科技.SQLServer2000数据库开发技术与工程实践[M].北京:人民邮电出版社,2004.[5]广州致远电子有限公司.SQLServerMobile数据库编程示例.产品应用笔记.2008[6]广州致远电子有限公司.Web串口远程控制示例.产品应用笔记.200858
附录A串口驱动程序代码SerialObject.h文件源代码#defineQUEUE_SIZE51200/*接收队列缓冲区大小*/#defineBUFFER_SIZE1024/*从串口驱动读取数据的接收缓冲区大小*/typedefstruct_SERIALCFG{BYTEbBaudSel;/*波特率序号*/BYTEbDataBitSel;/*数据位序号*/BYTEbStopBitSel;/*停止位序号*/BYTEbParitySel;/*校验类型序号*/}SERIALCFG;/*定义串口配置情况结构体*/classCSerialObject/*定义串口对象类*/{public:SERIALCFGm_SerialCfg;/*用于传出串口已配置情况*/public:DWORDRead(PBYTEpRcvBuffer,DWORDdwToReadLen);BOOLWrite(PBYTEpSndBuffer,DWORDdwLength);voidClose();BOOLIsOpen();BOOLOpen(BYTEbPort,BYTEbBaudRate,BYTEbDataBit,BYTEbStopBit,BYTEbParity);CSerialObject();virtual~CSerialObject();private:staticDWORD__stdcallRecvThread(LPVOIDpParam);HANDLEm_hComm;/*串口流驱动文件句柄*/PBYTEm_pQueueBuf;/*接收队列缓冲区指针*/DWORDm_dwQueueIndexIn;/*接收队列追加数据点序号*/DWORDm_dwQueueIndexOut;/*接收队列取数据点序号*/DCBm_dcb;/*串口设备控制块结构体,包含串口配置信息*/CRITICAL_SECTIONm_csQueue;/*接收队列临界对象*/staticvoidCALLBACKCommRecv(LPVOIDpParam,PBYTEpBuf,DWORDdwLen);};#endif//!defined(AFX_SEIALOBJECT_H__1D103668_E3B1_4DB0_8A73_36DAD26D9C68__INCLUDED_)58
SerialObject.cpp文件源代码*****************************************************************************************///SerialObject.cpp:implementationoftheCSerialObjectclass.#include"stdafx.h"#include"SerialObject.h"#defineUBOUND(name,type)(sizeof(name)/sizeof(type))/*用于计算数组元素个数*/constTCHAR*g_szCommPortTbl[]={_T("COM1:"),_T("COM2:"),_T("COM3:"),_T("COM4:")};/*串口文件名表*/constintg_nBaudRateTbl[]={110,300,600,1200,2400,4800,9600,14400,19200,38400,56000,57600,115200};/*串口波特率表*/constintg_nDataBitTbl[]={5,6,7,8};/*串口数据位表*/constintg_nStopBitTbl[]={0,1,2};/*串口停止位表*/constintg_nParityTbl[]={NOPARITY,ODDPARITY,EVENPARITY,MARKPARITY,SPACEPARITY};/*串口校验类型表*//********************************************************************************************Functionname:CSerialObject::CSerialObject()**Descriptions:串口对象类构造函数**Inputparameters:无**Outputparameters:无**Returnedvalue:无******************************************************************************************/CSerialObject::CSerialObject(){m_hComm=INVALID_HANDLE_VALUE;m_pQueueBuf=NULL;m_dwQueueIndexIn=0;m_dwQueueIndexOut=0;memset(&m_SerialCfg,0,sizeof(SERIALCFG));InitializeCriticalSection(&m_csQueue);}/********************************************************************************************Functionname:CSerialObject::CSerialObject()**Descriptions:串口对象类析构函数**Inputparameters:无**Outputparameters:无**Returnedvalue:无******************************************************************************************/CSerialObject::~CSerialObject(){58
Close();DeleteCriticalSection(&m_csQueue);}/********************************************************************************************Functionname:CSerialObject::Open()**Descriptions:打开串口**Inputparameters:bPort:串口序号**bBaudRate:波特率序号**bDataBit:数据位序号**bStopBit:停止位序号**bParity:校验类型序号**Outputparameters:无**Returnedvalue:TRUE:成功FALSE:失败******************************************************************************************/BOOLCSerialObject::Open(BYTEbPort,BYTEbBaudRate,BYTEbDataBit,BYTEbStopBit,BYTEbParity){BOOLbRet=TRUE;COMMTIMEOUTSctoTimeOut;if(IsOpen())returnFALSE;/*判断是否已打开了*/if(bPort>=UBOUND(g_szCommPortTbl,constTCHAR*)||bBaudRate>=UBOUND(g_nBaudRateTbl,constint)||bDataBit>=UBOUND(g_nDataBitTbl,constint)||bStopBit>=UBOUND(g_nStopBitTbl,constint)||bParity>=UBOUND(g_nParityTbl,constint)){/*判断传入参数是否有越界*/returnFALSE;}m_hComm=CreateFile(g_szCommPortTbl[bPort],GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);if(m_hComm==INVALID_HANDLE_VALUE)returnFALSE;GetCommState(m_hComm,&m_dcb);/*读取串口的DCB*/m_dcb.BaudRate=g_nBaudRateTbl[bBaudRate];/*波特率设置*/m_dcb.ByteSize=g_nDataBitTbl[bDataBit];/*数据位设置*/m_dcb.StopBits=g_nStopBitTbl[bStopBit];/*停止位设置*/m_dcb.Parity=g_nParityTbl[bParity];/*奇偶校验设置*/m_dcb.fParity=(m_dcb.Parity!=NOPARITY);m_dcb.fBinary=TRUE;m_dcb.fOutX=FALSE;/*禁止软件流控制。fOutX:收到Xoff后停止发送*/58
m_dcb.fInX=FALSE;/*禁止软件流控制。fInX:缓冲区接收满后发送Xoff*/m_dcb.fTXContinueOnXoff=FALSE;/*禁止软件流控制。fInX事件之后,发送是否继续运行*//**设置状态参数*//*串口事件:接收到一个字符*/SetupComm(m_hComm,16384,16384);/*设置接收与发送的缓冲区大小*/if(!SetCommState(m_hComm,&m_dcb)){/*设置串口的DCB*/CloseHandle(m_hComm);m_hComm=INVALID_HANDLE_VALUE;returnFALSE;}PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);GetCommTimeouts(m_hComm,&ctoTimeOut);ctoTimeOut.ReadIntervalTimeout=10;/*接收字符间最大时间间隔*/ctoTimeOut.ReadTotalTimeoutMultiplier=1;ctoTimeOut.ReadTotalTimeoutConstant=10;/*读数据总超时常量*/SetCommTimeouts(m_hComm,&ctoTimeOut);EnterCriticalSection(&m_csQueue);if(!m_pQueueBuf){/*未申请除列缓冲区则进行申请*/bRet=((m_pQueueBuf=newBYTE[QUEUE_SIZE])!=0);}LeaveCriticalSection(&m_csQueue);if(bRet){DWORDdwId;HANDLEhThread=CreateThread(NULL,0,RecvThread,this,0,&dwId);/*创建接收线程*/CloseHandle(hThread);m_SerialCfg.bBaudSel=bBaudRate;m_SerialCfg.bDataBitSel=bDataBit;m_SerialCfg.bStopBitSel=bStopBit;m_SerialCfg.bParitySel=bParity;}else{CloseHandle(m_hComm);m_hComm=INVALID_HANDLE_VALUE;}returnbRet;58
}/********************************************************************************************Functionname:CSerialObject::IsOpen()**Descriptions:判断串口是否已经打开**Inputparameters:无**Outputparameters无**Returnedvalue:TRUE:是FALSE:否******************************************************************************************/BOOLCSerialObject::IsOpen(){return(m_hComm!=INVALID_HANDLE_VALUE);}/********************************************************************************************Functionname:CSerialObject::Close()**Descriptions:关闭串口**Inputparameters:无**Outputparameters:无**Returnedvalue:无******************************************************************************************/voidCSerialObject::Close(){if(IsOpen()){SetCommMask(m_hComm,0);PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);CloseHandle(m_hComm);m_hComm=INVALID_HANDLE_VALUE;}EnterCriticalSection(&m_csQueue);if(m_pQueueBuf){delete[]m_pQueueBuf;/*释放申请的接收队列缓冲区*/m_pQueueBuf=NULL;}LeaveCriticalSection(&m_csQueue);}/********************************************************************************************Functionname:CSerialObject::Write()**Descriptions:发送数据**Inputparameters:pSndBuffer:发送数据缓冲区**dwLength:要发送数据长度58
**Outputparameters:无**Returnedvalue:TRUE:成功FALSE:失败******************************************************************************************/BOOLCSerialObject::Write(PBYTEpSndBuffer,DWORDdwLength){DWORDdwActLen;COMSTATcomstatTest;DWORDdwErrorFlags;if(!IsOpen()||(pSndBuffer==NULL)||(dwLength<1))returnFALSE;ClearCommError(m_hComm,&dwErrorFlags,&comstatTest);WriteFile(m_hComm,pSndBuffer,dwLength,&dwActLen,NULL);returnTRUE;}/********************************************************************************************Functionname:CSerialObject::Read()**Descriptions:从接收队列读取数据**Inputparameters:dwToReadLen:要读取数据长度**Outputparameters:pRcvBuffer:接收缓冲区,将向接收缓冲区写入接收到的数据**Returnedvalue:实际读取的数据字节数******************************************************************************************/DWORDCSerialObject::Read(PBYTEpRcvBuffer,DWORDdwToReadLen){DWORDdwIndex=0;PBYTEpQueueBuf=0;DWORDdwQueueDataSize=0;EnterCriticalSection(&m_csQueue);dwIndex=m_dwQueueIndexOut;pQueueBuf=m_pQueueBuf+dwIndex;dwQueueDataSize=m_dwQueueIndexIn>=m_dwQueueIndexOut?m_dwQueueIndexIn-m_dwQueueIndexOut:m_dwQueueIndexIn+QUEUE_SIZE-m_dwQueueIndexOut;dwToReadLen=dwToReadLen=QUEUE_SIZE){dwIndex=0;pQueueBuf=m_pQueueBuf;}58
}m_dwQueueIndexOut=dwIndex;LeaveCriticalSection(&m_csQueue);returndwToReadLen;}/********************************************************************************************Functionname:CSerialObject::CommRecv()**Descriptions:接收数据回调函数**Inputparameters:pParam:线程传入参数**pBuf:接收缓冲区指针**dwLen:接收数据长度**Outputparameters:无**Returnedvalue:实际读取的数据字节数******************************************************************************************/voidCSerialObject::CommRecv(LPVOIDpParam,PBYTEpBuf,DWORDdwLen){CSerialObject*pObj=(CSerialObject*)pParam;DWORDdwQueueFree=0;if(pObj->m_pQueueBuf){EnterCriticalSection(&pObj->m_csQueue);dwQueueFree=pObj->m_dwQueueIndexIn>=pObj->m_dwQueueIndexOut?pObj->m_dwQueueIndexOut+QUEUE_SIZE-pObj->m_dwQueueIndexIn:pObj->m_dwQueueIndexOut-pObj->m_dwQueueIndexIn;if(dwQueueFree>1){/*循环队列最后一个空位不能使用*/dwLen=(dwLenm_dwQueueIndexIn;PBYTEpQueueBuf=pObj->m_pQueueBuf+dwIndex;for(DWORDi=0;i=QUEUE_SIZE){dwIndex=0;pQueueBuf=pObj->m_pQueueBuf;}}pObj->m_dwQueueIndexIn=dwIndex;}LeaveCriticalSection(&pObj->m_csQueue);58
}}/********************************************************************************************Functionname:CSerialObject::RecvThread()**Descriptions:串口接收线程函数**Inputparameters:pParam:线程传入参数*Outputparameters:无**Returnedvalue:0******************************************************************************************/DWORDCSerialObject::RecvThread(LPVOIDpParam){CSerialObject*pObj=(CSerialObject*)pParam;BYTE*pucRcvBuf=newBYTE[BUFFER_SIZE];DWORDdwLength;BOOLbReadState;while(TRUE){if(pObj->m_hComm==INVALID_HANDLE_VALUE)break;bReadState=ReadFile(pObj->m_hComm,pucRcvBuf,BUFFER_SIZE,&dwLength,NULL);if(bReadState){/*接收成功调用回调函数*/if(dwLength!=0){pObj->CommRecv(pParam,pucRcvBuf,dwLength);}}Sleep(1);}delete[]pucRcvBuf;return0;}58
感谢在导师的辅导下,经过两个多月的学习与研究,终于完成了本次设计。从论文的选题、论文的审阅到论文的完成等方面都凝聚着导师的心血。导师渊博的学识、严谨的治学态度、为人谦虚的品格,都使我受益匪浅。从导师身上,我不仅学到先进的科学思想,更重要的是导师严谨的科学态度和做人的品格会让我终身受益。在此,我首先向王老师说声:谢谢,老师您辛苦了!并祝愿王老师身体健康,工作顺利,在以后的教研工作中取得更加辉煌的成果。同时,也向我的同学们表示感谢,在做毕业设计期间他们给了我很多的帮助,马上就要毕业了,愿他们一路走好!最后,我要特别感谢学校有关领导给予我这次学习的机会,衷心的感谢在我学习期间给予过我帮助和支持的所有老师和领导。58