1 基于51单片机的12路病房呼叫系统设计与实现
点击链接下载protues仿真设计资料:https://download.csdn.net/download/m0_51061483/92081442
1.1 项目背景与系统概述
- 医院病房呼叫系统是临床护理工作中非常关键的基础设施之一。病人通常在卧床状态下需要随时呼叫护士或医护人员,例如输液异常、身体不适、行动不便、紧急情况等。传统方式依赖人工巡视或患者大声呼喊,容易出现响应不及时、护士工作负担增加、夜间影响他人休息等问题。通过电子呼叫系统,病人只需按下床头呼叫按钮,护士站即可立即获知具体呼叫位置,从而快速处理,提高护理效率与安全性。
- 本设计以AT89S51(8051内核)单片机为核心控制器,构建一个12路病房呼叫系统。系统以3×4矩阵键盘作为呼叫输入,映射到4个病房、每个病房3个病床(共12个床位)。当病人按下对应呼叫键后,护士站显示屏实时显示具体病床号,同时点亮相应指示灯,并驱动蜂鸣器持续报警,提醒护士及时处理。医护人员按下清除键后,系统取消当前呼叫信息,关闭指示灯,停止蜂鸣器,显示屏清除当前呼叫内容。
- 本系统的核心价值包括:
- 系统整体由以下部分组成:
- 系统工作逻辑可以归纳为:
- 实时扫描矩阵键盘
- 检测到呼叫键按下后确定床位号
- 锁存呼叫信息并触发声光报警
- 显示床位号直至医护人员清除
- 清除后恢复待机状态等待下一次呼叫
2 功能设计
2.1 12路远程呼叫功能
- 系统支持12个呼叫按钮,分别对应4个病房,每个病房3张病床。
- 患者按下任意呼叫键后,系统必须做到:
- 立即识别按下的键位并进行消抖确认;
- 生成唯一的床位编号(例如“1-1床”“2-3床”等);
- 将呼叫信息存入当前呼叫寄存器并保持显示;
- 触发蜂鸣器持续报警并点亮相应指示灯。
- 呼叫信息必须可靠锁存,即按键松开后呼叫状态仍然保持,直到护士站清除。这样可以避免病人短按后信号消失导致护士错过信息。
2.2 3×4矩阵键盘输入功能
- 由于AT89S51的IO资源有限,采用矩阵键盘可用7根线实现12个按键输入:
- 3行(R0~R2)
- 4列(C0~C3)
- 扫描方式一般为:
- 软件必须加入消抖措施,防止机械按键抖动造成误判或重复触发。
2.3 护士站显示具体床位号
- 当有呼叫发生时,护士站显示屏必须显示对应床位号。
- 显示内容可以采用:
- 数码管:显示“房号+床号”,例如“203”表示2号房3床(需要规范编码方式);
- LCD1602:显示“ROOM:2 BED:3”或“2-3 CALL”等文字提示,更直观。
- 显示逻辑要求:
- 无呼叫时显示“READY”或空白;
- 呼叫时显示具体床位号并保持;
- 清除后恢复待机显示。
2.4 指示灯提示与蜂鸣器持续报警
- 系统设置指示灯用于直观指示呼叫来源,可采用两种方式:
- 12个LED分别对应12张床位,呼叫时点亮对应LED;
- 4个LED对应病房,呼叫时点亮病房LED,同时显示床位号。
- 蜂鸣器用于声音报警,要求:
- 呼叫触发后持续鸣叫或间歇鸣叫(根据需求设定);
- 直到清除键按下才停止。
- 为防止蜂鸣器长时间持续响造成噪音,可设置间歇鸣叫模式(例如500ms响、500ms停),但题目要求“持续报警提醒护士注意呼叫”,因此可默认持续或高占空比间歇。
2.5 清除键功能
- 护士站设置清除键(CLEAR),医护人员在处理完呼叫后按下清除键完成复位。
- 清除动作包括:
- 清除当前呼叫信息(床位号归零);
- 关闭指示灯;
- 停止蜂鸣器;
- 显示屏恢复待机状态。
- 清除键也需要消抖处理,避免误操作或重复触发。
2.6 系统快速响应与可靠性要求
- 呼叫系统属于实时性较高的安全相关设备,要求响应迅速、误触发少、掉电后状态明确。
- 软件设计需满足:
- 键盘扫描周期短(一般10ms~20ms即可);
- 消抖时间合理(20ms左右);
- 呼叫锁存可靠;
- 在蜂鸣器工作与显示刷新过程中仍能及时检测清除键。
- 硬件设计需满足:
3 系统电路设计
3.1 电路总体结构与设计思路
- 本系统的电路结构可分为“控制核心 + 输入 + 输出显示/报警 + 电源保护”四大部分:
- AT89S51最小系统:提供稳定运行平台;
- 矩阵键盘输入:12个床位呼叫按键;
- 显示与声光输出:显示屏、LED、蜂鸣器;
- 清除键输入:护士站复位操作;
- 电源模块:5V供电、滤波与保护。
- 由于51单片机是典型的8位MCU,IO驱动能力有限,蜂鸣器与多路LED通常需要驱动电路(如三极管/ULN2003)实现电流放大,避免直接由单片机供电导致IO口过载或电压跌落。
- 矩阵键盘输入线路较长或环境干扰较大时,容易出现误触发,因此需要上拉电阻、滤波电容以及软件消抖。
3.2 AT89S51单片机最小系统模块
3.2.1 核心功能
- 单片机最小系统是整个呼叫系统的控制中心,负责:
- 读取矩阵键盘与清除键
- 处理按键映射生成床位号
- 更新显示内容
- 控制LED指示灯与蜂鸣器
- 管理系统状态(待机/呼叫/报警)
- AT89S51具有典型的8051资源:
- 选用AT89S51的优势是成熟稳定、成本低、资料丰富,适合教学实验和中小型控制系统。
3.2.2 时钟电路
- 时钟电路为MCU提供系统时钟,常用12MHz晶振(兼容延时与串口波特率计算)。
- 晶振两端需接入两个小电容(通常22pF左右)作为负载电容,保证振荡稳定。
- 时钟对扫描周期与定时器精度影响较大,若要求严格响应时间,应选择稳定晶振并保证PCB走线短。
3.2.3 复位电路
- 上电复位确保系统通电后进入确定状态。
- 常用RC复位:RST脚外接电容与电阻,上电时产生高电平复位脉冲。
- 可增加手动复位按键,便于调试或故障恢复。
3.2.4 去耦与抗干扰
- 单片机VCC与GND之间必须放置0.1uF去耦电容,紧靠芯片引脚。
- 系统电源入口建议加电解电容(10uF~100uF),抵抗瞬态电流波动。
- 蜂鸣器与LED同时工作时可能造成电源波动,去耦与滤波有助于防止MCU误复位。
3.3 3×4矩阵键盘输入模块
3.3.1 矩阵键盘结构与优点
- 3×4矩阵键盘可实现12个按键输入,仅需7根IO线,相比12个独立按键节省大量IO口资源。
- 矩阵键盘适合本系统“12床位呼叫”需求,映射关系直观:
- 行数=3可对应床号(1~3床)
- 列数=4可对应房号(1~4房)
- 这种映射方式便于护士站显示转换,例如:
- 行1列1 = 1房1床
- 行3列4 = 4房3床
3.3.2 上拉与输入保护
- 通常列线设置为输入并上拉(使用内部上拉或外部上拉电阻),行线为输出扫描。
- 当按键按下时,输出低电平的行线会通过按键把某列拉低,从而被检测到。
- 若线缆较长或环境干扰较大,建议:
- 列输入加串联限流电阻(几十欧到几百欧)
- 加小电容形成RC滤波(如0.01uF~0.1uF)
- 软件中做多次确认。
3.3.3 消抖电路与消抖策略
- 按键机械抖动一般持续5ms~20ms,如果不消抖,系统可能误认为多次按下。
- 本系统建议采用软件消抖:检测到按键后延时20ms再次确认。
- 对于呼叫按键,为避免短按与抖动影响呼叫锁存,确认后直接锁存呼叫状态。
3.4 显示模块(护士站显示屏)
3.4.1 显示方案选择
- 显示模块可以采用数码管或LCD1602:
- 数码管显示简单、成本低,但显示信息有限;
- LCD1602可显示文字与更清晰的床位信息,适合护士站。
- 在病房呼叫系统中,显示清晰直观非常重要,因此推荐LCD1602。
- 若采用数码管,可使用动态扫描或使用驱动芯片减少IO口占用,但要注意动态扫描与键盘扫描的时间分配。
3.4.2 LCD1602接口设计(典型4位模式)
- LCD1602的控制线包括RS、RW、EN与数据线D4~D7(4位模式)。
- RW可直接接地(只写不读),减少一根IO占用。
- LCD背光需要限流或驱动电路,避免直接从MCU口供电。
3.4.3 显示内容规划
- 待机界面:
- 第一行显示“WARD CALL SYS”
- 第二行显示“READY…”
- 呼叫界面:
- 第一行显示“CALL FROM:”
- 第二行显示“R1 B2”或“ROOM1 BED2”
- 清除后恢复待机界面。
3.5 指示灯模块(床位指示)
3.5.1 指示灯设计方式
- 指示灯用于直观提示呼叫位置,常见两种实现:
- 12个LED对应12床位(最直观)
- 4个LED对应4病房(节省硬件)
- 本题强调“相应指示灯亮起”,通常理解为每床位一个指示灯更符合需求。
- 若使用12个LED,IO口可能不足,建议使用:
3.5.2 LED驱动与限流
- 每个LED必须串联限流电阻(一般220Ω~1kΩ)。
- 若LED数量多,单片机直接驱动会导致总电流过大,应采用驱动芯片或三极管扩流。
- 若使用ULN2003,LED可接VCC,通过ULN2003下拉点亮,连接方便且具备一定抗干扰能力。
3.6 蜂鸣器报警模块
3.6.1 蜂鸣器类型选择
3.6.2 驱动电路
- 蜂鸣器电流通常大于单片机IO口驱动能力,必须使用三极管或MOSFET驱动:
- IO口输出高电平驱动三极管导通;
- 蜂鸣器接VCC,三极管下拉驱动。
- 若蜂鸣器为电磁型,需要并联续流二极管抑制反向电动势。
- 蜂鸣器与LED同时动作时应注意电源滤波,避免噪声导致显示异常或复位。
3.7 清除键模块(护士站复位)
3.7.1 清除键电路与要求
- 清除键属于系统关键控制键,必须可靠。
- 清除键通常采用上拉输入,按下接地产生低电平。
- 清除键需要软件消抖,且在报警状态下应优先响应,保证护士能够立即停止报警。
3.8 电源模块与系统可靠性设计
3.8.1 电源结构
- 系统通常采用5V直流供电,可由适配器或稳压模块提供。
- 若使用12V适配器,可用7805或DC-DC模块降压到5V。
- 电源输出必须能提供足够电流驱动蜂鸣器与多路LED。
3.8.2 去耦、滤波与保护
4 程序设计
4.1 软件总体架构与设计目标
- 软件需满足“响应迅速、显示准确、报警可靠、可清除复位”的核心目标。
- 程序模块划分如下:
- 系统初始化模块
- 矩阵键盘扫描模块(12路呼叫)
- 清除键扫描模块
- 呼叫状态管理模块(锁存与优先级)
- LED控制模块
- 蜂鸣器控制模块
- 显示模块(LCD1602驱动与显示更新)
- 系统状态可定义为:
- IDLE:无呼叫待机
- CALLING:有呼叫锁存并报警
- 本系统最基本版本只支持“单个呼叫锁存”(即一次只显示一个床位),如果希望支持多床位同时呼叫,可扩展为队列或位图记录,但题目要求主要是显示具体床位号,因此默认实现“先来先显示,清除后再接收下一呼叫”,或实现“最新呼叫覆盖旧呼叫”。为了护理实际需求,推荐“呼叫队列”扩展,但不强制。
4.2 系统初始化模块
4.2.1 初始化内容
- IO口初始化:
- 行输出、列输入上拉
- 蜂鸣器输出
- LED输出(或移位寄存器接口)
- 清除键输入上拉
- LCD1602初始化:设置显示模式、清屏
- 定时器初始化:用于1ms或10ms系统节拍(用于按键扫描与蜂鸣器节奏控制)
- 变量初始化:当前床位号=无,报警状态=关闭
4.2.2 初始化代码示例
#include <REGX51.H>
void IO_Init(void);
void LCD_Init(void);
void Timer0_Init_1ms(void);
void System_Init(void)
{
IO_Init();
LCD_Init();
Timer0_Init_1ms();
}
4.3 矩阵键盘扫描模块(3×4键盘)
4.3.1 扫描原理与映射
- 扫描采用逐行置低法:
- 先将行线全部置高;
- 依次将某一行置低;
- 读取列线电平判断按键。
- 将扫描得到的行号row(02)与列号col(03)映射为床位号:
- 病房号 = col + 1
- 床位号 = row + 1
- 总床位编号(1~12)= col*3 + row + 1
- 该映射方式与题目要求“4病房×3床位”非常匹配。
4.3.2 软件消抖策略
- 第一次检测到按键按下后延时20ms再次确认。
- 若确认仍按下,则判定有效并返回键值。
- 在呼叫锁存状态下,可选择忽略新的呼叫或记录多个呼叫。
4.3.3 扫描代码示例
// 假设:P1.0~P1.2 为行输出,P1.4~P1.7 为列输入
sbit R0 = P1^0;
sbit R1 = P1^1;
sbit R2 = P1^2;
sbit C0 = P1^4;
sbit C1 = P1^5;
sbit C2 = P1^6;
sbit C3 = P1^7;
void DelayMs(unsigned int ms);
unsigned char KeyScan_3x4(void)
{
unsigned char row, col;
// 默认无按键
if(C0 && C1 && C2 && C3) return 0xFF;
// 逐行扫描
for(row = 0; row < 3; row++)
{
R0 = R1 = R2 = 1;
if(row == 0) R0 = 0;
if(row == 1) R1 = 0;
if(row == 2) R2 = 0;
// 读取列
if(!C0 || !C1 || !C2 || !C3)
{
DelayMs(20); // 消抖
if(!C0) col = 0;
else if(!C1) col = 1;
else if(!C2) col = 2;
else if(!C3) col = 3;
else continue; // 抖动导致恢复,继续扫描
// 再次确认仍按下
if((col==0 && !C0) || (col==1 && !C1) || (col==2 && !C2) || (col==3 && !C3))
{
// 返回键值 0~11
return (col * 3 + row);
}
}
}
return 0xFF;
}
4.4 清除键扫描模块
4.4.1 功能说明
- 清除键用于取消当前呼叫。
- 清除键的扫描需要更高优先级,建议每次主循环都扫描,或在定时器中断中扫描。
- 同样需要消抖确认。
4.4.2 清除键代码示例
sbit KEY_CLR = P3^2; // 清除键输入,低电平有效
bit ClearKey_Pressed(void)
{
if(KEY_CLR == 0)
{
DelayMs(20);
if(KEY_CLR == 0) return 1;
}
return 0;
}
4.5 呼叫状态管理模块(锁存逻辑)
4.5.1 状态变量设计
- 设计一个系统状态:
g_callActive:是否存在呼叫g_callIndex:床位索引0~11g_room:房号1~4g_bed:床号1~3
- 当系统处于呼叫状态时:
- 蜂鸣器开启
- 指示灯点亮
- 显示锁存床位信息
- 清除键按下后恢复待机。
4.5.2 锁存逻辑代码示例
bit g_callActive = 0;
unsigned char g_callIndex = 0xFF;
unsigned char g_room = 0, g_bed = 0;
void Call_Set(unsigned char idx)
{
g_callActive = 1;
g_callIndex = idx;
g_room = (idx / 3) + 1;
g_bed = (idx % 3) + 1;
}
void Call_Clear(void)
{
g_callActive = 0;
g_callIndex = 0xFF;
g_room = 0;
g_bed = 0;
}
4.6 LED控制模块
4.6.1 LED输出方式
- 若直接用IO口驱动12个LED,IO可能不足,且电流限制较大。
- 推荐使用74HC595级联输出12位或16位LED控制:
- 单片机用3根线控制SER、SRCLK、RCLK
- 595输出接LED(串联限流电阻)
- 需要扩流可再接ULN2003。
- 程序中维护一个16位LED位图变量,某床位呼叫则点亮对应位。
4.6.2 LED控制代码示例(位图方式)
unsigned int g_ledMask = 0x0000;
void LED_UpdateMask(unsigned char idx)
{
g_ledMask = 0x0000;
if(idx <= 11)
{
g_ledMask = (1U << idx);
}
LED_ShiftOut16(g_ledMask); // 通过74HC595输出
}
void LED_AllOff(void)
{
g_ledMask = 0x0000;
LED_ShiftOut16(g_ledMask);
}
4.7 蜂鸣器控制模块
4.7.1 蜂鸣器控制策略
- 题目要求蜂鸣器持续报警,可直接置位蜂鸣器输出为常开。
- 也可以采用间歇报警减少噪声,但仍保持持续提醒效果。
- 建议实现“持续鸣叫 + 可选间歇模式”,方便后续扩展。
4.7.2 蜂鸣器代码示例
sbit BUZZ = P3^7;
void Buzzer_On(void)
{
BUZZ = 1;
}
void Buzzer_Off(void)
{
BUZZ = 0;
}
4.8 显示模块程序设计(LCD1602)
4.8.1 显示更新逻辑
- 待机状态:显示系统标题与READY。
- 呼叫状态:显示CALL FROM与房号床号。
- 清除后恢复待机。
4.8.2 显示代码示例
void Display_Standby(void)
{
LCD_SetCursor(0,0);
LCD_Print("WARD CALL SYS ");
LCD_SetCursor(0,1);
LCD_Print("READY... ");
}
void Display_Call(unsigned char room, unsigned char bed)
{
LCD_SetCursor(0,0);
LCD_Print("CALL FROM: ");
LCD_SetCursor(0,1);
LCD_Print("ROOM ");
LCD_PrintNum(room);
LCD_Print(" BED ");
LCD_PrintNum(bed);
LCD_Print(" ");
}
4.9 定时器与系统调度模块
4.9.1 定时器用途
- 定时器可用于:
- 生成系统节拍(1ms或10ms)
- 实现蜂鸣器间歇鸣叫(若采用)
- 提供软件延时基准(替代空循环)
- 为了保证键盘扫描迅速与显示稳定,可采用定时器中断做节拍,主循环根据标志执行扫描与更新。
4.9.2 定时器示例(1ms中断标志)
volatile bit g_flag10ms = 0;
void Timer0_ISR(void) interrupt 1
{
static unsigned char cnt = 0;
TH0 = 0xFC;
TL0 = 0x18; // 12MHz下约1ms
cnt++;
if(cnt >= 10)
{
cnt = 0;
g_flag10ms = 1;
}
}
5 主程序流程设计与实现
5.1 主循环整体流程
- 系统初始化 → 显示待机界面。
- 循环执行以下逻辑:
- 扫描清除键(优先级最高)
- 若有呼叫状态:保持蜂鸣器与LED,显示锁存信息
- 若无呼叫状态:扫描矩阵键盘
- 检测到有效按键:锁存床位信息并进入呼叫状态
- 清除后恢复待机继续扫描。
5.2 主程序代码示例
int main(void)
{
System_Init();
Display_Standby();
LED_AllOff();
Buzzer_Off();
while(1)
{
// 优先处理清除键
if(ClearKey_Pressed())
{
Call_Clear();
LED_AllOff();
Buzzer_Off();
Display_Standby();
}
// 若无呼叫,扫描矩阵键盘
if(!g_callActive)
{
unsigned char key = KeyScan_3x4();
if(key != 0xFF)
{
Call_Set(key);
LED_UpdateMask(key);
Buzzer_On();
Display_Call(g_room, g_bed);
}
}
else
{
// 呼叫锁存状态:保持声光与显示
Buzzer_On();
}
}
}
6 系统响应速度与可靠性保障分析
6.1 响应速度设计
- 矩阵键盘扫描周期决定系统响应速度。若主循环中每次都扫描,响应可达到几十毫秒以内。
- 消抖时间一般为20ms,因此按键从按下到确认的响应时间约为20~40ms,属于“响应迅速”范围。
- LCD显示更新通常在毫秒级完成,但为了避免频繁写LCD造成闪烁,可以仅在状态变化时刷新显示。
6.2 抗干扰与误触发防护
- 软件层:消抖确认、按键释放检测(可选)、锁存机制避免重复触发。
- 硬件层:
- 输入上拉稳定电平
- RC滤波抑制毛刺
- 电源去耦防止蜂鸣器启动导致复位
- 若应用环境电磁干扰强,可增加:
6.3 呼叫信息处理策略讨论
- 本系统基础实现为“单呼叫锁存”,优点是简单、显示清晰;缺点是无法同时处理多床位呼叫。
- 若需要扩展多呼叫处理,可采用位图队列:
- 使用12位bit记录每床位是否呼叫
- 显示模块循环显示未清除的床位
- 清除键可清除当前显示床位或清除全部
- 即使扩展多呼叫队列,核心电路与键盘结构仍可保持不变,仅需增加软件逻辑。
7 系统总结
7.1 设计成果总结
阅读全文
285