51单片机病房呼叫器(8位病床)

该系统采用AT89C51单片机,通过按键扫描模块、数码管显示和LED灯指示,实现病房呼叫与护士响应的功能。当病房呼叫时,护士站会显示病房号并报警,护士处理完毕后可通过按键复位关闭报警。系统还包括复位、晶振、报警灯和蜂鸣器模块。
摘要由CSDN通过智能技术生成

目录

内容描述

工具

总体设计

Proteus仿真图:

 Keil程序完整代码:

完整成品链接

程序流程图

 详细描述


内容描述

系统若某一个病房呼叫,护士站内的显示模块能显示相应的病房号,而且与该病房号对应的指示灯也要点亮,并响铃报警;当护士处理完相应病房的事情时,可按下按键,红色报警灯熄灭表示护士已处理完事情。

        功能:(1) 系统能控制8个病房的情况;

                (2)每个病房有独立的按键和指示灯;

                (3)要求护士值班室有1个响应键;

                (4)要求护士站内有显示;

                (5)要求护士站内有与病房号对应的警报灯和蜂鸣器;

                (6)按下复位键后系统重新自检。

工具

代码编写:Keil uVision5

仿真工具:Proteus 8 Professional

总体设计

整个系统有八部分组成:单片机控制模块、按键扫描模块、数码管显示模块、LED灯显示模块、晶振模块、复位模块、报警灯和蜂鸣器模块、响应模块。

其中单片机控制器则是采用的是AT89C51,AT89SC51是一个低功耗,高性能CMOS 8位单片机,片内含4k Flash,40个引脚,对于完成这个任务非常适合。

按键扫描模块使用的是类似矩阵按键,这样按键占用较少的引脚就能实现较多按键值的读取。

数码管显示模块负责床号的显示,用来提示护士哪个床号有病人呼叫。

LED灯显示模块用来提示护士哪个病床需要帮助。

晶振模块为单片机系统提供基准时钟信号。

复位模块使单片机系统初始化。

报警灯和蜂鸣器模块为本系统提供声音和LED灯指示的报警用来提示护士有病床需要帮助。

响应电路:当护士处理完相应病房的事情时,可按下按键,绿色报警灯和红色LED灯熄灭表示护士已处理完事情。

Proteus仿真图

 Keil程序完整代码

#include<reg51.h>  
#define uchar unsigned char
#define uint unsigned int
sbit LED=	P3^0;		  //定义LED指示灯接口
sbit BUZZER =	P3^3;	//蜂鸣器接口
sbit key=	P3^7;		  //清除按键

sbit led1 =	P2^0;
sbit led2 =	P2^1;
sbit led3 =	P2^2;
sbit led4 =	P2^3;
sbit led5 =	P2^4;
sbit led6 =	P2^5;
sbit led7 =	P2^6;
sbit led8 =	P2^7;
uint array[10]={1,1,1,1,1,1,1,1,1};



uchar code table[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共阳数码管编码
uchar Key_scan() //扫描按键
{
	static uchar key_down;
	uchar t=200;
	uchar key_num=0xff,tem,i; 
	uchar keynum_tab[14]={0x7e,0xd7,0xb7,0x77,0xdb,0xbb,0x7b,0xdd,0xbd,0x7d,0xde,0xbe,0x7e};//表格数据是根据按键值和个按键的定义的出来的
	P1 = 0xf0;
	if(P1 != 0xf0)//说明有按键按下
	{	
		while(t--);//延时去抖动				
		if((key_down==0))	
		{
			tem = P1;
			P1=0XFF;
			P1 = (tem|0x0f);
			key_num = P1;
			key_down=1;	 
		
			for(i=1;i<9;i++)
			{
				if(keynum_tab[i]==key_num){
					array[i]=0;
					
				break;}
			}
			return i;
				
		}
		else
			return 0xff;		  		   
	}	
	else
	{
		key_down = 0;
		return 0xff;		
	}  
  
}
 //刷新显示num
 void Dispaly(uchar num)
 {
 	//static uchar t=0;
		P0=0xff;
	
	 if(num!=0){
		 P0=table[num];
	 }
	 if(array[1]==0){
		 led1=0;
	 }
	 if(array[2]==0){
		 led2=0;
	 }
	 if(array[3]==0){
		 led3=0;
	 }
	 if(array[4]==0){
		 led4=0;
	 }
	 if(array[5]==0){
		 led5=0;
	 }
	 if(array[6]==0){
		 led6=0;
	 }
	 if(array[7]==0){
		 led7=0;
	 }
	 if(array[8]==0){
		 led8=0;
	 }
   
 }
/*主函数*/						  
void main(void)
{
  uchar num=0,House_num=0;
  uchar flag=0;
  uchar i=200;
	
	uint j=1;
	led1=1;
	led2=1;
	led3=1;
	led4=1;
	led5=1;
	led6=1;
	led7=1;
	led8=1;
	
  while(1)
  {
  	num=Key_scan(); //获取矩阵按键数值
	  if(num<9&&flag==0) //有按键按下就打开指示灯和报警
	  {
		House_num=num;
		LED=0;
		BUZZER=0;
		flag=1;
	  }
	  if(key==0)//清零键按下
	  {
	  	while(i--);	//延时去抖
			if(key==0)//清除报警和指示灯
			{
				LED=1;
				BUZZER=1;
				
				flag=0;	
			/*	if(House_num==1){
						array[1]=1; 
						led1=1;
				}else if(House_num==2){
						array[2]=1;
						led2=1;
				}else if(House_num==3){
						array[3]=1;
						led3=1;
				}else if(House_num==4){
						array[4]=1;
						led4=1;
				}else if(House_num==5){
						array[5]=1;
						led5=1;
				}else if(House_num==6){
										array[6]=1;
										led6=1;
				}else if(House_num==7){
										array[7]=1;
										led7=1;
				}else if(House_num==8){
										array[8]=1;
										led8=1;
			 }*/
		
			 switch(House_num){
				 case 1:
								array[1]=1; 
								led1=1;
								break;
				 case 2:
								array[2]=1;
								led2=1;
								break;
				 case 3:
								array[3]=1;
								led3=1;
								break;
				 case 4: 
								array[4]=1;
								led4=1;
								break;
				 case 5:
								array[5]=1;
								led5=1;
								break;
				 case 6:
								array[6]=1;
								led6=1;
								break;
				 case 7:
								array[7]=1;
								led7=1;break;
				 case 8:
								array[8]=1;
								led8=1;
								break;
				 default:
								break;
			 }
				House_num=0;//清除房间号		
			 
		}
	  }
	  
	   for(j=1;j<9;j++){
			 if(array[j]==0){
				 House_num=j;
				 break;
		 }
	 }
		Dispaly(House_num);//显示相应的房间号 
	}
}

完整成品链接

病房呼叫器

程序流程图

 详细描述

复位电路:由电容串联电阻构成,由图并结合“电容电压不能突变”的性质,可以知道,当系统一上电,RST脚将会出现高电平,并且,这个高电平持续的时间由电路的RC值来决定。典型的51单片机当RST脚的高电平持续两个机器周期以上就将复位,所以,适当组合RC的取值就可以保证可靠的复位,C取1u,R取100,让RC组合可以在RST脚上产生不少于2个机周期的高电平。根据电路分析,可以算出电容充电到电源电压的0.7倍(单片机的电源是5V,所以充电到0.7倍即为3.5V),需要的时间100k*1UF=0.1S,大于两个机器周期2us((1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12),所以单片机就能复位。

 晶振电路:典型的晶振取1MHz可以准确地得到9600波特率和19200波特率,用于有串口通讯的场合;取12MHz可以产生精确的uS级时歇,方便定时操作,这里我们没有用到串口通讯,直接使用12MHz的晶振以获得更加精确的时间。

数码管显示电路,这里使用的是一个一位的共阳数码管,用来显示具体是哪个床位呼叫,接入到单片机的P0端口,给低电平能够点亮。数码管的动态扫描是利用人眼的视觉暂留效应,让数码管分时段依次点亮,当轮寻的频率快到一定程度的时候,人眼就感觉不到数码管在闪烁了,这就是所谓的数码管动态扫描。动态扫描相较于静态显示的优势是占用较少的单片机引脚。

指示灯电路比较简单,主要由LED灯和排阻组成,接入到单片机的P2端口,给的电平能够点亮。根据LED灯的颜色和封装不同电流也不同,一般点亮一个LED灯只需要几毫安就可以了。电流越大指示灯越亮。如果想要点亮LED灯只需要把相应的IO口拉低就可以了。

蜂鸣器的驱动单路由一个蜂鸣器、电阻和一个PNP三极管组成,由于蜂鸣器的工作电流比较大所以使用三极管进行驱动。通过调整P3.3口的高低电平,来实现三极管的开关作用,之所以通过三极管的发射极引导电流进入集电极,而不是用P3.3直接加到蜂鸣器上,是因为单片机的功率很小,虽然可以输出很高的电压,但是是无法驱动这种功率器件的。

当P3.3口输出高电平(5V)时,VCC即电源也是5V,此时三极管没有导通,所以蜂鸣器无反应,当输出低电平时,发射极电压远大于基极,电流从发射极流入集电极,蜂鸣器震动。

报警灯电路比较简单,主要由LED灯和电阻组成,接入到单片机的P3.0端口,给低电平能够点亮。根据LED灯的颜色和封装不同电流也不同,一般点亮一个LED灯只需要几毫安就可以了。电流越大指示灯越亮。当有病房按键按下时,IO口拉低LED灯被点亮。

响应电路则是由一个按键构成,接到单片机的P3.7端口,当护士处理完事情时按下按键得到低电平,LED指示灯和报警灯同时熄灭,蜂鸣器停止鸣响。

一个类似矩阵的按键每行接在一起,每列接在一起,然后分别与单片机的P1口进行连接。其工作原理是单片机不断的逐行扫描按键来确定到底是哪一个按键被按下了,然后根据按下的按键再进行相应的操作。

起初,先给全体赋予高电平1(P1=0xFF),如果出现一个端口为低电平0,说明这条线路导通了,那么就可以判断是哪个按键按下了。

(由于P1端口有8个接口,用矩阵的方式最多可以形成16个按键,由于题目要求这里只做了8个)

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值