一、设计背景
随着社会的发展和技术的进步,安全问题越来越受到重视。各种工业设施、家庭、商业场所以及公共场所的安全保障成为了重点。报警器作为安全防护系统的重要组成部分,在预防和及时应对各种突发事件中发挥着至关重要的作用。传统的报警器通常在功能上比较单一,仅能处理一种类型的警报事件,难以满足复杂环境下的多样化需求。因此,基于51单片机的多路报警器设计应运而生,以满足现代安全防护系统的需求。
51单片机因其结构简单、功能强大、价格低廉以及开发工具丰富等优点,广泛应用于各种电子项目中。特别是在需要实现多种功能和处理复杂逻辑的场合,51单片机展现了其独特的优势。基于51单片机的多路报警器能够通过其强大的计算和控制能力,支持多种传感器输入,实现多路报警功能,这对于提升报警系统的智能化水平和灵活性具有重要意义。
本设计中,51单片机充当了核心控制器的角色,通过IO口与各个功能模块相连接。4*4矩阵键盘负责模拟16路报警信号,当矩阵键盘某个按键按下时,视为该路触发报警,此时会通过IO口电平的变化通知单片机,单片机会记录发生报警的路数,通过数码管显示当前的报警路数并通过蜂鸣器进行报警提示。
软件系统采用C语言编写程序,包括显示程序,定时中断服务,延时程序等,并在KEIL5中调试运行,硬件系统利用PROTEUS8.11强大的功能来实现,简单切易于观察,在仿真中就可以观察到实际的工作状态。
二、实现功能
以51单片机为控制核心,设计一种多路报警器。整个系统包括MCU、晶振电路、时钟电路、矩阵键盘、蜂鸣器控制电路以及数码管显示电路。该系统通过矩阵键盘不同按键按下模拟不同路数触发报警,利用共阳数码管实时显示发生报警的路数,并通过蜂鸣器进行报警提示。可具体实现以下功能:
(1)使用4*4矩阵键盘模拟16路报警信号。
(2)当某一个按键按下时,即视为该路发生报警,两位数码管显示当前发生报警的路数,并且以方波驱动蜂鸣器实现报警。
(3)16路均未发生报警时,数码管显示00。
三、仿真演示
未运行仿真时,数码管不显示。
运行仿真后,进入非报警界面,此时未触发任何一路报警。
按下矩阵键盘的按键1,表示第1路触发报警,数码管显示01,蜂鸣器“滴答”3声进行报警提示。
按下矩阵键盘的按键6,表示第6路触发报警,数码管显示06,蜂鸣器“滴答”3声进行报警提示。
按下矩阵键盘的按键14,表示第14路触发报警,数码管显示14,蜂鸣器“滴答”3声进行报警提示。
按下矩阵键盘的按键16,表示第16路触发报警,数码管显示16,蜂鸣器“滴答”3声进行报警提示。
四、源程序(部分)
#include "reg52.h"
sbit wei0=P3^2;
sbit wei1=P3^3;
sbit Beep=P0^0;//蜂鸣器
unsigned char a=0;
unsigned char disCode[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数码管段码 0~9
unsigned char Num=0,number=0;//号码
unsigned int Jishu=0,BeepC=0; //时间计数加
void DisplaySMG();//数码管延时
bit BeepFlag=0;
void Delay1ms(unsigned int n)
{
unsigned char i, j;
for (; n>0; n--)
for(i=0;i<10;i++)
for(j=0;j<33;j++);
}
/**定时器初始化函数**/
void Tim0_Init()
{
TMOD=0x01; //设定定时器状态
TH0=0xfc; //1ms
TL0=0x18; //赋初值
ET0=1; //打开T0中断允许开关
EA=1; //打开中断总开关
}
void disPlay(unsigned char num) //数码管、led显示函数
{
P2 = 0xff; //消除重影
wei0=1;wei1=0; //位码输出
P2 = disCode[num/10]; //段码输出
Delay1ms(1); //增加显示时间,防止显示过暗
P2 = 0xff; //消除重影
wei1=1;wei0=0; //位码输出
P2 = disCode[num%10]; //段码输出
Delay1ms(1); //增加显示时间,防止显示过暗
}
void SMGdelay(unsigned int t)
{
while(t--)
{
disPlay(a); //数码管显示函数
}
}
void keycheckdown() /* 反转法键盘扫描 */
{
short temp1,temp2,temp;
P1=0xf0; /* 输入行值(或列值) */
SMGdelay(20); /* 延时 */
temp1=P1; /* 读列值(或行值) */
P1=0xff;
SMGdelay(20); /* 延时 */
P1=0x0f; /* 输入列值(或行值) */
SMGdelay(20); /* 延时 */
temp2=P1; /* 读行值(或列值) */
P1=0xff;
temp=(temp1&0xf0)|(temp2&0xf); /* 将两次读入数据组合 */
switch(temp) /* 通过读入数据组合判断按键位置 */
{
case 0x7e :a=4;BeepFlag=1;TR0=1;break;// 按键4
case 0x7d :a=3;BeepFlag=1;TR0=1;break; // 按键3
case 0x7b :a=2;BeepFlag=1;TR0=1;break; // 按键2
case 0x77 :a=1;BeepFlag=1;TR0=1;break; // 按键1
case 0xbe :a=8;BeepFlag=1;TR0=1;break;// 按键8
case 0xbd :a=7;BeepFlag=1;TR0=1;break; // 按键7
case 0xbb :a=6;BeepFlag=1;TR0=1;break; // 按键6
case 0xb7 :a=5;BeepFlag=1;TR0=1;break; // 按键5
case 0xde :a=12;BeepFlag=1;TR0=1;break;// 按键12
case 0xdd :a=11;BeepFlag=1;TR0=1;break; // 按键11
case 0xdb :a=10;BeepFlag=1;TR0=1;break; // 按键10
case 0xd7 :a=9;BeepFlag=1;TR0=1;break; // 按键9
case 0xee :a=16;BeepFlag=1;TR0=1;break;// 按键16
case 0xed :a=15;BeepFlag=1;TR0=1;break;// 按键15
case 0xeb :a=14;BeepFlag=1;TR0=1;break;// 按键14
case 0xe7 :a=13;BeepFlag=1;TR0=1;break;// 按键13
}
}
//主函数
void main()
{
Tim0_Init();
while(1)
{
keycheckdown();
disPlay(a);
}
}
/**定时器T0工作函数**/
void Time0() interrupt 1
{
TH0=0xfc; //1ms
TL0=0x18; //重新赋初值
Jishu++; //计数加
if(Jishu==500)//计数大于5000
{
Jishu=0; //数据清零
if(BeepFlag==1)
{
Beep=~Beep;
BeepC++;
if(BeepC==6)
{
BeepC=0;
BeepFlag=0;
TR0=0;
}
}
}
}
仿真源文件及源程序百度网盘链接:https://pan.baidu.com/s/1mQ3l7uxPm8QCPjz71WfQFA
提取码:yevc