下位机软件的流程图
系统开机之后对硬件开始初始化,包括TFT显示屏的描绘、PCF8563的数据读取、U盘的驱动等等。下面将根据实际的代码来了解该流程图。
2.3 系统软硬件初始化
系统开机之后就进入该状态,进入该状态的目的是为了将整个硬件配置到准备好的状态,进行后面数据的采集和传输,整个配置过程如下:
Ø 进行短时间的延时,等待系统稳定
Ø 将显示屏进行初始化
Ø USB接口的初始化,此时USB接口上必须有U盘插入,否则进入死循环
Ø 对RTC中断相关的寄存器进行设置
Ø 对2路串口以及串口对应的中断进行设置
Ø 对定时器及其中断相关的寄存器进行初始化
Ø 系统完成启动准备
2.4系统软件完成启动之后
系统完成了上面所说的初始化之后,开始正式进入到工作的状态,开始进行判断是否有一下三种请求,分别是“是否有接收数据中断请求”、“是否有数据上传请求”、“ 是否有固件升级请求”。
首先判断系统是否收到“数据接口端传送过来的数据”请求,如果有,则将传输过来的数据在显示屏上特定的位置显示出来,以实现即时显示的功能;如果没有收到,那么判断是否收到存储数据的请求。显示屏上的五个医疗监控项目如果没有收到新的数据,会显示“无”字样。
如果收到“上传数据请求”,首先会判断五个项目是否有新的数据,如果开机之后,某个项目一直没有收到数据,那么系统就直接跳过该过程。如果某项有新的数据,那么就会将该项目的数据进行上传,上传的过程是首先根据接收到的数据结合时间、ID号、项目类型生成一个固定格式的字符串,然后通过GPRS模块发送该字符串,发送后开启定时器,开始进行10秒钟的等待。这10秒的作用是用来给上位机发送接收应答,因为存在网络的延时,所以延时时间用的比较长,10秒钟之后,单片机会检测与GPRS相连接的串口是否收到了接收成功应答。如果接收到了,表示这次发送成功,此时将会检测U盘中是否有之前没有发送成功的数据保存在里面,如果有,将会读取该信息,并进行发送。当U盘中的数据发送结束或者U盘中没有存储的数据的时候,将会进行其他项目数据的发送。如果发送数据没有成功,则将生成的字符串保存到U盘中固定名称的文件中,并开始进行下一个项目的发送。
当接收到“固件升级请求”时,系统首先在U盘中的固定路径中创建一个名称为AP_ROM.HEX的文件然后关闭除了GPRS模块对应的串口中断之外所有的中断,并开始进行固件的接收。在接收的过程中不响应其他所有的中断,也不会更新接收到的数据,当接收完毕之后,会显示“结束”字样,此时用户应该手动将PB.7引脚接到GND上,然后重新开启系统,系统在再次开机的时候就会检测U盘中是否有固件,如果有,就会进行固件的更新,更新之后,自动进入新的固件下进行运行。
2.5 TFT显示屏驱动程序的设计
本系统用到的LCD是八位数据模式,驱动IC型号是ILI9325,该芯片最高支持26万色的TFT LCD,有6位、8位、16位和18位数据模式,可以方便选择。本系统配套的LCD使用的是八位数据模式,65K色。
(1)LCD读写寄存器
对LCD寄存器的操作线设置RS为低,表示写入寄存器,然后拉低片选信号,然后通过一个WR的脉冲,就可以把数据写入到LCD了。最后释放RS,CS,完成此次操作。对LCD寄存器的读操作和写操作差不多,不同之处就是把WR脉冲改为RD脉冲。
(2)LCD读写数据
对于LCD数据的读写,和寄存器的读写差不多,只要把RS设置为高,就表示此次操作是对数据的读写,其他同寄存器的读写操作一样。
对于以上两步,要注意在读写数据的时候必须先对寄存器写入0X0E/0X0F命令来表明是读还是写。
(3)LCD初始化
这部分是在前面两步成功的基础上才能进行的,LCD的初始化涉及到其内部很多寄存器的初始化。比较复杂,由void ILI9325_Initial(void)函数实现,具体初始化过程请参考代码。
(4)LCD画点
画点的实现,要先设置LCD开始显示和结束显示的范围,通过0X02H~0X04H这四个命令实现。之后写入0X0E命令,开始写入数据,就可以写入像素值(16bit)了,对于画点,我们只要写入一个像素点就可以了,这样就完成了在LCD上画一点。
以上四个函数是LCD的主要函数,是最底层的。其他任何功能的函数都可以在这几个底层函数基础上实现。其他功能的LCD驱动函数均在ILI9325.c里面有定义和说明,具体见附件。
2.6 RTC驱动程序的设计
PCF8563的读写采用标准的IIC接口,其内部共有16个8位寄存器,一个可自动增量的地址寄存器,一个内置32.768KHz的振荡器,一个分频器,一个可编程时钟输出,一个定时器,一个报警器,一个掉电检测器和一个400KHz标准 IIC总线接口。
所有16个寄存器设计成可寻址的8位并行寄存器,但不是所有位都有用。前两个寄存器(内存地址00H,01H)用于控制寄存器和状态寄存器,内存地址02H~O8H用于时钟计数器(秒~年计数器),地址09H~OCH用于报警寄存器(定义报警条件),地址ODH控制CLKOUT管脚的输出频率,地址OEH和OFH分别用于定时器控制寄存器和定时器控制器。秒、分钟、小时、日、月、年、分钟报警、小时报警、日报警寄存器,编码格式为BCD,星期和星期报警寄存器不以BCD格式编码。
当一个RTC寄存器被读时,所有计数器的内容被锁存,因此,在传送条件下,可以禁止对时钟/日历芯片的错读。
芯片数据的读写采用的是标准的IIC接口。
写模式过程为:首先主传送器发送一个起始信号;然后发送从设备地址,默认写地址为A2H,然后接收PCF8563应答信号;然后往从设备发送需要写入数据的内存地址,该地址根据具体的操作而定,发送后接收应答信号;然后主传送器发送需要写入特定内存中的数据,该数据根据具体而定,发送结束后接收PCF8563的应答信号,接收成功后发送IIC结束信号。
读模式过程为:首先主传送器发送一个起始信号;然后发送从设备地址,模式写地址为A2H,然后接收PCF8563应答信号;然后往从设备发送需要读取的寄存器的地址,具体的地址根据实际而定,等待PCF8563应答信号;当接收到应答信号之后,再发送起始信号,接着发送从设备地址信息,此时的地址模式为A3H,发送结束后等待从设备应答,接收到应答之后就可以从SDA读取数据信息了;如果采用连续内存读取,那么每次读取之后发送一个ACK,在读取的最后一个内存数据之后,发送一个NACK;然后发送一个结束信号。
2.7 GPRS驱动程序的设计
2.8 USB驱动程序的设计
CH563的USB程序是沁恒提供的库文件,无法读取到源程序,有开放的函数名供调用,使用很方便,所有的函数名见下表。
| |
UINT8 CH563GetVer( void ) | |
void CH563DirtyBuffer( void ) | |
UINT8 CH563DiskConnect( void ) | |
UINT8 CH563BulkOnlyCmd( void ) | |
UINT8 CH563DiskReady( void ) | |
UINT8 CH563AnalyzeError(UINT8 iMode ) | USB操作失败分析CH563IntStatus返回错误状态 |
UINT8 CH563FileOpen( void ) | |
UINT8 CH563FileClose( void ) | |
UINT8 CH563FileErase( void ) | |
UINT8 CH563FileCreate( void ) | |
UINT8 CH563FileModify( void ) | |
UINT8 CH563FileQuery( void ) | |
UINT8 CH563FileLocate( void ) | |
UINT8 CH563FileRead( void ) | |
UINT8 CH563FileWrite( void ) | |
UINT8 CH563ByteLocate( void ) | |
UINT8 CH563ByteRead( void ) | |
UINT8 CH563ByteWrite( void ) | |
UINT8 CH563DiskQuery( void ) | |
void CH563SaveVariable( void ) | 备份/保存/恢复子程序库的变量,用于子程序库在多个芯片或者U盘之间进行切换 |
USB操作相关的函数
在实际使用的过程中,有两种数据需要存储和读取,一种是在服务器没有给应答时候的存储数据到U盘中,另一种是接收固件文件并存储到U盘中指定路径中。
在使用之前,应该在U盘根目录下建立一个文件夹,名称为CH563,该文件夹的实际作用就是在固件升级的时候放置固件文件AP_ROM.HEX。如果不建立该文件夹,将会在固件升级的时候死机,并无法接收固件文件。
在存储未传输成功的数据时,是存储在U盘的根目录中的。存储的时候需要修改两个文件,分别是BACKUP.DAT和LOCATION.DAT文件。其中BACKUP.DAT是实际存储的数据文件;LOCATION.DAT文件中存储的是已发送数据文件指针位置和总数据长度。通过LODATION.DAT
2.9 开发语言和开发环境介绍
上位机采用的开发语言是C#,Microsoft Visual C#是一种功能强大、使用简单的语言,主要面向需要使用Microsoft .NET Framework来创建应用程序的开发者。它在C++和Microsoft Visual Basic的基础上去芜存菁,最终成了一种更加清晰、更富有逻辑的语言。C# 1.0于2001年亮相。随着C#2.0和Visual Studio 2005的问世,语言中新增了几个重要的功能,其中共包括泛型、迭代器和匿名方法等。随同Microsoft Visual Studio 2008发布的C# 3.0添加了更多的功能,例如扩展方法、lambda表达式以及最有名的语言集成查询(Language IntegratedQuery,LINQ)工具。语言的最新版本C# 4.0提供了进一步的增强,它改善了与其他语言和技术的互操作性。新增的功能包括命名和可选参数;dynamic类型,它告诉语言的“运行时”要实现一个对象的晚期绑定;以及斜变性和逆变性,它们解决了泛型接口的定义方式所造成的问题。C# 4.0利用了最新版本的 .NET Framework,新版本也是4.0。在这个版本中,.NET Framework添加了许多新的东西,但最重要的就是构成“任务并行库”(Task Parallel Library, TPL)的类和类型。现在可以使用TPL构建具有良好伸缩性的应用程序,从而快速和简单地利用多核处理器的强大能力。对Web服务和Windows Communication Foundation(WCF)的支持也得到了扩展;现在可以遵循REST模型和较传统的SOAP方案构建服务。
Microsoft Visual Studio 2010提供的开发环境使得这些强大的功能变得易于使用,Visual Studio 2010新增的大量想到和增强措施也显著提高了开发人员的工作效率。
Microsoft Visual Studio 2010启动之后的主界面如下图所示,图中显示的界面已经配置成C#语言开发模式。
3.0上位机的设计思路
上位机的主界面如下图所示,下面将根据实际开发过程从四个大点来分析设计思路,分别是SerialPort数据的接收、Excel文件的操作、折线图的绘画、固件的升级。
上位机主界面
3.1 SerialPort数据的接收
3.2 Excel文件的操作
在上位机系统中,数据的保存采用的是Excel文件的方式,采用该方式的原因主要是因为容易操作和脱离上位机程序时,直接打开Excel文件也可观察到具体的数据。
在4.2.1中我们讲述到接收到35字节长的数据后,从数据中提取出年、月、日、小时、分钟、ID、类型、数据值,根据接收到的数据,我们将会找到数据所要存储的路径。默认我们的数是保存在我的电脑中的D盘,具体保存路径为D:RCVDATAyearmonthdayIDkind.xls,路径中的year是具体接收到数据的年,month是具体接收到数据中的月,day是具体接收到数据中的日,ID是具体接收到数据中的ID号,kind是具体接收到数据中的类型,kind有五种分别是A、B、C、D、E,分别代表血压、心跳、脉搏、温度、血糖。
这样我们就根据接收到的数据找到需要保存的路径,然后打开改路径下的Excel文件,如果不存在,则会创建新的文件,并进行保存。
在保存的过程中我们采用的是冒泡法进行时间顺序进行存储,即在Excel文件中,所有的数据是按照时间顺序由上而下排列的,如下图所示。
Excel数据库数据格式
这样保存有一个好处,即在读取历史数据的时候,直接读取对应的文件,不需要再对数据进行排序,直接显示即可,数据也是按照时间顺序来显示的,方便观看。
如果耐心观察我们D盘下的数据库文件,还会发现在D:RCVDATAUSER下会有一个名为USER.xls文件,该文件中存储的是用户列表,即使用下位机的所有ID存储的地方;还有一个文件是FM.hex文件,该文件是下位机固件,如果选择升级,那么就会发送该文件。
至此有关Excel数据的操作就讲解完毕。
3.3 折线图的绘画
3.4固件的升级
该系统中固件的升级采用的是上位机主动控制下位机升级固件系统,在升级的时候,首先会向下位机发送一个升级开始操作符“UPGRADE_FIRM”,当下位机接收到这个字符串的时候,将会知道接下来串口接收到的数据是固件文件,此时它会关闭除了连接GPRS模块对应的串口的中断外的所有中断,并在U盘中的CH563目录下创建空固件文件AP_ROM.HEX,然后返还给服务器准备就绪信息字符串“CH563_REQUIRE_NEW_FIRMWAREXXXXXXXXX”,当上位机接收到该字符串之后,意味着此时可以进行发送固件文件了。通过点击对应的按钮开始发送固件文件。
固件发送的是hex文件,实例化一个StreamReader类型,通过运行代码SteamReader.Read()代码逐字符的读取文件中的数据。因为考虑到下位机的串口中断FIFO是14个字节,因此在实际发送的过程中,每发送14个字节,会进行短时间的延时,来给下位机足够的时间来处理中断,防止因为中断执行时被中断而造成数据没来得及存储而丢失。
3.5 使用指导
[url=]3.6 无线串口软件的配置[/url]
Comway无线串口软件与GPRS DTU配合使用,可以帮助用户建立远端串口设备和用户计算机之间的无线通信信道。此无线通信信道是基于北京天同诚业有限公司设立在专业机房中的Comway Data-Server集群服务器系统,该系统向广大中小客户及行业客户提供电信级无线数据通信服务。
拥有的Comway无线串口系统,就等于拥有了“无线延长的串口线”,能够方便的实现现有应用系统的改造和扩容。
该软件使用之前首先要进行注册一个账号,具体可以在打开软件的时候,点击“开户”并输入邮箱,几秒钟后邮箱将会收到包含密码的邮件,通过邮箱账号和密码就可以登陆该系统。
3.7 在用户私有账户中修改密码和添加DTU设备
用户通过用户认证后,进入如下图所示的系统界面,可以在此界面中任意空白位置点击鼠标右键来修改密码和添加本账户管理的DTU设备。
3.8 添加虚拟串口
点击任意一个DTU图标,按右键会弹出如下图所示的菜单。点击添加虚拟串口,系统将列出全部可以使用的串口清单,选择添加其中一个如:COM7,XP系统将自动添加虚拟串口驱动程序(将两次运行更新硬件,选择自动安装即可)。
选择一个与用户的串口设备相连接的DTU并为之添加虚拟串口,如图5.4所示。映射成功后再现DTU会显示映射到所选择的虚拟串口,如COM12.此时,应用该软件或串口调试软件如超级终端即可与此虚拟串口与远程设备进行实时双向通信了。
3.9上位机软件的使用
双击运行图标之后将会看到如下图显示的主界面,其中菜单栏有三个按键,分别是用户、编辑、帮助。有两个标签切换按钮,分别是“当前数据”、“历史数据”。默认的主界面显示的是当前数据界面。如果点击“历史数据”标签,将会显示历史数据界面。如下图所示。
在使用的时候,首先要将配置软件打开对应无线串口软件虚拟到的端口上,点击编辑——端口配置,弹出如图5.6所示的对话框,在下拉菜单中选择对应的COM口,然后点击确认设置,如果该端口没有被占用并且可用,就会打开该中断,此时软件的状态栏会显示“端口打开成功:COMX”,其中X表示具体打开的端口的编号。如果没有配置端口,则状态栏左边将会显示“端口尚未配置”。
在配置过端口之后,如果要停止数据的接收,也可以关闭对应的端口,具体操作是:点击编辑——关闭端口,此时状态栏左边将会显示“端口尚未配置”。在状态栏的右边显示的是此时的日期和时间。
历史数据界面
下面将从查看/添加用户、数据的接收、查看历史数据、固件升级四个方面来详细讲解上位机软件的使用方法。
4.0 查看/添加用户
默认情况下,上位机软件安装后首次运行时,用户库里面是没有用户信息的,此时如果接收到用户发来的数据,将会在主界面中显示“用户库中无此人”,并且接收到的数据不会存储和显示。
要使上位机正常记录数据信息,首先要做的就是将下位机的ID识别号添加进用户库中,这里需要注意,ID号的必须是以英文字母A开头,总长度为19个字符串。其操作方法是:点击用户——添加用户,将会弹出如图5.7所示的对话框,在弹出的对话框中输入下位机的ID识别号和对应的使用者的姓名,然后点击“确认添加”即可。
添加用户对话框
如果要查看上位机用户库中已经添加的所有用户,可以点击用户——查看用户列表,将会弹出如
该上位机软件没有删除用户的功能。所以添加用户之后从上位机角度无法删除用户列表,但是可以打开路径D:RCVDATAUSER路径下的数据库文件USER.xls,将对应的用户从其中删除即可。
4.1 数据的接收
如果上位机用户库中已经添加有效用户,并且下位机也配置好了,那么可以打开上位机的端口。具体操作为:点击编辑——端口设置,在弹出的对话框中选择对应的端口号,点击“确认设置”。
此时如果下位机有数据发送过来,上位机就会接收到数据,并根据其中的年、月、日、小时、分钟、ID号、类型来讲数据存储到“D:RCVDATA”下对应的路径中。每当接收到数据,就会在主界面中的“当前接收到数据”群组中显示最近一次接收到的数据的ID号、姓名、数据类型、数据值。
在主界面中的“数据折线图”群组中可以根据选择“选择显示项目”和“选择显示姓名”来确定显示折线图的内容。当选定之后,折线图中将会显示选中的姓名和项目最近收到的12组数据。如果最近收到的数据不足12组,将会显示默认数据0(显示的为体温时默认为33℃)。
在数据的接收过程中,如果关闭了端口,将会停止数据的接收。
4.2 查看历史数据
4.3 固件升级
在本系统中,我采用的升级模式为上位机主动升级模式。
当我们决定对下位机进行固件升级的时候,首先点击用户——发送升级请求,此时上位机会给下位机发送升级请求命令,下位机接收到该升级命令之后,会做出相应的准备,并发送准备完毕命令到上位机。上位机接收到该命令之后,会弹出对话框通知下位机已经准备好了,对话框如下图所示。
下位机升级准备完毕对话框
升级结束消息框
此时我们就可以向下位机发送固件文件了,具体操作为:点击用户——升级用户固件,将会弹出图示所示界面,点击“升级”按钮,将会对其进行升级操作,进度条将会显示固件发送进度如图所示。当升级结束之后,将会弹出消息框显示固件发送结束。
至此上位机的操作将完成,下位机在接收到固件文件之后,需要进行关机操作,将PB.7引脚连接到GND,然后开机,就会进行固件的升级操作,固件写入Flash之后,将会在新的固件系统下运行。
4.4系统联调的必要
4.5 GPRS模块的配置
4.6 RTC中断无法产生
在调试过程中,最初的方案是通过PCF8563内部的定时器产生定时中断,并输出到中断引脚,将该中断引脚连接到单片机的外部中断输入引脚。当中断产生的时,引脚产生的低电平脉冲会触发单片机中断,然后将接收到的数据发送到服务器。
4.7 接收固件时数据容易丢失
在进行固件更新的过程中需要发送的文件有120kByte,虽然该文件的大小对于平常来说是很小的,但是这里我们采用的传输方式是:串口——无线网络——串口。而且接收的时候单片机串口的缓冲区FIFO只有14Byte,当接收到的数据达到14个字节的时候,就会触发单片机产生串口数据可用中断,此时将会执行中断函数把FIFO中的14个字符读取出来,以及其他一些操作,如果在执行这些操作的过程中,FIFO又接收到另外14个字节,将会再次触发中断,导致之前的14个字节数据的处理还没有完成的情况下再次执行中断函数。而固件文件相当于是一个计算机的操作系统,即使有一个bit位产生错误,都会造成不可估量的后果。
解决办法:因为考虑到固件文件的重要性,这里综合了几个方案同时实施,保证固件信息接收的完整。第一,在单片机中开辟双缓冲结构,当触发中断之后,马上将FIFO中的14个字节存储到开辟的缓冲区中,中断中不作任何多余的事情,当该缓冲区存储满了之后,立刻将存储位置改到另一个缓冲区中,并将之前的缓冲区中的数据保存到U盘中,这样保证了在中断函数中有尽量少的代码,不会在处理中断函数的过程中再次触发中断。第二,在之前备份数据时采用的是字节方式来读写U盘,因为数据量比较少,只有35个字节,操作也比较方便、直观。在这里我们改用扇区的方式来读写U盘,可以大大加快读写的速度。防止缓冲区溢出造成数据丢失。第三,因为单片机的串口中断的数据可用中断是FIFO中的14个字节充满了就会触发,那么上位机在发送的时候刻意每发送14个字节就延时一段时间,给予下位机足够的时间来处理中断函数。
优缺点:开辟双缓冲需要大量的单片机RAM硬件资源,因此不能完全靠增大双缓冲来解决问题;至于每发送14字节给予一定的延时,因为服务器和下位机之间不是直接连接,北京天同诚业公司内部数据服务器有3M的FIFO,这就意味着,当我从服务器发送数据到下位机,当数据到达FIFO中时,如果网络状况不佳,造成数据暂存,那么这个数据就会和后面发来的数据在网络良好的时候一起发到下位机,这样会造成延时消失。在实际开发的上位机中,我给予的延时比较长,因此进行一次固件升级需要3—6分钟,具体根据PC机的主频而定。而且在实际调试过程中仍有一定比率的接收固件出错。
下图是下位机系统的整体硬件。其中GPRS模块采用DC-5V供电,单片机和TFT显示采用PC端的USB供电。 /[hide]
下位机硬件系统(有点丑,凑活看)