初始条件:计算机、Max+plusⅡ、EDA实验箱。
摘要
本设计的呼叫系统由按键检测,数据处理,信息显示三部分组成。由C51单片机作为主要控制器,利用液晶显示器作为显示部分,使用3X8矩阵开关分别模拟医院病房与病床位数。病人按下按键时,C51立即获取病人的病房号和病床号,同时采集此时的时间并一起显示在液晶显示器上,当护士看到显示器上病人的信息,并按下清零键后,液晶显示器恢复到初始状态。本系统对键盘的检测采用中断的方式,能够提高系统的立即性和高效性。当同时有数个病床呼叫时,本系统还可以循环呼叫记录显示。
关键词:病房呼叫 单片机 中断 液晶显示
1设计任务及要求分析
近年来,随着人们生活水平的不断提高,人们对医疗水平的要求也不断提高,特别是突发情况下病人请求值班医生或护士进行及时诊断或护理,这一环节对提高医院的管理服务质量显得尤其重要,这同时也大大提高了医院医护人员应对突发事件的能力。因此,一种新型临床呼叫仪器的研制成为近些年来的研究热点之一。呼叫系统的优劣直接关系到病员的安危,历来受到各大医院的普遍重视。它要求及时、准确、可靠、简便可行、利于推广。利用电力线载波通信技术、单片机多机通信和计算机监控管理技术设计的具有呼叫、振铃、显示排队、优先权设定、存储记录等功能的病床呼叫系统,满足了医院的病房管理和护理要求。
1.1设计任务
本病床呼叫系统中,使用3X8矩阵开关分别模拟医院病房与病床位数,当某开关按下时,系统显示呼叫的病房与病床、呼叫的时间。处理完毕可清除该呼叫显示记录。当同时有数个病床呼叫时,本系统还可以循环呼叫记录显示。
1.2 任务要求分析
通过对上述设计任务的分析,可以将之细分为以下几点,最后的调试也将以下面各点为依据。
①当有病人按下按键时,液晶显示器上显示病人的病房号,病床号,以及按键时的时间。
②在护士按下清零键后,液晶显示器上内容恢复到初始状态。
③若在护士按下清零键前有多个病人按键,则液晶显示器上将循环显示各个病人的信息,直到护士按下清零键后,液晶显示器上内容恢复到初始状态。
2系统设计和方案选择
2.1设计思路
根据设计要求,该病床呼叫系统利用C51单片机作为核心,外接3X8矩阵键盘,每一个键对应着不同的床位。在没有病人呼叫时,单片机循环等待按键按下;当病人按下床头对应的按键,产生中断信号。单片机收到中断信号后调用中断服务程序识别出呼叫病床的病房号码和床位号码,同时记录当时系统的时间,将呼叫记录通过LCD12864显示出来,护士通过读取屏幕上提示的呼叫信息即可快速的、正确的查出病人的床位,并做相应的准备以及时处理,处理完成后,按下清除按钮,即可清除本次呼叫记录,等待下次呼叫,同时液晶屏幕上再次显示“一切正常”。其结构图如下:
图2.1 病床呼叫系统结构图
2.2键盘采集方案选择
键盘的工作方式应该根据实际应用系统中CPU的工作状况而定其选取的原则是既要保证CPU能及时响应按键操作又不要过多占用CPU的工作时间。通常键盘的工作方式有三种即编程扫描、定时扫描和中断扫描。
1编程扫描方式
编程扫描方式是利用CPU完成其他工作的空余时间调用键盘扫描子程序来检验按键态响应键盘输入。执行键功能程序时CPU不再享有键输入要求直到CPU重新扫描键盘为止。
2定时扫描方式
定时扫描方式就是每隔一段时间对键盘扫描一次她利用单片机内部的定时器产生一定时间如20ms的定时定时时间到产生定时器溢出中断。CPU在中断服务程序中键盘进行扫描并在有键按下时识别出该键并保存键号然后在中断服务程序或主程序中执行该键的功能程序。
3中断扫描方式
中断扫描方式就是当按键有按下时,产生中断信号,CPU收到中断信号后就执行相应的中断服务子程序响应该按键,处理完后CPU又开始循环等待下一次按键按下。
当采用前两种键盘描方式时,无论是否有键按下CPU都要定时扫描键盘而单片机应用系统工作时并非经常需要键盘输入。因此CPU经常处于空扫描状态,浪费CPU大量时间。CPU不扫描键盘而有键按下时通过相应电路产生中断请求,CPU响应中断,执行键盘扫描子程序并识别键号。
所以本设计中采用中断扫描方式采集键盘信息。
2.3 设计芯片的选择
C51单片机:
单片机是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的CPU、RAM、ROM、多路I/O口和中断系统、定时器/计数器等功能集成到一块芯片上的一个小系统,通过编写程序下载到单片机的程序存储器以实现不同的功能。
液晶显示器LCD12864:
相对于数码管、LED二极管点阵等,液晶显示具有可以实现汉字的显示,硬件电路连接比较简单等优点。
3病床呼叫系统硬件电路设计
3.1单片机控制系统硬件设计
单片机控制系统功能是:键盘数据采集并保留采集结果、控制液晶显示设计要求的内容、读取实时时间,并作适当的数据处理
该控制系统中单片机AT89C51的P0,P1,P2及P3.0,P3.1接口作普通I/O使用,其中P0口作为LCD12864的数据传输口,P2.0~P2.5口的作为其控制端口,P2.6、P2.7、P3.0以及P1口为键盘的行列口,P3.0作为清除按键的数据输入口。P3.2作为外部中断信号输入口。P3部分口与时钟芯片DS1302相连实现时间的通信。具体电路图显示如图3.1所示。
图3.1 单片机控制系统电路图
3.2 液晶显示的硬件设计
液晶显示的功能包括:没有病人呼叫时,显示“一切正常”;当有病人呼叫时,显示病人的具体位置和呼叫的时间、日期。
通用型LCD12864共有18个引脚,其中DB7~DB0是连接控制器的数据总线,其他的引脚中6根控制线,另外还有电源线,具体连接见图3.2。
其中上拉电阻是由于P0口作普通口时内部没有上拉电阻。
图3.2液晶LCD12864电路图
3.3扫描键盘的硬件设计
键盘输入的功能:每个按键对应着一张病床,由3X8矩阵键盘组成。
该矩阵键盘的总共需要11个接口,其中列分别与单片机P2.6、P2.7、P3.0口相接,行占用了整个P1口。具体连接如图3.3所示。
图3.3 3X8矩阵键盘
3.4时钟芯片的硬件设计
时钟芯片DS1302有两个电源引脚,VCC1和VCC2,其中VCC1是主电源,VCC2是备份电源。当VCC2>VCC1+0.2V时,由VCC2向DS1302供电,当VCC2<VCC1时,由VCC1向DS1302供电,以防止系统掉电时芯片内部的数据不会丢失。其通信引脚有3个,另外外接32.768KHz晶振是为芯片提供计时脉冲。其连接电路图如图3.4所示。
图3.4 时钟芯片电路图
3.4中断电路设计
若系统初始化时将L1,L2,L3设置为高电平,P0口设置为低电平,则当有按键按下时,L1,L2,L3会有一个变为低电平。同样当按下清除键时,CLEAR也会为低电平。这样通过一个4输入与门连接到P3.2上即可实现对键盘的中断检测。其连接电路图如图3.5所示。
图3.5 中断电路图
4病房呼叫系统软件设计
对于一个完整的设计,除了需要设计硬件电路外,还需要根据功能需求设计要求设计一个运行高效、冗余指令少、稳定性强的软件系统。在这一块的完成上,我们采用的主要是各个子程序设计,主函数只需要做简单的数据处理和各个子程序的调用,从而逐步完成题目的全部要求。
4.1主程序设计
主程序主要是对各子程序,中断服务子程序进行初始化,并循环显示病人信息。其流程图如图4.1所示。
图4.1主程序流程图
主程序设计见附录:
void main()
{
.....
}
4.2矩阵键盘的中断程序的设计
矩阵键盘的中断程序主要是对按键的扫描以实现对按键的键号识别,同时对键号对应的病房,病床号以及按键的时间进行存储。主函数通过调用存储的数据便可实现病房信息的循环显示。
其设计流程图如图4.2所示。
需要说明的是,在此中断程序中抖动的识别可以通过延时一段时间后再对L1,L2,L3及CLEAR的高低电平进行判断来实现,若延时后仍然有低电平则不是抖动而是真的有按键按下。
矩阵键盘的中断程序设计如下:
void int0( ) interrupt 0 using 0
{
.......
}
图4.2矩阵键盘的中断程序流程图
4.3液晶LCD12864驱动程序的设计
编写液晶LCD12864驱动程序前首先要对系统中用到的汉字,数字以及特殊字符的数据组进行设计。针对液晶驱动程序主要考虑以下的编写:
1、void read_busy() 读忙函数
2、void write_LCD_command(uchar value) 写指令函数
3、void write_LCD_data(uchar value) 写数据函数
4、void set_page(uchar page) 设置页
5、void set_line(uchar startline) 设置起始行
6、void set_column(uchar column) 设置起始列
7、void setonoff(uchar onoff) 开、关显示(0开,1关)
8、void selectscreen(uchar screen) 选屏函数(00全屏01左半屏10右半屏)
9、void clearscreen(uchar screen) 清屏函数
10、void init_LCD() 初始化函数
11、void display(uchar ss,uchar page,uchar column,uchar p) 显示汉字函数
12、void display1(uchar ss,uchar page,uchar column,uchar p) 显示字符
上述函数的具体编写参看附录2。
4.4实时时钟DS1302驱动程序的设计
由于DS1302是SPI总线驱动方式,它不仅要向寄存器写入控制字,还需要读取相应的寄存器数据,所以要想与其通信,首先得了解DS1302控制字,而且SPI总线进行数据通行时只有两条数据线,即SCLK和RST,通过不同时刻两条总线的电瓶变化不同可以进行不同的操作。
其驱动函数包括:
1、void write_byte1302(uchar dat) 写一个字节
2、uchar read_byte1302() 读一个字节
3、void write_1302(uchar add,uchar dat)写数据
4、uchar read_1302(uchar add) 读数据
5、void init1302() 初始化
上述函数的具体编写参看附录2。
5仿真结果及分析
在protues和单片机编译软件keil C51中分别完成硬件电路设计和软件系统的设计后,生成HEX文件载入单片机中开始逐步调试程序,经过多次调试,系统能够正常的运行,并能够正确的在液晶屏上显示呼叫病床的病房号和床位号以及系统当时的时间与日期。
5.1无病人呼救时的仿真结果
点击“运行”按钮,系统开始运行,并在液晶屏上显示“一切正常”表示没有病人求救,如图4.1所示。
图5.1没有呼叫时液晶显示结果
5.2有病人呼救时的仿真结果
当某一房间的病人按下求救按钮(如按下2-3键)时液晶屏提示值班人员的显示,如图4.2,左边是DS1302内部系统时间,通过对比可以看出显示时间是定在按键时间的。
图5.2 2号房间第5床的病人求救
当按下“清除”键后,在没有病人求救的情况下,液晶屏幕会再次出现“一切正常”。与运行开始时的结果是一致的。
5.3有多个病人呼救时的仿真结果
当有多个病人同时按键时,液晶显示屏上以一定的时间间隔循环显示各个病人的病房,病床信息以及按键时间。其仿真结果见图5.3,图5.4(这里假设只有两个病人同时按键)。
图5.3 2号房间第2床位的病人求救
图5.4 3号房间第3床位的病人求救
当按下“清除”键后,在没有病人求救的情况下,液晶屏幕会再次出现“一切正常”。与运行开始时的结果是一致的。
6心得体会
本设计是以AT89C51为核心的病人呼叫系统,对该系统的硬件和软件结构进行了相应的描述。通过对病区的数据采集实现医院医疗人员值班室和病人房之间的通信联系具有使用方便、操作简单等特点。此次设计为有线呼叫系统虽存在布线复杂、维修不便、病房不能与值班室的语音对话等缺陷。但相对于无线呼叫系统而言它的可靠性能高而且不干扰其他医疗设备。如果采用无线传输会节约布线和改造线路的资金为医院节约成本并且及时、简便可行比目前的同类产品更能受到医院及病人的认可有更强的竞争力能大量推广。
在系统设计期间,尤其是程序的调试间段出现很多次差错,主要包括LCD12864显示和DS1302部分子程序的错误,这主要是由于自己对LCD12864的显示原理和对DS1302的子函数返回值不熟悉所导致。在设计多病人呼叫循环显示时,我也遇到了许多难题。为了将病人的键号和按键时间及时存储下来,我在主程序外定义了两个无符号整型的数组,并按24个病人的长度进行定义,结果导致数据段内存不够,不能编译。后来将数组改能无符号字符型,并将长度降为10,这样已经可以满足实际需要。修改后程序才能顺利编译运行。
通过本次设计不仅让我对医院病床呼叫系统有了进一步的了解,也在熟悉芯片的同时,加强了我在编程方面的技巧。另外,在这次的设计过程中,我不断地查阅资料并请将同学,这让我的自学能力也有了很大的提高。
参考文献
[1]李群芳.单片微型计算机与接口技术[M].第3版.北京:电子工业出版社,2008
[2]窦振中.基于单片机的嵌入式系统式工程设计[M].北京:中国电力出版社,2008
[3]冯建华。单片机应用系统设计与产品开发[M],北京:人民邮电出版社,2004
[4]谭浩强.C程序设计(第三版)[M].清华大学出版社,2008
[5]王巧芝,郑锋,刘瑞国,高学辉.51单片机开发应用从入门到精通[M].中国铁道出版社,2011
附录1系统原理图
附录2程序源代码:
#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define LCD_databus P0
uchar room_num,bed_num,n,y,r,s,f,m,t=0;
uchar num[10][2],time[10][6];
uchar code table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar keyscan();
sbit RS=P2^4; //RS为0命令,为1数据
sbit RW=P2^5; //RW为1写,为0读
sbit EN=P2^2; //使能端
sbit CS1=P2^0; //片选1低电平有效,控制左半屏
sbit CS2=P2^1; //片选2低电平有效,控制右半屏
sbit L1=P2^6;
sbit L2=P2^7;
sbit L3=P3^0;
sbit IO=P3^7;
sbit SCLK=P3^6;
sbit RST=P3^5;
sbit CLEAR=P3^1;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
uchar code ZK[]={
/*-- 文字: 病 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x10,0x60,0x00,0xFC,0x04,0x24,0x24,0x24,0x25,0xE6,0x24,0x24,0x24,0x24,0x04,0x00,
0x84,0x42,0x31,0x0F,0x00,0xFF,0x11,0x09,0x05,0x03,0x05,0x59,0x81,0x7F,0x00,0x00,
/*-- 文字: 床 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0xFC,0x04,0x44,0x44,0x44,0x45,0xF6,0x44,0x44,0x44,0x44,0x44,0x04,0x00,
0x40,0x30,0x0F,0x20,0x10,0x08,0x06,0x01,0xFF,0x01,0x06,0x08,0x10,0x20,0x20,0x00,
/*-- 文字: 房 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0xFC,0x24,0x24,0x24,0x25,0x66,0xA4,0x24,0x24,0x24,0x24,0x3C,0x00,0x00,
0x40,0x30,0x0F,0x81,0x41,0x31,0x0F,0x09,0x09,0x09,0x49,0x89,0x79,0x01,0x00,0x00,
/*-- 文字: 时 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0xFC,0x84,0x84,0x84,0xFC,0x00,0x10,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x00,
0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,0x01,0x06,0x40,0x80,0x7F,0x00,0x00,0x00,
/*-- 文字: 间 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0xF8,0x01,0x06,0x00,0xF0,0x12,0x12,0x12,0xF2,0x02,0x02,0x02,0xFE,0x00,0x00,
0x00,0xFF,0x00,0x00,0x00,0x1F,0x11,0x11,0x11,0x1F,0x00,0x40,0x80,0x7F,0x00,0x00,
/*-- 文字: 日 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x00,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xFF,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xFF,0x00,0x00,0x00,0x00,
/*-- 文字: 期 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x04,0xFF,0x24,0x24,0x24,0xFF,0x04,0x00,0xFE,0x22,0x22,0x22,0xFE,0x00,0x00,
0x88,0x48,0x2F,0x09,0x09,0x19,0xAF,0x48,0x30,0x0F,0x02,0x42,0x82,0x7F,0x00,0x00,
/*-- 文字: 号 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x80,0x80,0x80,0xBE,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xA2,0xBE,0x80,0x80,0x80,0x00,
0x00,0x00,0x00,0x06,0x05,0x04,0x04,0x04,0x44,0x84,0x44,0x3C,0x00,0x00,0x00,0x00,
/*-- 文字: 一 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*-- 文字: 切 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x40,0x40,0x40,0xFF,0x20,0x20,0x20,0x04,0x04,0xFC,0x04,0x04,0x04,0xFC,0x00,0x00,
0x00,0x00,0x00,0x1F,0x08,0x84,0x42,0x20,0x18,0x07,0x40,0x80,0x40,0x3F,0x00,0x00,
/*-- 文字: 正 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x00,0x02,0x02,0xC2,0x02,0x02,0x02,0xFE,0x82,0x82,0x82,0x82,0x82,0x02,0x00,0x00,
0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,
/*-- 文字: 常 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
0x20,0x18,0x08,0xEA,0xAC,0xA8,0xA8,0xAF,0xA8,0xA8,0xAC,0xEA,0x08,0x28,0x18,0x00,
0x00,0x00,0x3E,0x02,0x02,0x02,0x02,0xFF,0x02,0x02,0x12,0x22,0x1E,0x00,0x00,0x00,
};
uchar code SK[]={
/*-- 文字: 0 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,
/*-- 文字: 1 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
/*-- 文字: 2 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,
/*-- 文字: 3 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,
/*-- 文字: 4 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,
/*-- 文字: 5 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,
/*-- 文字: 6 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,
/*-- 文字: 7 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,
/*-- 文字: 8 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,
/*-- 文字: 9 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
经过查找分析,发现键盘扫描程序没有没有按键消抖部分,按键在按下与松手时,都会有一定程度的抖动,从而可能使单片机做出错误的判断,导致按键条件预设温度时失灵,甚至根本不能正常工作。因此必须在按键扫描程序中加入消抖部分,即在按键按下与松手时加入延时判断,以检测键盘是否真的按下或已完全松手。
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,
/*-- 文字: : --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,
/*-- 时间号: : --*/
/*-- 宋体12;此符号下对应的点阵为: 宽x高=8x16 --*/
0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x00,
/*-- 文字: - --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
};
void delay(uint i)
{
uint x,y;
for(x=i;x>0;x--)
for(y=110;y>0;y--);
}
void read_busy() //读忙函数,数据线最高位为DB7为1则busy
{
P0=0x00;RS=0;RW=1;EN=1;
while(P0&0x80);EN=0;
}
void write_LCD_command(uchar value)
{
read_busy();
RS=0;RW=0;
LCD_databus=value;
EN=1;
_nop_();
_nop_();
EN=0;
}
void write_LCD_data(uchar value)
{
read_busy();
RS=1;RW=0;
LCD_databus=value;
EN=1;
_nop_();
_nop_();
EN=0;
}
void set_page(uchar page)
{
page=page|0xb8;
write_LCD_command(page);
}
void set_line(uchar startline)
{
startline=0xc0|startline;
write_LCD_command(startline);
}
void set_column(uchar column)
{
column=column&0x3f;
column=0x40|column;
write_LCD_command(column);
}
void setonoff(uchar onoff)
{
onoff=0x3e|onoff;
write_LCD_command(onoff);
}
void selectscreen(uchar screen)
{
switch(screen)
{
case 0: CS1=0;CS2=0;break;
case 1:CS1=0;CS2=1; break;
case 2:CS1=1;CS2=0;break;
default:break;
}
}
void clearscreen(uchar screen)
{
uchar i,j;
selectscreen(screen);
for(i=0;i<8;i++)
{
set_page(i);
set_column(0);
for(j=0;j<64;j++)
{
write_LCD_data(0x00);
}
}
}
void init_LCD()
{
read_busy();
selectscreen(0);
setonoff(0);
selectscreen(0);
setonoff(1);
selectscreen(0);
clearscreen(0);
set_line(0);
}
void display(uchar ss,uchar page,uchar column,uchar p)
{
uint i;
selectscreen(ss);
set_page(page);
set_column(column);
for(i=0;i<16;i++)
{
write_LCD_data(ZK[i+p*32]);
}
set_page(page+1);
set_column(column);
for(i=0;i<16;i++)
{
write_LCD_data(ZK[i+16+p*32]);
}
}
void display1(uchar ss,uchar page,uchar column,uchar p)
{
uint i;
selectscreen(ss);
set_page(page);
set_column(column);
for(i=0;i<8;i++)
{
write_LCD_data(SK[i+p*16]);
}
set_page(page+1);
set_column(column);
for(i=0;i<8;i++)
{
write_LCD_data(SK[i+8+p*16]);
}
}
void write_byte1302(uchar dat)
{
uchar kk;
ACC=dat;
RST=1;
for(kk=8;kk>0;kk--)
{
IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>>1;
}
}
uchar read_byte1302()
{
uchar kk;
RST=1;
for(kk=8;kk>0;kk--)
{
ACC7=IO;
SCLK=1;
SCLK=0;
ACC=ACC>>1;
}
return ACC;
}
void write_1302(uchar add,uchar dat)
{
RST=0;SCLK=0;RST=1;
write_byte1302(add);
write_byte1302(dat);
SCLK=1;RST=0;
}
uchar read_1302(uchar add)
{
uchar temp;
RST=0;SCLK=0;RST=1;
write_byte1302(add);
temp=read_byte1302();
SCLK=1;RST=0;
return(temp/16*10+temp%16); //返回十进制数据显示
}
void init1302()
{
RST=0;
SCLK=0;
write_1302(0x80,0x00);
}
void key_display(uchar aa)
{
m=time[aa][0];
f=time[aa][1];
s=time[aa][2];
r=time[aa][3];
y=time[aa][4];
n=time[aa][5];
RST=0;
clearscreen(0);
display(1,0,0*16,0); //病
display(1,0,1*16,2); //房
display1(1,0,2*16,11); // 冒号
display1(2,0,0*16,num[aa][0]); //房号 数
display(2,0,1*16,7); //号
display(1,2,0*16,0); //病
display(1,2,1*16,1); //床
display1(1,2,2*16,11); //冒号
display1(2,2,0*16,num[aa][1]); //床号数
display(2,2,1*16,7); //号
display(1,4,0*16,3); //时
display(1,4,1*16,4); //间
display1(1,4,2*16,11); //冒号
display1(2,4,24,10);
display1(2,4,0,10); //时间符
display1(2,4,32,m/10);
display1(2,4,40,m%10);
display1(2,4,16,f%10);
display1(2,4,8,f/10);
display1(1,4,48,s/10);
display1(1,4,56,s%10); //时分秒的显示
display(1,6,0*16,5);
display(1,6,1*16,6);
display1(1,6,2*16,11);
display1(1,6,40,2);
display1(1,6,48,0);
display1(1,6,56,n/10);
display1(2,6,0,n%10);
display1(2,6,16,y/10);
display1(2,6,24,y%10);
display1(2,6,40,r/10);
display1(2,6,48,r%10);
display1(2,6,32,12);
display1(2,6,8,12);
}
void clear_display()
{
t=0;
clearscreen(0);
display(1,2,2*16,8);
display(1,2,3*16,9);
display(2,2,0*16,10);
display(2,2,1*16,11);
}
void main()
{
uchar i;
init_LCD();
init1302();
set_line(0);
clear_display();
EA=1;
EX0=1;
INT0=1;
P1=0x00;
L1=L2=L3=1;
while(1)
for(i=0;i<t;i++)
{
key_display(i);
delay(1000);
}
}
void int0( ) interrupt 0 using 0
{
uchar i;
EX0=0;
delay(5);
if((L1&L2&L3&CLEAR)!=1)
{
if(L1==0)
room_num=1;
else if(L2==0)
room_num=2;
else
room_num=3;
P1=0xff;
L1=L2=L3=0;
for(i=0;i<8;i++)
if(P1==table[i])
{
bed_num=i+1;
break;
}
num[t][0]=room_num;
num[t][1]=bed_num;
time[t][0]=read_1302(0x81);
time[t][1]=read_1302(0x83);
time[t][2]=read_1302(0x85);
time[t][3]=read_1302(0x87);
time[t][4]=read_1302(0x89);
time[t][5]=read_1302(0x8d);
t++;
P1=0x00;
L1=L2=L3=1;
if(CLEAR==0)
clear_display();
}
EX0=1;
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
关注我们"单片机", 回复"课程设计"获取更多文档
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >
单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板单片机开发板