|
简单的51单片机做的密码锁,带矩阵键盘,用数码管来显示,初始密码111111,
所有资料下载:
51密码锁改.zip
(147.63 KB, 下载次数: 58)
下面是源程序:
- #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;
- }
- }
- }
复制代码
|
评分
-
查看全部评分
|