本帖最后由 946098169 于 2014-9-15 11:45 编辑
毕业论文和大家共享,欢迎各位提出指导意见,共同进步!因字数限制精简了好多内容,只介绍了大体思路:lol 1.1绪论 本设计是一个软硬件结合的设计,以CH563单片机为控制中心控制整个下位机系统,实现将医疗数据接收,远程传送到服务器,从而实现对消费者医疗信息的监控。本设计的主要功能如下:数据的采集、离线数据的存储、 TFT屏显示、 GPRS远程数据传送、固件的升级。 以MCU为主控制器,接收来自传感器的数据,获取RTC芯片的时间信息,并将它们在TFT显示屏上显示出来,当收到上传数据命令的时候,将最新的数据通过GPRS模块传送到服务器。如果发送没有成功,则将数据保存到U盘中,这些保存的数据将会在后面的传输数据成功时再进行发送。系统的结构很清晰,主要难点是操作U盘和固件升级,以及如何对中断进行合理地嵌套处理。 本设计的上位机部分采用C#进行编写,主要用到C#编程语言中的下面几个功能,分别是:Excel文件的读写控制、SerialPort的编程。其中SerialPort的功能是从COM口读取数据,Excel文件读取是用来将接收到的数据存储到Excel文件中。 1.2设计思路 由于该远程医疗系统需要通过串口控制GPRS模块和接收传感器的信息,因此选择的单片机至少应该有2个串口,另外做即时显示的时候选用的是240*320分辨率的TFT显示屏,因此单片机需要较快的主频。最重要的一点是需要操作U盘,单片机一定要拥有USB接口。初步选择为ARM内核的单片机。 经过网上查询MCU资料,当前ARM内核的MCU价格普遍比较高,主流的Cortex-M3内核单片机公司,如:ST、Philip、Ti等,它们的单片机性能较好,但是价格相比较高,并且有USB接口的单片机价格很贵。相比之下南京沁恒的CH563L单片机拥有很高的性价比,其价格低于市场上相同配置的芯片,主频最高可以达到130MHz,主要硬件接口为:1个USB2.0高速主从接口,1个内置PHY的100M网络接口,2个串口,2个SPI接口,1个8位被动并口,74个通用IO口等。完全可以满足我的设计要求,并且可以降低设计的成本,因此选择CH563作为下位机的主控芯片。 1.3 硬件系统框图 经过上面分析可知,整个硬件系统由一个CH563单片机控制,硬件系统框图如下图所示。
硬件系统框图
1.4系统结构分析 CH563作为主控制器,其主要作用是医疗信息的U盘存储、驱动GPRS模块和服务器进行通信、接收数据接口传来的数据、驱动TFT显示屏来进行下位机显示,当进行升级操作的时候,将固件文件存储到U盘中,从而对MCU中的固件进行升级。 U盘主要有两个功能,第一个是在服务器断电的情况下进行数据的暂存,从而在后续的过程中将之前的数据发送到服务器上;第二个功能是在系统选择升级固件的时候,先将固件文件存储在里面,然后CH563升级自身的固件,从而使得系统工作在最新的固件版本下。串口数据接口是预留的一个USART接口,用来和传感器接口相连接。GPRS是该系统中的通信模块,主要用来和服务器进行通信,在使用的过程中需要插入SIM卡,并会消耗一定的数据流量。(如果不用无线GPRS也可使用CH563的以太网接口和服务器相连,但这样需要网线连接) PCF8563为系统提示时间,并每2分钟在中断引脚INT(低电平有效)产生一次中断,CH563一旦接收到中断,就会进行一次将数据传送到服务器的操作。 当有数据从数据接口传输过来的时候,CH563首先将其在显示屏上显示出来,并将此时的数据在缓存中存储起来,后面如果有新的数据过来,则先显示,再更新到缓存中;当PCF8563产生中断的时候,CH563会将缓存中最新的数据结合此时的时间以及用户设备的识别号码发送到服务器,并开始等待服务器应答,如果接收到应答,表明发送成功;如果超时等待时间没有收到应答,表明发送失败,此时将会把这次发送失败的数据存储到U盘中,在下次可以发送成功的时候,再进行发送。 1.5 MCU和各接口电路的设计 MCU(CH563L)的封装为LQFP128,总共有128个引脚,在实际使用的时候用到的引脚比较少,实际电路中CH563L的接口电路如下图所示。
XI、XO是晶振输入和输出引脚,只要使用该单片机,就必须连接。 串口0的输入输出引脚为第109(PB8/RXD0)和110(PB9/TXD0),这两个引脚是用来和GPRS模块的串口输出出入相连接的。 串口1的输入引脚为第111(PB10/RXD1/RXTX1),这个引脚用来和传感器接口的发送引脚进行相连,因为此处的数据传送方向为单向的,所以不需要使用串口1的发送引脚。 CH563没有硬件IIC接口,因此需要用普通IO口模拟IIC接口,本系统中采用第117引脚(PD0)和第118引脚(PD1)模拟IIC接口分别和PCF8563的SCL和SDA引脚相连接。 CH563的USB接口为第23引脚(DN)和第24引脚(DP),在电路中分别和USB插座的DN和DP引脚相连接。 CH563的第83—90引脚为PA0—PA7,在这里和TFT显示屏的并行数据接口DB0—DB7相连接。CH563的第96引脚(PA8)和TFT显示屏控制引脚的RW引脚进行连接,CH563的第97引脚(PA9)和TFT显示屏控制引脚的RS引脚进行连接,CH563的第98引脚(PA10)和TFT显示屏控制引脚的CS引脚进行连接,CH563的第99引脚(PA11)和TFT显示屏控制引脚的RST引脚进行连接。
1.6系统软件完成启动之后 系统完成了上面所说的初始化之后,开始正式进入到工作的状态,开始进行判断是否有一下三种请求,分别是“是否有接收数据中断请求”、“是否有数据上传请求”、“ 是否有固件升级请求”。 首先判断系统是否收到“数据接口端传送过来的数据”请求,如果有,则将传输过来的数据在显示屏上特定的位置显示出来,以实现即时显示的功能;如果没有收到,那么判断是否收到存储数据的请求。显示屏上的五个医疗监控项目如果没有收到新的数据,会显示“无”字样。 如果收到“上传数据请求”,首先会判断五个项目是否有新的数据,如果开机之后,某个项目一直没有收到数据,那么系统就直接跳过该过程。如果某项有新的数据,那么就会将该项目的数据进行上传,上传的过程是首先根据接收到的数据结合时间、ID号、项目类型生成一个固定格式的字符串,然后通过GPRS模块发送该字符串,发送后开启定时器,开始进行10秒钟的等待。这10秒的作用是用来给上位机发送接收应答,因为存在网络的延时,所以延时时间用的比较长,10秒钟之后,单片机会检测与GPRS相连接的串口是否收到了接收成功应答。如果接收到了,表示这次发送成功,此时将会检测U盘中是否有之前没有发送成功的数据保存在里面,如果有,将会读取该信息,并进行发送。当U盘中的数据发送结束或者U盘中没有存储的数据的时候,将会进行其他项目数据的发送。如果发送数据没有成功,则将生成的字符串保存到U盘中固定名称的文件中,并开始进行下一个项目的发送。 当接收到“固件升级请求”时,系统首先在U盘中的固定路径中创建一个名称为AP_ROM.HEX的文件然后关闭除了GPRS模块对应的串口中断之外所有的中断,并开始进行固件的接收。在接收的过程中不响应其他所有的中断,也不会更新接收到的数据,当接收完毕之后,会显示“结束”字样,此时用户应该手动将PB.7引脚接到GND上,然后重新开启系统,系统在再次开机的时候就会检测U盘中是否有固件,如果有,就会进行固件的更新。 1.7 USB驱动程序的设计 CH563的USB程序是沁恒提供的库文件,无法读取到源程序,有开放的函数名供调用,使用很方便,所有的函数名见下表。 函数名 |
函数功能
|
UINT8 CH563GetVer( void )
|
获取当前子程序库的版本号
|
void CH563DirtyBuffer( void )
|
清除磁盘缓冲区
|
UINT8 CH563DiskConnect( void )
|
检查磁盘是否连接并更新磁盘状态
|
UINT8 CH563BulkOnlyCmd( void )
|
执行基于BulkOnly协议的命令
|
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
1.8固件的升级 该系统中固件的升级采用的是上位机主动控制下位机升级固件系统,在升级的时候,首先会向下位机发送一个升级开始操作符“UPGRADE_FIRM”,当下位机接收到这个字符串的时候,将会知道接下来串口接收到的数据是固件文件,此时它会关闭除了连接GPRS模块对应的串口的中断外的所有中断,并在U盘中的\CH563\目录下创建空固件文件AP_ROM.HEX,然后返还给服务器准备就绪信息字符串“CH563_REQUIRE_NEW_FIRMWAREXXXXXXXXX”,当上位机接收到该字符串之后,意味着此时可以进行发送固件文件了。通过点击对应的按钮开始发送固件文件。 固件发送的是hex文件,实例化一个StreamReader类型,通过运行代码SteamReader.Read()代码逐字符的读取文件中的数据。因为考虑到下位机的串口中断FIFO是14个字节,因此在实际发送的过程中,每发送14个字节,会进行短时间的延时,来给下位机足够的时间来处理中断,防止因为中断执行时被中断而造成数据没来得及存储而丢失。
1.9固件升级 在本系统中,我采用的升级模式为上位机主动升级模式。 当我们决定对下位机进行固件升级的时候,首先点击用户——发送升级请求,此时上位机会给下位机发送升级请求命令,下位机接收到该升级命令之后,会做出相应的准备,并发送准备完毕命令到上位机。上位机接收到该命令之后,会弹出对话框通知下位机已经准备好了,对话框如下图所示。
下位机升级准备完毕对话框
升级结束消息框 此时我们就可以向下位机发送固件文件了,具体操作为:点击用户——升级用户固件,将会弹出图示所示界面,点击“升级”按钮,将会对其进行升级操作,进度条将会显示固件发送进度如图所示。当升级结束之后,将会弹出消息框显示固件发送结束。至此上位机的操作将完成,下位机在接收到固件文件之后,需要进行关机操作,将PB.7引脚连接到GND,然后开机,就会进行固件的升级操作,固件写入Flash之后,将会在新的固件系统下运行。 下图是下位机系统的整体硬件。其中GPRS模块采用DC-5V供电,单片机和TFT显示采用PC端的USB供电。
下位机硬件系统(有点丑,凑活看)
下位机TFT显示屏
上位机接收数据时界面
|