的环境监测数据采集系统设计.pdf
作者简介作者简介:刘建鑫,男,1980 年出生,汉族,黑龙江省牡丹江市人,硕士,中科天融(北京)科技有限公司研发部工程师。从事环境监测气体分析仪器研发及电路设计工作。基于 PIC18F4550 的环境监测数据采集系统设计 刘建鑫,郭炜,胡刚(中科天融(北京)科技有限公司,北京,100085)摘要摘要:本文介绍了基于 PIC18F4550 单片机和 USB-HID 类的数据采集系统,并列举了该系统在环保分析仪器中的应用实例。详细介绍了相关的电路设计、单片机固件程序和上位机程序的开发流程。该方案具有实用性强,成本低廉,开发周期短等特点。关键字关键字:PIC18F4550;USB;数据采集;HID 中图分类号中图分类号:X851 Design of A USB Data Acquisition System for Environment Monitoring Based on PIC18F4550 MCU LIU Jian-Xin,guowei,hugang (Talroad Technology LTD.,Beijing,100085,China)Abstract:This article introduces a USB data acquisition system based on PIC18F4550 MCU and USB-HID Class,and describes an application of it.Related Circuits,MCU firmware and PC program are also introduced in detail.This system is characterized with practicability,inexpensiveness and rapidity of developing period.Keywords:PIC18F4550;USB;data acquisition;HID 引言 USB(Universal Serial BUS,通用串行总线)接口现今已经成为各种计算机上的通用配置,具有高速性、易获得性和兼容性等突出特点。与其他数据传输方式相比,USB 总线硬件集成自动数据校验和自动重发功能,具有较高可靠性。从传输速度上看,USB 总线适用于对采集速度要求适中的场合,可满足大部分测量采集应用的需要。所以,使用 USB 技术的数据采集系统非常适合应用在各种环保监测设备中。但是 USB 技术有一定复杂性,USB 标准文档内容多且抽象,涉及的知识广泛,导致很多工程技术人员入门困难,往往将大量开发时间浪费在 USB 通信方面,而非重要的应用上。针对此问题,本文介绍一种基于 PIC18F4550 单片机和 Windows USB HID 类设备驱动程序进行USB 接口采集系统的开发方法,具有上手容易、开发周期短、成本低廉和性能优良等特点,适合各种环保在线监测领域的数据采集应用。1 1 PIC18F4550PIC18F4550 单片机介绍单片机介绍 芯片 PIC18F4550 来自 MCU 厂商 Microchip,属于带有 USB 接口的特殊功能中高档单片机,编译环境及仿真器与其他 PIC 系列的单片机相同,程序开发过程也类似,所以对于有单片机开发经验的工程师来说很容易上手。该芯片主要有如下特点1:1、内置稳压器的片上 USB 收发器,兼容 USB V2.0 标准,支持低速(1.5 Mb/s)和全速(12 Mb/s);2、最多 13 路通道 10 位精度模数转换器模块(A/D);3、具有 8 x 8 单周期硬件乘法器;4、具有增强型 CCP 模块:在 PWM 模式下,该模块提供 10 位分辨率的 1、2 或 4 路调制输出来控制半桥和全桥驱动器,适用于直流电机的控制;5、具有常用电路接口。可通过此芯片轻松实现 USB 转并行接口、GPIO、I2C、SPI、PWM等功能;可以通过 I2C 或 SPI 接口外接 ADC 芯片来进行扩更高精度或更高速率的 ADC 展。6、具有增强型通用同步/异步收发器(Universal Synchronous Asynchronous Receiver Transmitter,USART),可以在模块的基础上轻松扩展出 RS232 或 RS485 接口,还可实现更多功能,包括自动波特率检测和校准,以及自动唤醒,这些使 EUSART 模块成为局域互连网络(Local Interconnect Network,LIN)总线系统非常理想选择。总之,芯片 PIC18F4550 价格低廉,接口丰富,功耗低,可利用的开发资源丰富,既拥有USB 接口可进行高速数据通信,又具有单片机外设接口丰富、开发简便、控制能力强等特点,特别适合用于构建中低速数据测量及控制系统。2 2 数据采集系统电路设计数据采集系统电路设计举例举例 基于 PIC18F4550 的数据采集系统除可实现与上位机的 USB 通信功能外,还能够方便地拓展出多种电路接口,方便工程师根据应用灵活配置外围电路模块。图 1 硫气体分析仪中基于 PIC18F4550 的数据采集子系统 例如在 TR2294B1 气体分析仪中使用的数据采集系统即基于 PIC18F4550 芯片(如图 1),该采集系统实现如下功能:1、通过 ADC 电路模块放大、采集 KE-25 氧传感器信号,实时测量样气中的氧浓度;2、利用温度传感器 18B20 测量分析仪机箱内的工作温度,并使用 PID 控制算法输出 PWM信号调节机箱风扇转速,使机箱内温度的波动保持在0.1范围内,从而使设备传感器工作稳定,减少分析仪的温度漂移;PIC18F4550 温度传感器 18B20 氧传感器 KE-25 闪光氙灯 散热风扇 USB SPI SPI 420mA 电流输出 PWM 主机 3、发出脉冲信号控制紫外脉冲氙灯闪光;4、通过控制阀泵的通断来切换气路;5、将测量数据以 420mA 的形式向外输出。下面对其中的 USB 通信、AD 采集和 420mA 电流信号输出部分进行详细说明。图 2 PIC18F4550 实现 USB 通信功能的电路模块 首先,通过 PIC18F4550 进行 USB 通信,需要在电路上进行相应配置。图 2 是 PIC18F4550采集系统 USB 通信接口电路。其无需外接电源,而是直接从 USB 接口中的 Vbus 取电,最大取电电流可达 500mA。根据 USB 规范的要求,D-或 D+端口必须有上拉电阻,大小为 1.5 k(5%),在 PIC18F4550 芯片内部集成了内部上拉电阻,用户可以在程序中进行选择配置,将上拉电阻加载在 D+端口,表示配置为全速设备(Full speed),将上拉电阻加载在 D-端口,表示配置为低速设备(Low speed)。芯片的 Vusb 引脚为使用外部上拉电阻提供 3.3V 电源,当使用内部上拉电阻时不使用该引脚,可将其禁用,但无论怎样配置,一定要在该引脚上外接 470pF 的电容,否则会导致 USB通信不正常。芯片一般外接20MHz晶振,也可使用其他低频率的晶振。因为要为USB通信模块提供48MHz时钟,芯片使用锁相环将外接晶振频率转化为 48MHz 时钟,所以外接晶振频率值不是任意,具体可参考 PIC18F4550 的使用手册进行选择。为防止晶振时钟信号上升沿退化,可在晶振两端跨接 1M 电阻。ADC 模拟电压信号采集模块使用 AD7705BZ 芯片组建(如图 3),适用于低频 16 位精度信号采集。ADC 芯片 AD7705BZ 集成信号放大与采集功能,带有数字滤波功能,温漂小,非常合适低频小信号的采集。图 3 ADC 模块电路 电流信号输出模块使用 12 位精度 DAC 芯片 TLV5614C 和 420mA 输出芯片 XTR115U 组建(如图 4),精度高,抗干扰能力强,适用于信号的远程传输;可使用一片 TLV5614C 实现 4路输出(图 4 中仅实现 1 路);电流输出部分使用 24V 电压供电。图 4 420mA 电流信号输出电路 3 3 单片机程序设计单片机程序设计 通过 PIC18F4550,可以实现各类应用,例如 USB 存储设备、音频视频设备、人机交互设备、打印设备等,USB 规范中也针对不同类别的应用而定义了很多标准应用类。其中应用比较广泛且开发简便的一个是 HID(Human Interface Device,人机接口设备)类。HID 类设备并不一定要有人机接口,只要符合 HID 类别规范的设备都是 HID 类设备,可以将 HID 类应用于其他非人机交互的应用,其具有以下优点23:1、实时性强,延迟时间有保障。HID 类使用中断或控制的方式进行数据传输,上位机 Host以最低 1ms 的周期轮询 USB HID 设备,上位机 Host 对通信的响应有最长保证时间。从而适合数据采集、控制等应用。2、Windows 操作系统为 USB HID 类提供了充分的驱动程序支持,提供了丰富的 API 接口供用户调用。只要芯片的通信数据支持 HID 规范,用户便不必开发 Windows 底层驱动程序,大大减少了开发工作量。由于 HID 类设备具有以上优点,所以特别适合应用于中低速的数据采集系统。为了支持用户 USB 产品的开发,Microchip 公司为其生产的带 USB 通信功能的单片机提供 MCHPFSUSB Framework 开发包。开发包中包含了各种 USB 应用程序的框架、实例和详细的说明文档,帮助用户在短时间内开发出符合自身要求的 USB 应用系统。MCHPFSUSB Framework开发包中为 HID 类程序提供的程序结构如图 5。图 5 PIC18F4550 HID 类程序结构 其中通用代码主要完成编译器相关的设置和通用数据类型的定义;USB 配置代码用于设置 USB 传输活动;USB 程序栈中的各部分代码用于处理 USB 底层数据传输任务,对于初步接触 USB 开发的人员,可先不必深入此部分代码。用户应用代码主要位于 main.c 文件中的ProcessIO()函数中,是用户根据实际应用需要而编写的应用程序,对于数据采集系统而言,这部分代码主要应该完成外部数据的采集,并及时上传给上位机,同时监控上位机的应用控制命令,完成对外部设备的控制。下面对用户代码的框架进行说明(如图 6)。在单片机程序中有两种处理 USB 通信总线事务的方式,一是中断方式,即当总线上有 USB事务时,触发芯片的高优先级中断处理函数 YourHighPriorityISRCode(),在其中调用USBDeviceTasks()来对事务进行处理;另一种方式是采用轮询的方法,即在主程序中的无限循环中定期调用 USBDeviceTasks()。用户应用代码主要位于 ProcessIO()函数中,是用户根据实际应用需要而编写的应用程序。在该函数中,使用 HIDRxHandleBusy(USBOutHandle)函数来检查是否有数据被接收,使用 HIDTxHandleBusy(USBInHandle)函数检查是否可以向上位机上传数据;收到的数据被放置在 ReceivedDataBuffer 数组中,要发送的数据需被放置在 ToSendDataBuffer 数组中;使用HIDRxPacket 函数接收数据,使用 HIDTxPacket 函数发送数据。PIC18F4550 USB-HID 类程序 通用代码 USB 配置代码 用户应用代码 Compiler.h GenericTypeDefs.h usb_config.h usb_descriptors.c main.c USB 程序栈 usb.h usb_device.h usb_ch9.h usb_device.c usb_function_hid.c 图 6 PIC18F4550 用户应用程序举例 4 4 上位机上位机 WindowsWindows 应用程序设计应用程序设计 由于 Windows 为 USB HID 类设备提供了充分支持,用户可不必编写底层驱动程序,节省了开发时间,上位机的应用程序可直接通过调用各个 Windows API 来对 HID 设备进行操作。程序的具体操作步骤如下4:1、首先需要定位设备,获取指定 HID 设备的路径,并监测设备的可用状态。为检测设备的插入和移除事件,程序须对相应插入和移除事件进行注册,将主窗口的句柄发送给RegisterDeviceNotification。当一个新设备被探测到或被移除,Windows 将向主窗口发送void YourHighPriorityISRCode()#if defined(USB_INTERRUPT)/如果使用中断方式处理 USB 总线事务 USBDeviceTasks();#endif void main(void)InitializeSystem();/初始化系统#if defined(USB_INTERRUPT)USBDeviceAttach();/检查设备的连接状态#endif while(1)#if defined(USB_POLLING)/如果使用轮询的方式处理 USB 总线事务 USBDeviceTasks();/处理 USB 总线事务#endif ProcessIO();/用户应用程序 void ProcessIO(void)/检查连接状态 if(USBDeviceState CONFIGURED_STATE)|(USBSuspendControl=1)return;if(!HIDRxHandleBusy(USBOutHandle)/检查是否有已接收数据 /依据用户应用,对数据进行处理 if(!HIDTxHandleBusy(USBInHandle)/检查是否可以发送数据 /发送数据 USBInHandle=HIDTxPacket(HID_EP,(BYTE*)&ToSendDataBuffer0,64);/定期接收数据 USBOutHandle=HIDRxPacket(HID_EP,(BYTE*)&ReceivedDataBuffer,64);WM_DEVICECHANGE 消息。在窗口程序中重写 WndProc 函数来对此消息进行处理。一旦有新设备被探测到,程序需要在当前 USB 总线的设备列表中搜索,来判断是否是应用所需的那个设备。为得到设备列表,调用 setupapi.dll 中的 USB API 函数 SetupDiGetClassDevs。SetupDiGetClassDevs 的第一个参数需要指定表示 HID 设备类的 GUID,这可通过调用 hid.dll中的 HidD_GetHidGuid 来实现。SetupDiGetClassDevs 函数开辟一块内存来存放数组,数组的每个元素对应一个设备。调用 setupapi.dll 中的 SetupDiEnumDeviceInterfaces 函数查找数组中是否包含所关注的那个设备。调用 SetupDiGetDeviceInterfaceDetail 填充DeviceInterfaceData 结构体,结构体中包含每个设备的路径,路径中含有设备的 VID 和 PID,可以对比要寻找设备的 VID 和 PID。如果都符合,即找到想要的设备。2、获取 HID 设备的能力信息。最重要的 HID 设备信息是能够传输数据的最大长度,从而上 位 机 可 以 为 传 输 的 数 据 开 辟 相 应 大 小 的 缓 冲 区。可 以 使 用 hid.dll 中 的HidD_GetPreparsedData 和 HidP_GetCaps 函数来获取每次能够传输数据的最大长度信息,并使用 HidD_FreePreparsedData 函数来清理临时内存空间。3、打开 HID 设备。可以像操作普通文件一样以 overlapp 方式使用 CreateFile API 函数对 HID 设备进行打开操作,支持并发的异步读写操作。一旦打开设备后,对设备的读写就如同对文件的读写,只不过数据的长度有限制,最大长度是由设备器件来决定。4、发送和接收数据。可以使用 FileIO.ReadFile 函数从 HID 设备接收数据,使用FileIO.WriteFile 函数向设备发送数据,这些操作均可异步地进行。上位机收到采集数据后可以根据应用进行后续深入处理。所有操作所用到的 API 函数见表 1。表 1 编写上位机程序需用到的 Windows API 函数 函数名称函数名称 DLL 功能描述功能描述 SetupDiGetClassDevs setupapi 获得某类的所有设备的列表 SetupDiDestroyDeviceInfoList setupapi 清理上一个函数分配的内存 SetupDiEnumDeviceInterfaces setupapi 获得一个已连接设备的详细信息 SetupDiGetDeviceInterfaceDetail setupapi 上一个函数的补充 HidD_GetPreparsedData hid 获取 HID 设备的描述 HidD_FreePreparsedData hid 清理上一个函数分配的内存 HidP_GetCaps hid 获取 HID 设备的能力 HidD_GetHidGuid hid 获取 HID 设备类的 GUID 限于篇幅,具体程序代码不在这里列出,可参考文献5。5 5 总结总结 基于 PIC18F4550 芯片和 USB-HID 类的数据采集系统,具有 USB 通信功能,集采集与控制功能于一体,成本低廉,可满足大部分环保监测分析仪研发过程中的试验、采集及控制应用的需要,具有广阔的应用前景。参考文献:参考文献:1 PIC18F4550 数据手册.Microchip Technology Inc.2007.2 Device Class Definition for Human Interface Devices(HID)Firmware SpecificationS.USB.org.2001.3 Universal Serial Bus Specification 2.0.USB.org.2000.4 Ashley Deakin.Making USB C#friendly.http:/www.vsj.co.uk/articles/display.asp?id=600.2006.5 Jan Axelson.USB Complete:The Developers Guide,Third EditionM.Lakeview research LLC.2007.联系方式联系方式:地址:北京市海淀区上地三街嘉华大厦 E 座 601 邮编:10085 办公电话:010-60701596 转 8027 手机:13552432627 E-mail: