找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1446|回复: 1
打印 上一主题 下一主题
收起左侧

基于单片机的病床呼叫系统(八个床位外加时间控制)

[复制链接]
跳转到指定楼层
楼主
ID:580346 发表于 2019-7-8 22:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 努力努力在努力z 于 2019-7-8 22:58 编辑

#include<AT89x52.h>
#define uchar unsigned char
#define uint unsigned int
void display();//显示时间子函数
void display1();//显示倒计时时间子函数
void disp();  //显示呼叫病床总数及当前呼叫病床子函数
void Time0() ; //定时中断子函数,用于改变时间参数
void Time1() ;
void rest();    // 初始化子函数,用于病床复位后
uchar codeDSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0xc6,0xa1,0x86,0x8e,0x00};      //共阴极数码管显示段码
sbit P36=P3^6;                              //接蜂鸣器
sbit P37=P3^7;                              //病床复位按键
void DelayMS(uint x)                      //延时子函数
{
uchar y;
while(x--)
for(y=0;y<120;y++);
}
uchar d[8]={0,0,0,0,0,0,0,0};                //用于存放呼叫病床的显示段码
uchar g=0,j=0,log=0,CEN=0;      //下面有详细说明
void rest()    // 初始化子函数,用于病床复位后
{
g=0;     //g计数:要显示的呼叫病床个数
log=0;     //病床呼叫标志位,有人呼叫置1
P36=0;     //接蜂鸣器,高电平响
CEN=0;     //当前显示的病床号在数组d中的偏移量
for(j=0;j<8;j++) //清空数组d
d[j]=0;
}
ucharhour=0,min=0,secon=0,tim0=0,hour1=0,min1=0,secon1=0,tim1=0;//时分秒的计数参数
uchar watch=0,t,KeyNo;//watch倒计时秒表标志位,KeyNo保存键号
void Keys_Scan()//4*4键盘扫描得到按键号即床号:0~7存于KeyNo,8~15号用于时间调整
{
uchar temp;
P1=0xfe;
temp=P1;
if(temp!=0xfe)
{
log=1;                    //病床呼叫标志
P36=1;                    //只要有病床呼叫蜂鸣器便发出响声
DelayMS(10);            //延时
P36=0;                    //关蜂鸣器
switch(temp)
{
case 0xee: KeyNo=0;break;
case 0xde: KeyNo=1;break;
case 0xbe: KeyNo=2;break;
case 0x7e: KeyNo=3;break;
}
}
P1=0xfd;
temp=P1;
if(temp!=0xfd)
{
log=1;                    //病床呼叫标志
P36=1;                    //只要有键按下就开蜂鸣器
DelayMS(10);            //延时
P36=0;                    //关蜂鸣器
switch(temp)
{
case 0xed: KeyNo=4;break;
case 0xdd: KeyNo=5;break;
case 0xbd: KeyNo=6;break;
case 0x7d: KeyNo=7;break;
}
}
P1=0xfb;
temp=P1;
if(temp!=0xfb&&g==0) //无人呼叫时才能进行时间调整
switch(temp)
{
case 0xeb: KeyNo=8;
if(watch!=0) t=secon1;
else t=secon;
if(++t>=60)t=0;
if(watch!=0) secon1=t;
else secon=t;
break;
case 0xdb: KeyNo=9;
if(watch!=0) t=min1;
else t=min;
if(++t>=60)t=0;
if(watch!=0) min1=t;
else min=t;
break;
case 0xbb: KeyNo=10;
if(watch!=0) t=hour1;
else t=hour;
if(++t>=60)t=0;
if(watch!=0) hour1=t;
else hour=t;
break;
case 0x7b: KeyNo=11;TR0=~TR0;break;               //暂停计时
}
P1=0xf7;
temp=P1;
if(temp!=0xf7&&g==0)
switch(temp)
{
case 0xe7: KeyNo=12;
if(watch!=0) t=secon1;
else t=secon;
if(t--==0)t=59;
if(watch!=0) secon1=t;
else secon=t;
break;
case 0xd7: KeyNo=13;
if(watch!=0) t=min1;
else t=min;
if(t--==0)t=59;
if(watch!=0) min1=t;
else min=t;
break;
case 0xb7: KeyNo=14;
if(watch!=0) t=hour1;
else t=hour;
if(t--==0)t=59;
if(watch!=0) hour1=t;
else hour=t;
break;
case 0x77: KeyNo=15;watch++;    //倒计时watch=1设定倒计时时间,
if(watch==2) TR1=1;      //watch=2开始计时
if(watch==3)
{
watch=0;
TR1=0;
}
break;   
}
//等待按键松开
P1=0X0f;
temp=P1;
while(temp!=0x0f)   
{
P1=0X0f;
temp=P1;
if(log==1)//当前按键为病床按键
disp(); //显示病床号及呼叫总数
else if(watch==0)    //当前按键为时间调整按键且无人呼叫
display();          //显示时间
else display1();    //当前按键为倒计时时间调整按键且无人呼叫
}
}
void display() //显示时间函数
{
P0=0xfe;
P2=DSY_CODE[hour/10];
DelayMS(1);
P0=0xfd;
P2=DSY_CODE[hour%10];
DelayMS(1);
P0=0xfb;
P2=DSY_CODE[min/10];
DelayMS(1);
P0=0xf7;
P2=DSY_CODE[min%10];
DelayMS(1);
P0=0xef;
P2=DSY_CODE[secon/10];
DelayMS(1);
P0=0xdf;
P2=DSY_CODE[secon%10];
DelayMS(1);
}
void display1() //倒计时显示时间函数
{
P0=0xfe;
P2=DSY_CODE[hour1/10];
DelayMS(1);
P0=0xfd;
P2=DSY_CODE[hour1%10];
DelayMS(1);
P0=0xfb;
P2=DSY_CODE[min1/10];
DelayMS(1);
P0=0xf7;
P2=DSY_CODE[min1%10];
DelayMS(1);
P0=0xef;
P2=DSY_CODE[secon1/10];
DelayMS(1);
P0=0xdf;
P2=DSY_CODE[secon1%10];
DelayMS(1);
}
void disp()    //显示呼叫病床总数及当前呼叫病床
{
DelayMS(1);
P0=0xfe;
P2=DSY_CODE[g];  //显示当前呼叫病床总数
DelayMS(1);
P0=0xfd;
P2=d[CEN];//显示当前床号,CEN的值在定时中断中发生发生改变,实现一秒的闪烁显示,精华之处
DelayMS(1);
}
void main()        //主程序
{
TMOD=0x00;             //定时器T0方式0
TH0=(8192-4000)/32; //计时250*4ms=1s
TL0=(8192-4000)%32;
TH1=(8192-5000)/32; //计时250*4ms=1s
TL1=(8192-5000)%32;
IE=0x8a;            //T0,T1中断
PX1=1;
TR1=0;                //T1
TR0=1;               //初始化完毕
while(1)          //主程序在此处循环
{
if(g!=0)          //有人呼叫时,显示病床号
disp();
else if(watch==0)//无人呼叫时,显示时、分、秒
display();
else              //无人呼叫显示倒计时
display1();
//判断是否有病床呼叫
P1=0xf0;
if(P1!=0xf0)
{
Keys_Scan();            //有呼叫则求得床号
for(j=0;j<8;j++)        //判断是否是重复按键若是则不再保存本次床号
if(DSY_CODE[KeyNo]==d[j])
{
j=8;
log=0;
}   
if(log==1)
{
g++;
if(g==9)g=0;
switch(g)
{
case 1: d[0]=DSY_CODE[KeyNo];break;
case 2: d[1]=DSY_CODE[KeyNo];break;
case 3: d[2]=DSY_CODE[KeyNo];break;
case 4: d[3]=DSY_CODE[KeyNo];break;
case 5: d[4]=DSY_CODE[KeyNo];break;
case 6: d[5]=DSY_CODE[KeyNo];break;
case 7: d[6]=DSY_CODE[KeyNo];break;
case 8: d[7]=DSY_CODE[KeyNo];break;
}
}
}
if(P37==0)      //按下病床复位键
rest();
}
}
void Time0() interrupt 1 //显示时间
{
TH0=(8192-4000)/32;    //恢复初值
TL0=(8192-4000)%32;
if(d[CEN]==0)CEN=0;      //精华所在之处,非常巧妙
if(++tim0!=250) return;
tim0=0;
CEN++;
if(CEN==8)CEN=0;
secon++;
if(secon==60)
{
secon=0;
min++;
if(min==60)
{
min=0;
hour++;
if(hour==24)hour=0;
}
}
}
void Time1() interrupt 3 //倒计时秒表
{
TH1=(8192-5000)/32;    //初值重装
TL1=(8192-5000)%32;
if(++tim1!=2) return; //计时10ms
tim1=0;
if(secon1!=0)            //秒针调整,此if与下面的两个else if语句能且只能执行其中的一个
secon1--;
else if(hour1!=0)    //秒针等于0,时针不为0
{
secon1=99;
min1--;
if(min1>=60)   
{
min1=59;
hour1--;
if(hour1==0)
hour1=0;
}   
}
else if(min1!=0)    //秒针,时针都为0,分针不为0
{
secon1=99;
min1--;
}
if(hour1==0&&min1==0&&secon1==0)
TR1=0;
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:503717 发表于 2019-11-14 22:22 | 只看该作者
想问一下,如果要加模块,怎么加啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表