标题:
51单片机做的密码锁程序及proteus仿真
[打印本页]
作者:
51黑ff
时间:
2016-9-25 15:15
标题:
51单片机做的密码锁程序及proteus仿真
0.png
(39.3 KB, 下载次数: 54)
下载附件
2016-9-25 15:12 上传
简单的51单片机做的密码锁,带矩阵键盘,用数码管来显示,初始密码111111,
0.png
(51.13 KB, 下载次数: 67)
下载附件
2016-9-25 15:15 上传
所有资料下载:
51密码锁改.zip
(147.63 KB, 下载次数: 58)
2016-9-25 15:14 上传
点击文件名下载附件
下载积分: 黑币 -5
下面是源程序:
#include <reg51.h>
typedef unsigned char uchar;
typedef unsigned int uint;
//键盘子程序相关说明
#define BLANKCHAR 10 //定义空白常量
#define PCHAR 11 //定义字符 P 常量(等待用户输入密码)
#define OPENCHAR 12 //定义开锁字符 |— 常量
#define ALARMCHAR 13 //定义字符 A 常量(密码多次错误警告)
#define LINECHAR 14 //定义字符 - 常量
#define BACKKEY 0X0D //定义退格按键常量
#define ENTERKEY 0X0F //定义确认键常量
#define LOCKKEY 0X0E //定义闭锁键常量
#define NO_KEY 20 //定义无按键返回值
//定义按键扫描码表,按键扫描时,4位列线和4位行线组成字节数据表
uchar code KEYCODE[] = {0XEE,0XDE,0XBE,0X7E, // 0 1 2 3
0XED,0XDD,0XBD,0X7D, // 4 5 6 7
0XEB,0XDB,0XBB,0X7B, // 8 9
0XE7,0XD7,0XB7,0X77};// back lockkey enter
uchar KeyPre; //保存上次扫描按键的键值
uchar KeyUp;//用于控制按键去抖动操作。1:扫描时消抖 2:等待释放 3:释放时消抖
#define LEDPORT P0 //定义显示器段码输出端口
#define LEDCON P1 //定义显示器位控制端口
#define KEYPORT P2 //定义键盘端口
sbit ALARMCON = P3^3; //定义报警控制引脚
sbit LOCKCON = P3^5; //定义电子锁控制引脚
uchar code SEGCODE[] =
{0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,//0...9的共阳极段码
0XFF,//不显示
0X8C,//显示字符P(等待用户输入密码)
0X8F,//|-的共阳极段码(开锁)
0X88,//字符A
0XBF,//字符-
0X9f,//返回字符
};
//定义LED位码控制码
uchar code BITCODE[6] = {0XC1,0XC2,0XC4,0XC8,0XD0,0XE0};
uchar DispBuf[6]; //保存显示的字符
bit DispNormal; //控制显示时,是正常显示还是闪烁显示
uchar DispCnt; //控制闪烁显示时的频率
#define SHORT_TIME 10 //蜂鸣器响200ms
#define LONG_TIME 100 //蜂鸣器响2s
#define LONGER_TIME 9000 //蜂鸣器响3min
bit AlarmEnable; //是否报警或声音提示
uint AlarmTime; //控制报警时间长度
uchar code PassWord[] = {1,1,1,1,1,1};//定义初始密码表
uchar PassInBuf[5]; //保存输入的密码字符
uchar PassPosi; //用户输入密码字符存放在PassInBuf[]的位置
bit TimerBit; //20ms定时时间到
uchar SysMode; //系统所处模式 0:输入密码模式 1:报警模式 2:开锁模式
uchar ErrorCnt; //用户连续输入密码出错次数
void Delay(int z)
{
uchar y;
int x;
for(x=z; x>0; x--)
for(y=255; y>0; y--);
}
/*********************************************************
*1、填充子程序负责将显示内容写入DisBuf和PassInBuf缓冲区,*
* 分为以下几个子程序。 *
* 函数Fill_Buf;使用特定字符填充DisBuf和PassInBuf。 *
* 函数Fill_Buf_P;将系统闭锁时的显示信息写入缓冲区。 *
* 函数Fill_Buf_O;将系统开锁时的显示信息写入缓冲区。 *
* 函数Fill_Buf_A;将系统报警时的显示信息写入缓冲区。 *
*********************************************************/
/**********函数Fill_Buf**************/
void Fill_Buf(uchar FillChar)
{
uchar i;
for (i=0; i<6; i++)
{
DispBuf[i] = FillChar;//用字符FillChar填充DispBuf[i]
PassInBuf[i] = FillChar;//用字符FillChar填充PassInBuf[i]
}
}
void Fill_Buf_P()
{
Fill_Buf(BLANKCHAR);//DispBuf[1..5] = ' '
DispBuf[0] = PCHAR;//DispBuf[0] = 'p'
LEDPORT = SEGCODE[PCHAR]; //显示P
LEDCON = BITCODE[5];//在最后一个数码管显示
}
void Fill_Buf_O()
{
Fill_Buf(BLANKCHAR);
DispBuf[0] = OPENCHAR;// DispBuf[0] = '|-'
LEDPORT = SEGCODE[OPENCHAR]; //显示'|-'
LEDCON = BITCODE[5];//在最后一个数码管显示
}
void Fill_Buf_A()
{
Fill_Buf(BLANKCHAR);
DispBuf[0] = ALARMCHAR;// DispBuf[0] = 'A'
LEDPORT = SEGCODE[ALARMCHAR]; //显示'A'
LEDCON = BITCODE[5];//在最后一个数码管显示
}
/*********************************************************
*2、缓冲区显示子程序负责将显示内容写入DisBuf和PassInBuf *
* 缓冲区,分为以下几个子程序。 *
* 函数Disp_Led_Sin;在某个LED数码管上显示一个字符。 *
* 函数Disp_Led_OFF;关闭数码管显示。 *
* 函数Disp_Led_All;将DispBuf缓冲区的内容显示。 *
* 函数Disp_Led;当系统处于不同模式时,刷新显示器。 *
*********************************************************/
void Disp_Led_Sin(uchar DispChar, uchar DispPosi)
{
LEDPORT = SEGCODE[DispChar];//输出显示段码
LEDCON = BITCODE[DispPosi];//输出显示位码
Delay(500);
LEDCON = 0X00;//关闭显示器
}
/*********启动报警函数***********/
void Sys_Speaker(uint stime)
{
AlarmEnable = 1;//允许报警
AlarmTime = stime;//报警时间长短
}
/*********系统报警函数**********/
void Sys_Alarm()
{
if (AlarmEnable == 1) //允许报警
{
ALARMCON = 0;//报警
AlarmTime--;
if (AlarmTime == 0) //停止报警时间到
{
AlarmEnable = 0;
ALARMCON = 1;
if (SysMode == 1) //报警发生在模式1.要返回模式0
{
SysMode = 0;
Fill_Buf_P();//显示P
}
}
}
}
/*********按键检测子程序**************/
uchar Find_Key()
{
uchar KeyTOP, i;
KEYPORT = 0XF0;//行线输出全0,列线输出全1
KeyTOP = KEYPORT;//读按键端口值
if(KeyTOP == 0XF0)
return NO_KEY;
KEYPORT = KeyTOP | 0X0F;//列线输出,行线输入
KeyTOP = KEYPORT;
for (i=0; i<16; i++)
{
if(KeyTOP == KEYCODE[i])//根据按键端口扫描值,查找按键值
return i;//返回按键值
else if(i >= 15)
{
i = NO_KEY;
return i;
}
}
}
/****************按键扫描函数**************/
uchar Scan_Key()
{
uchar KeyTOP;
KeyTOP = Find_Key();//接收按键检测的返回值
if (KeyTOP != NO_KEY)
{
Delay(100);
if (KeyTOP != NO_KEY)
KeyPre = KeyTOP;
while(KeyTOP == Find_Key());
return KeyPre;
}
else
return NO_KEY;
}
/***************按键处理子程序**************/
void Key_Process(uchar Key)
{
uchar i;
if (Key == NO_KEY)
return;//无按键,不处理
switch(SysMode)
{
case 0://输入密码
switch(Key)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
Disp_Led_Sin(Key,PassPosi);
PassInBuf[PassPosi] = Key;//保存用户输入的密码
if (PassPosi<5)
PassPosi++;//调整密码输入位置
Sys_Speaker(SHORT_TIME);//发按键提示音
break;
case 20:break;
case BACKKEY:
DispBuf[PassPosi] = BLANKCHAR;//显示空键
PassInBuf[PassPosi] = BLANKCHAR;//清除当前位置的密码
if (PassPosi>0)
{
PassPosi--;//调整显示位置
Disp_Led_Sin(15,5);
}
Sys_Speaker(SHORT_TIME);//发按键提示音
break;
case ENTERKEY:
for (i=0; i<5; i++)//比较用户密码是否与预设密码一致
{
if (PassInBuf[i] != PassWord[i])
break;
}
if (i>=5)//输入密码正确
{
Fill_Buf_O();//显示开锁状态
PassPosi = 0;
LOCKCON = 1;//开锁
ErrorCnt = 0;
Sys_Speaker(LONG_TIME);//发长提示音
SysMode = 2;//转模式2
}
else
{
ErrorCnt++;
if(ErrorCnt>2)//超过3次
{
ErrorCnt = 0;
Fill_Buf_A();//显示报警状态
PassPosi = 0;
Sys_Speaker(LONGER_TIME);//发报警音
SysMode = 1;
}
else //少于3次,重新输入
{
Fill_Buf_P();
PassPosi = 0;
Sys_Speaker(LONG_TIME);//发长提示音
}
}
break;
case LOCKKEY://闭锁键
Fill_Buf_P();
PassPosi = 0;
Sys_Speaker(SHORT_TIME);//发短提示音
break;
}
break;
case 2://开锁状态
if (Key == LOCKKEY)//用户按动闭锁按键
{
Fill_Buf_P();
SysMode = 0;
LOCKCON = 0;//闭锁
Sys_Speaker(SHORT_TIME);
}
break;
}
}
void Init_Timer()
{
TMOD &= 0XF0;
TMOD |= 0X01;
TR0 = 0;
TH0 = (65536-20000) / 256;
TL0 = (65536-20000) % 256;
TR0 = 1;
ET0 = 1;
}
void Timer0() interrupt 1
{
TR0 = 0;
TH0 = (65536-20000) / 256;
TL0 = (65536-20000) % 256;
TR0 = 1;
TimerBit = 1;//20ms定时时间到
}
void Init_System()
{
PassPosi = 1;
LOCKCON = 0; //闭锁
Init_Timer();
Fill_Buf_P();
EA = 1;
}
void main()
{
uchar KeyTemp;
Init_System();
PassPosi = 0;
while(1)
{
if(TimerBit == 1)
{
Sys_Alarm();//报警函数
KeyTemp = Scan_Key();//按键扫描
Key_Process(KeyTemp);//按键处理
TimerBit = 0;
}
}
}
复制代码
作者:
123woscc
时间:
2017-6-19 09:21
谢谢楼主
作者:
哈哈哈哈膜拜
时间:
2017-6-19 14:40
谢谢楼主?
作者:
哈哈哈哈膜拜
时间:
2017-6-19 14:40
楼主万岁。。感谢感谢
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1