模拟病房呼叫系统设计.docx

上传人:b****1 文档编号:23006377 上传时间:2023-04-30 格式:DOCX 页数:22 大小:219.29KB
下载 相关 举报
模拟病房呼叫系统设计.docx_第1页
第1页 / 共22页
模拟病房呼叫系统设计.docx_第2页
第2页 / 共22页
模拟病房呼叫系统设计.docx_第3页
第3页 / 共22页
模拟病房呼叫系统设计.docx_第4页
第4页 / 共22页
模拟病房呼叫系统设计.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

模拟病房呼叫系统设计.docx

《模拟病房呼叫系统设计.docx》由会员分享,可在线阅读,更多相关《模拟病房呼叫系统设计.docx(22页珍藏版)》请在冰豆网上搜索。

模拟病房呼叫系统设计.docx

模拟病房呼叫系统设计

模拟病房呼叫系统设计

一、设计目的

通过设计模拟病床呼叫的程序,更加熟练掌握单片机C语言指令的使用,培养用单片机来实现一些电子设备运行的逻辑思路,为以后更好的使用单片机打下基础。

二、设计要求

模拟一个护理站下管8个床位,哪个病人要呼叫可以按键,相应蜂鸣器响,数码管显示:

呼叫数量_床位号.要求:

1.6个数码管,正常情况下显示时间(时分秒),时间可通过按键调整。

2.有人呼叫则闪烁显示数量_床位号并蜂鸣器响,按应答键后继续显示时间。

3.若同时有多个病人呼叫则依次轮流显示:

数量_床位号。

4、要求做出实物。

三、硬件电路设计

3.1系统结构框图

 

图3-1 系统框图

当单片机一上电时,数码管显示时,分,秒。

并且可通过按键对时,分的调节。

调节按键主要运用外部中断程序,其中时钟的显示是通过TO定时器定时1s和数码管显示电路主要运用动态扫描的方式以实现的。

此设计主要运用键盘扫描电路来设计病床号。

当有按键按下时数码管由当前的显示时,分,秒,变为显示当前呼叫数量和呼叫床号,并且呼叫床号按呼叫顺序循环显示,程序中运用数组作为按键缓冲区,先存储按键键值然后实现动态显示。

当按下复位键后重新显示时,分,秒。

并且清空按键缓冲区。

3.2STC89C52单片机芯片

89C52共有四个八位的并行双向口,即有32根输入输出口线。

各口的每一位均由锁存器、输出驱动器和输入缓冲器组成。

图3-2STC89C52集成芯片

89C52共有四个八位的并行双向口,即有32根输入输出口线。

各口的每一位均由锁存器、输出驱动器和输入缓冲器组成。

VCC(40引脚):

电源电压

VSS(20引脚):

接地

P0端口(P0.0~P0.7,39~32引脚):

P0口是一个漏极开路的8位双向I/O口。

作为输出端口,每个引脚能驱动8个TTL负载,对端口P0写入“1”时,可以作为高阻抗输入。

在访问外部程序和数据存储器时,P0口也可以提供低8位地址和8位数据的复用总线。

此时,P0口内部上拉电阻有效。

在FlashROM编程时,P0端口接收指令字节;而在校验程序时,则输出指令字节。

验证时,要求外接上拉电阻。

P1端口(P1.0~P1.7,1~8引脚):

P1口是一个带内部上拉电阻的8位双向I/O口。

P1的输出缓冲器可驱动(吸收或者输出电流方式)4个TTL输入。

对端口写入1时,通过内部的上拉电阻把端口拉到高电位,这是可用作输入口。

P1口作输入口使用时,因为有内部上拉电阻,那些被外部拉低的引脚会输出一个电流。

P1口特点是输出锁存器,输出时没有条件。

输入缓冲,输入时有条件,即需要先将该口设为输入状态,先输出1。

此外,P1.0和P1.1还可以作为定时器/计数器2的外部技术输入(P1.0/T2)和定时器/计数器2的触发输入(P1.1/T2EX)

P3口为准双向口。

可以字节访问,也可以位访问。

P3.0---RXD,串行输入口。

P3.1---TXD,串行输出口。

P3.2---INT0,外部中断0的请求。

P3.3---INT1,外部中断1的请求。

P3.4---T0,定时器/计数器0外部计数脉冲。

P3.5---T1,定时器/计数器,1外部计数脉冲。

P3.6---WR,外部数据存储器写选通。

P3.7---RD,外部数据存储器读选通。

RST(9引脚):

复位输入。

当输入连续两个机器周期以上高电平时为有效,用来完成单片机单片机的复位初始化操作。

ALE(30引脚):

地址锁存控制信号(ALE)是访问外部程序存储器时,锁存低8位地址的输出脉冲。

XTAL1(19引脚):

振荡器反相放大器和内部时钟发生电路的输入端。

XTAL2(18引脚):

振荡器反相放大器的输入端。

 

3.3键盘扫描电路

 

图3-3按键扫描电路

病床呼叫按钮采用了矩阵键盘扫描的方式。

按键设置在行、列线交点上,行、列线分别连接到按键开关的两端。

首先将列至零,主程序中扫描P1是否有键按下,如果有键按下执行子程序,先将列至零,扫描行然后置位行扫描列。

3.4数码管显示电路

图3-4数码管显示电路

数码管是通过锁存器573输出的。

驱动573需要上拉电阻。

通过P0口控制他的片选,以及数码管的位选,通过P2口控制数码管的段选,主程序中通过动态扫描以实现数码管的动态输出。

原理说明:

  74HC573的八个锁存器都是透明的D型锁存器,当使能(G)为高时,Q输出将随数据(D)输入而变。

当使能为低时,输出将锁存在已建立的数据电平上。

输出控制不影响锁存器的内部工作,即老数据可以保持,甚至当输出被关闭时,

  新的数据也可以置入。

这种电路可以驱动大电容或低阻抗负载,可以直接与系统总线接口并驱动总线,而不需要外接口。

特别适用于缓冲寄存器,I/O通道,双向总线驱动器和工作寄存器。

当输入的数据消失时,在芯片的输出端,数据仍然保持;这个概念在并行数据扩展中经常使用到。

3.5系统电路原理图

图3-7系统电路原理图

所用器件如下如所示:

数码管:

LD3461AS-SS22

锁存器:

74HC573

单片机:

AT89S52

上拉电阻:

RESPACK-8

4、软件

4.1程序设计

图4-1程序设计流程图

无人呼叫时,运用动态扫描方式利用定时器T0显示时间;有人呼叫时,运用数组作为按键缓冲区,先存储按键值然后动态显示按键床号。

 

4.2子程序设计

图4-2子程序流程图

扫描P1口前四位是否有变化,变化的位数为按键床号所属的行数;扫描P1口后四位是否有变化,变化的位数为按键床号所属的列数。

行列结合可知呼叫的病床号。

 

五、实验结果图

仿真时间:

启动后系统会自动进入显示时间状态,此状态下S8、S9、S10三个按键分别能对秒、分、时进行加1设置,而S12、S13、S14三个按键分别能对毫秒、秒、分进行减1设置。

按下S11便暂停显示。

仿真时间如图所示:

图5-1仿真时间

有呼叫时仿真:

在任意时刻按下S0至S7中的一个按键,蜂鸣器发出响声,进入显示病床号状态,左1显示呼叫总人数,右1闪烁显示病床号(若有多个人呼叫)。

在按下复位键P37以前如有病人重复按键则只发出响声,不会改变呼叫总人数的显示。

另外此状态下S8至S15处于无效无效状态,但时间计数仍未停止。

图5-2仿真呼叫

倒计时秒表仿真:

在无人呼叫时按下S15便进入秒表时间设定状态,此状态下S8、S9、S10三个按键分别能对毫秒、秒、分进行加1设置,而S12、S13、S14三个按键分别能对毫秒、秒、分进行减1设置,设置完成后再次按下S15倒计时便开始。

当计时结束后再次按下S15,便又回到了时间显示状态。

两个状态互不影响。

图5-3倒计时秒表仿真

六、源程序

/*************************************************************

程序名称:

病床呼叫系统设计

简要说明:

无人呼叫显示时间,有人呼叫显示病床号及呼叫总人数。

P0,P2口接数码管显示,P1口接4*4矩阵键盘(键号0~15)。

各键功能:

0~7号按键:

病床号0~7;

8~10号按键:

秒,分,时加1调整键

12~14号按键:

秒,分,时减1调整键

11号按键:

暂停时间显示键

15号按键:

倒计时的秒表

P3.6接蜂鸣器按键

P3.7病床复位键

编写:

邢志杰

时间:

2015年07月8日

最后修改时间:

2015年07月10日

**************************************************************/

#include

#defineucharunsignedchar

#defineuintunsignedint

voiddisplay();//显示时间子函数

voiddisplay1();//显示倒计时时间子函数

voiddisp();//显示呼叫病床总数及当前呼叫病床子函数

voidTime0();//定时中断子函数,用于改变时间参数

voidTime1();

voidrest();//初始化子函数,用于病床复位后

ucharcodeDSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,

0x77,0x7c,0xc6,0xa1,0x86,0x8e,0x00};//共阴极数码管显示段码

sbitP36=P3^6;//接蜂鸣器

sbitP37=P3^7;//病床复位按键

voidDelayMS(uintx)//延时子函数

{

uchary;

while(x--)

for(y=0;y<120;y++);

}

uchard[8]={0,0,0,0,0,0,0,0};//用于存放呼叫病床的显示段码

ucharg=0,j=0,log=0,CEN=0;//下面有详细说明

voidrest()//初始化子函数,用于病床复位后

{

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;//时分秒的计数参数

ucharwatch=0,t,KeyNo;//watch倒计时秒表标志位,KeyNo保存键号

voidKeys_Scan()//4*4键盘扫描得到按键号即床号:

0~7存于KeyNo中,8~15号用于时间调整

{

uchartemp;

P1=0xfe;

temp=P1;

if(temp!

=0xfe)

{

log=1;//病床呼叫标志

P36=1;//只要有病床呼叫蜂鸣器便发出响声

DelayMS(10);//延时

P36=0;//关蜂鸣器

switch(temp)

{

case0xee:

KeyNo=0;break;

case0xde:

KeyNo=1;break;

case0xbe:

KeyNo=2;break;

case0x7e:

KeyNo=3;break;

}

}

P1=0xfd;

temp=P1;

if(temp!

=0xfd)

{

log=1;//病床呼叫标志

P36=1;//只要有键按下就开蜂鸣器

DelayMS(10);//延时

P36=0;//关蜂鸣器

switch(temp)

{

case0xed:

KeyNo=4;break;

case0xdd:

KeyNo=5;break;

case0xbd:

KeyNo=6;break;

case0x7d:

KeyNo=7;break;

}

}

P1=0xfb;

temp=P1;

if(temp!

=0xfb&&g==0)//无人呼叫时才能进行时间调整

switch(temp)

{

case0xeb:

KeyNo=8;

if(watch!

=0)t=secon1;

elset=secon;

if(++t>=60)t=0;

if(watch!

=0)secon1=t;

elsesecon=t;

break;

case0xdb:

KeyNo=9;

if(watch!

=0)t=min1;

elset=min;

if(++t>=60)t=0;

if(watch!

=0)min1=t;

elsemin=t;

break;

case0xbb:

KeyNo=10;

if(watch!

=0)t=hour1;

elset=hour;

if(++t>=60)t=0;

if(watch!

=0)hour1=t;

elsehour=t;

break;

case0x7b:

KeyNo=11;TR0=~TR0;break;//暂停计时

}

P1=0xf7;

temp=P1;

if(temp!

=0xf7&&g==0)

switch(temp)

{

case0xe7:

KeyNo=12;

if(watch!

=0)t=secon1;

elset=secon;

if(t--==0)t=59;

if(watch!

=0)secon1=t;

elsesecon=t;

break;

case0xd7:

KeyNo=13;

if(watch!

=0)t=min1;

elset=min;

if(t--==0)t=59;

if(watch!

=0)min1=t;

elsemin=t;

break;

case0xb7:

KeyNo=14;

if(watch!

=0)t=hour1;

elset=hour;

if(t--==0)t=59;

if(watch!

=0)hour1=t;

elsehour=t;

break;

case0x77:

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();//显示病床号及呼叫总数

elseif(watch==0)//当前按键为时间调整按键且无人呼叫

display();//显示时间

elsedisplay1();//当前按键为倒计时时间调整按键且无人呼叫

}

}

voiddisplay()//显示时间函数

{

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);

}

voiddisplay1()//倒计时显示时间函数

{

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);

}

voiddisp()//显示呼叫病床总数及当前呼叫病床

{

DelayMS

(1);

P0=0xfe;

P2=DSY_CODE[g];//显示当前呼叫病床总数

DelayMS

(1);

P0=0xfd;

P2=d[CEN];//显示当前床号,CEN的值在定时中断中发生发生改变,实现一秒的闪烁显示,精华之处

DelayMS

(1);

}

voidmain()//主程序

{

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();

elseif(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)

{

case1:

d[0]=DSY_CODE[KeyNo];break;

case2:

d[1]=DSY_CODE[KeyNo];break;

case3:

d[2]=DSY_CODE[KeyNo];break;

case4:

d[3]=DSY_CODE[KeyNo];break;

case5:

d[4]=DSY_CODE[KeyNo];break;

case6:

d[5]=DSY_CODE[KeyNo];break;

case7:

d[6]=DSY_CODE[KeyNo];break;

case8:

d[7]=DSY_CODE[KeyNo];break;

}

}

}

if(P37==0)//按下病床复位键

rest();

}

}

voidTime0()interrupt1//显示时间

{

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;

}

}

}

voidTime1()interrupt3//倒计时秒表

{

TH1=(8192-5000)/32;//初值重装

TL1=(8192-5000)%32;

if(++tim1!

=2)return;//计时10ms

tim1=0;

if(secon1!

=0)//秒针调整,此if与下面的两个elseif语句能且只能执行其中的一个

secon1--;

elseif(hour1!

=0)//秒针等于0,时针不为0

{

secon1=99;

min1--;

if(min1>=60)

{

min1=59;

hour1--;

if(hour1==0)

hour1=0;

}

}

elseif(min1!

=0)//秒针,时针都为0,分针不为0

{

secon1=99;

min1--;

}

if(hour1==0&&min1==0&&secon1==0)

TR1=0;

}

七、设计总结

通过这次的程序设计使我懂得了动态扫描,关于汇编语言与C语言的联系。

比如汇编语言的查表指令在C语言中可以用数组的形式实现。

在编程过程中同样和其他同学一样也遇到了很多问题,比如在中断那忽略了interrupt0中的0,后来查资料才知道这不是随便写的。

论文设计是理论联系实际的最好方法之一,使我了解了许多课堂上学不到的东西,综合运用知识。

发现,提出,分析和解决实际问题的能力明显提高。

此外本课题是三人一组,团队合作至关重要,遇到问题时互相研究讨论。

最后在指导老师的帮助下,终于顺利完成本次实践。

在此感谢对给过我帮助的所有同学和各位指导老师!

八、参考文献

[1]沈美明.《IBM-PC汇编语言程序设计》.清华大学出版社.

[2]胡汉才.单片机原理及其接口技术.清华大学出版社,2004.

[3]贾金铃等.微型计算机原理及应用.重庆大学出版社,2006.

[4]薛栋梁.《单片机原理及应用》.中国水利水电出版社,2001.

[5]李勋.单片机微型计算机大学读本.北京航空航天大学出版社,2002.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1