#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit cs1=P2^4;
sbit cs2=P2^3;
sbit rs=P2^2;//LCD12864命令、数据选择引脚
sbit rw=P2^1;//LCD12864读、写选择
sbit e=P2^0;//12864使能信号
sbit flage=P0^7;
sbit beer=P3^0;//蜂鸣器引脚
sbit reset=P3^7;//蜂鸣器引脚
uchar ss,sp,kk;
//按键键值对应的字模
uchar code num2[]={
0x3E,0x51,0x49,0x45,0x3E, // -0-
0x00,0x42,0x7F,0x40,0x00, // -1-
0x62,0x51,0x49,0x49,0x46, // -2-
0x21,0x41,0x49,0x4D,0x33, // -3-
0x18,0x14,0x12,0x7F,0x10, // -4-
0x27,0x45,0x45,0x45,0x39, // -5-
0x3C,0x4A,0x49,0x49,0x31, // -6-
0x01,0x71,0x09,0x05,0x03, // -7-
0x36,0x49,0x49,0x49,0x36, // -8-
0x46,0x49,0x49,0x29,0x1E, // -9-
0x00,0x00,0x5F,0x00,0x00, // -!-
0x14,0x7F,0x14,0x7F,0x14, // -#-
0x22,0x14,0x7F,0x14,0x22, // -*-
};
//正常没有病人呼救对应的字模
uchar code num1[]={
0x80,0x80,0x80,0xBE,0xA2,0xA2,0xA2,0xA2,
0xA2,0xA2,0xA2,0xBF,0x82,0xC0,0x80,0x00,
0x00,0x00,0x00,0x04,0x06,0x05,0x04,0x04,
0x44,0x84,0x44,0x3E,0x04,0x00,0x00,0x00,
0x10,0x60,0x00,0xFC,0x04,0x24,0x24,0x24,
0x25,0xE6,0x24,0x24,0x34,0xA6,0x04,0x00,
0x04,0x42,0x31,0x0F,0x00,0xFF,0x01,0x11,
0x09,0x07,0x09,0x51,0x81,0x7F,0x01,0x00,
0x00,0x00,0xFC,0x94,0x94,0x94,0x95,0xB6,
0xD4,0x94,0x94,0x94,0x9E,0xC4,0x80,0x00,
0x40,0x30,0x0F,0x80,0x40,0x30,0x0F,0x04,
0x44,0x84,0x44,0x3E,0x04,0x00,0x00,0x00,
0x00,0x08,0x28,0x48,0xC8,0x08,0x08,0xFF,
0x88,0x0A,0x8C,0x48,0x6C,0x08,0x00,0x00,
0x00,0x10,0x10,0x08,0x04,0x42,0x81,0x7F,
0x00,0x03,0x04,0x04,0x08,0x18,0x08,0x00,
0x50,0x90,0x10,0xFF,0x10,0x92,0x54,0x20,
0xD0,0x1F,0x10,0x10,0xF0,0x18,0x10,0x00,
0x08,0x4C,0x82,0x7F,0x01,0x04,0x88,0x80,
0x41,0x36,0x08,0x37,0x40,0xC0,0x40,0x00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
};
//有病人呼救时对应的字模
uchar code num[]={
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x40,0x40,0x40,0xFF,0x20,0x30,0x20,0x04,
0x04,0xFC,0x04,0x04,0x04,0xFE,0x04,0x00,
0x00,0x00,0x00,0x1F,0x88,0x84,0x42,0x20,
0x18,0x07,0x40,0x80,0x40,0x3F,0x00,0x00,
0x00,0x02,0x02,0xC2,0x02,0x02,0x02,0xFE,
0x82,0x82,0x82,0xC2,0x83,0x02,0x00,0x00,
0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,
0x40,0x40,0x40,0x40,0x40,0x60,0x40,0x00,
0x20,0x18,0x08,0x0A,0xEC,0xA8,0xA8,0xAF,
0xA8,0xA8,0xEC,0x0A,0x08,0x28,0x18,0x00,
0x00,0x00,0x00,0x3E,0x02,0x02,0x02,0xFF,
0x02,0x22,0x42,0x3F,0x02,0x00,0x00,0x00,
};
/**选中左半屏**/
void zuo()
{
cs1=0;
cs2=1;
}
/**选中右半屏**/
void yuo()
{
cs1=1;
cs2=0;
}
/**判断LCD12864是否忙碌**/
void mang()
{
e=0;//使能拉低
rs=0;//选择命令
rw=1;//读操作
e=1;//使能拉高(产生下降沿)
e=0;//使能拉低
while(flage) ;//当第七位为0时才可以操作显示器
}
/**LCD12864写命令**/
void writecom(uchar z)
{
mang();//判忙
rs=0;//传输命令
rw=0;//写操作
P0=z;//向端口复赋值
e=1;//使能拉高(产生下降沿)
e=0;//使能拉低
}
/**LCD12864写数据**/
void writedat(uchar z)
{
mang();//判忙
rs=1;//传输数据
rw=0;//写操作
P0=z;//向端口复赋值
e=1;//使能拉高(产生下降沿)
e=0;//使能拉低
}
//选中要操作的页
void hang(uchar z)
{
uchar i;
i=z;
z=i|0xb8;//起始页
mang();//判忙
writecom(z);//写命令
}
//选中要操作的列
void lie(uchar z)
{
uchar i;
i=z;
z=i|0x40;//起始行
mang();//判忙
writecom(z);//写命令
}
/**LCD12864初始化**/
void init()
{
uchar i,j;
zuo();//选中左半屏
writecom(0x3f);//开显示
yuo();//选中右半屏
writecom(0x3f);//开显示
zuo();//选中左半屏
//左半屏清屏
for(i=0;i<8;i++)//控制页0-7总共8页
{
hang(i);
lie(0) ;//从第0列开始
for(j=0;j<64;j++)
{
writedat(0x00);//清屏数据
}
}
yuo();//选中右半屏
//右半屏清屏
for(i=0;i<8;i++)//控制页0-7总共8页
{
hang(i);
lie(0) ;//从第0列开始
for(j=0;j<64;j++)
{
writedat(0x00);//清屏数据
}
}
}
/**用来显示提示性文字“一切正常!病房报警等”**/
void xianshi(uchar s1,uchar s2,uchar *s3)
{
uchar i;
hang(s1);//选中页
lie(s2);//选中列
for(i=0;i<16;i++)
{
writedat(*s3);//写入数据
s3++;
}
hang(s1+1);//选中页
lie(s2);//选中列
for(i=0;i<16;i++)
{
writedat(*s3);//写入数据
s3++;
}
}
/*用来显示报警的病房号*/
void xianshi1(uchar s1,uchar s2,uchar *s3)
{
uchar i;
hang(s1);//选中页
lie(s2);//选中列
for(i=0;i<5;i++)
{
writedat(*s3);//写入数据
s3++;
}
}
/**矩阵按键检测函数**/
jiance()
{
P1=0XFC;//将P1.1置0
if(P1==0XEC)
{
return 1;//返回检测到的键值
}
if(P1==0XdC)
{
return 4;//返回检测到的键值
}
if(P1==0XbC)
{
return 7;//返回检测到的键值
}
if(P1==0X7C)
{
return '*';//返回检测到的键值
}
P1=0Xfb;//将P1.2置0
if(P1==0XEb)
{
return 2;//返回检测到的键值
}
if(P1==0Xdb)
{
return 5;//返回检测到的键值
}
if(P1==0Xbb)
{
return 8;//返回检测到的键值
}
if(P1==0X7b)
{
return 0;//返回检测到的键值
}
P1=0XF6;//将P1.3置0
if(P1==0XE6)
{
return 3;//返回检测到的键值
}
if(P1==0Xd6)
{
return 6;//返回检测到的键值
}
if(P1==0Xb6)
{
return 9;//返回检测到的键值
}
if(P1==0X76)
{
return '#';//返回检测到的键值
}
else
{
return 66;//返回检测到的键值
}
}
/**定时器初始化**/
void timerinit()
{
TMOD=0X01;
TH0=-50000/256;
TL0=-50000%256;
EA=1;//开总中断
ET0=1;//开定时器0
}
/**主函数**/
void main()
{
timerinit();//定时器初始化
init();//LCD12864初始化
kk=0;
while(1)
{
beer=1;
if(jiance()!=66)//如果检测到有按键被按下
{
switch(jiance())
{
ss=0;
sp=0;
case 0:TR0=1;ss=0;sp=0; kk=1;break;//如果0号病房呼救
case 1:TR0=1;ss=5;sp=5; kk=1;break;//如果1号病房呼救
case 2:TR0=1;ss=10;sp=10; kk=1;break;//如果2号病房呼救
case 3:TR0=1;ss=15;sp=15; kk=1;break;//如果3号病房呼救
case 4:TR0=1;ss=20;sp=20; kk=1;break;//如果4号病房呼救
case 5:TR0=1;ss=25;sp=25; kk=1;break;//如果5号病房呼救
case 6:TR0=1;ss=30;sp=30; kk=1;break;//如果6号病房呼救
case 7:TR0=1;ss=35;sp=35; kk=1;break;//如果7号病房呼救
case 8:TR0=1;ss=40;sp=40; kk=1;break;//如果8号病房呼救
case 9:TR0=1;ss=45;sp=45; kk=1;break;//如果9号病房呼救
case '*':TR0=1;ss=60;sp=50; kk=1;break;//如*号病房呼救
case '#':TR0=1;ss=55;sp=55; kk=1;break;//如果#号病房呼救
}
//显示有病房报警时的界面
//左半屏显示
zuo();
xianshi1(2,0+sp,num2+ss);//显示报警的病房号
xianshi(3,16,num1);
xianshi(3,32,num1+32);
xianshi(3,48,num1+64);
//右半屏显示
yuo();
xianshi(3,64,num1+96);
xianshi(3,80,num1+128);
xianshi1(4,96,num2+50);
}
if(reset==0)//当管理员按下复位键时系统恢复待机
{
while(reset==0);
init();//LCD12864初始化
//显示左半屏
zuo();
xianshi(3,16,num);
xianshi(3,32,num+32);
xianshi(3,48,num+64);
//显示右半屏
yuo();
xianshi(3,64,num+96);
xianshi1(4,80,num2+50);
}
if(kk==0)//显示正常工作,无病房报警界面
{
zuo();
xianshi(3,16,num);
xianshi(3,32,num+32);
xianshi(3,48,num+64);
yuo();
xianshi(3,64,num+96);
xianshi1(4,80,num2+50);
}
}
}
/**定时器驱动蜂鸣器报警**/
void timer0()interrupt 1
{
uint yy;
TH0=-5000/256;//定时器重装初值
TL0=-5000%256;
beer=~beer;//蜂鸣器报警
TR0=0;//关定时器
}