㈠ 单片机自锁程序
你的意思是K1按下,D1输出低电平,再按一次K1,D1输出高电平?
这……这里的按键检测就不需要使用延时了,使用while不用怕会阻塞后面的程序执行。事实在公司写程序,在检测按键时我从来不用延时,当然也不是使用这种while等待按键松开的方式。有兴趣可以一起研究一下,呵呵
#include<reg51.h>
#defineKEY1 (1<<0)
#defineKEY2 (1<<1)
#defineKEY3 (1<<2)
#defineKEY4 (1<<3)
#defineKEY5 (1<<4)
#defineKEY6 (1<<5)
sbitD1=P0^0;
sbitD2=P0^1;
sbitD3=P0^2;
sbitD4=P0^3;
sbitD5=P0^4;
sbitD6=P0^5;
voidmain(void)
{
while(1)
{
P1=0xff;
if(!(P1&KEY1))
{
D1=~D1;
while(!(P1&KEY1));
}
if(!(P1&KEY2))
{
D2=~D2;
while(!(P1&KEY2));
}
if(!(P1&KEY3))
{
D3=~D3;
while(!(P1&KEY3));
}
if(!(P1&KEY4))
{
D4=~D4;
while(!(P1&KEY4));
}
if(!(P1&KEY5))
{
D5=~D5;
while(!(P1&KEY5));
}
if(!(P1&KEY6))
{
D6=~D6;
while(!(P1&KEY6));
}
}
}
㈡ 求单片机密码锁源程序,C语言的
#include <reg52.h>
#include"键盘矩阵.h"
#include "delay_ms.h"
#include "矩阵键盘.h"
#include "i2c.h"
#include "1602.h"
#include "delay_ms.h"
#include "mima.h"
#define uchar unsigned char
#define uint unsigned int
#define A 0x0a //输入密码
#define B 0x0b //修改密码
#define D 0x0d //关锁
#define enter 0x0c //确认
#define backspace 0x0f //退格键
sbit baojing = P3^7; //蜂鸣器接口
sbit lock = P3^3;//锁信号
sbit set = P3^2;
uchar idata mima_5[6] = {1,2,3,4,5,6}; //初始密码
uchar flag_change;
uchar aa;//存放密码错误的次数,够三次报警
uchar bb;
uchar flag_t0;*/
void baoj1 ()//报警函数
{
int i;
for(i = 0;i < 5; i++)
{
baojing = 1;
delay_ms(5);
baojing = 0;
delay_ms(5);
}
}
void baoj()
{
uchar i;
for(i = 0; i < 10; i++)
}
void delay_ms(uint x)
{ int i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
void main()
{
uchar i=0;
uchar IIC_Password[10];
uchar IS_Valid_User=0;
P0=P1=P2=0XFF;
TMOD=0X02;
TH0=175;
TL0=175;
delay_ms(10);
}
㈢ 求51单片机C语言编的简易密码锁程序
首先得说明我这个可是自己原创手打的,但是没去仿真了,程序可能有错误,你自己修改下吧
#include<reg52.h>
typedef unsigned char uchar;
typedef unsigned int uint;
sbit key1=P0^0;
sbit key2=P0^1;
sbit key3=P0^2;
sbit key4=P0^3;
sbit wela=P2^0;//位锁存端
#define SMG P1
sbit LED=P3^0;//低电平亮
uchar code table[]={0x8d,0x86};//共阳数码管 P,E
uchar chushi_mima[]={2,1,3};
uchar shuru_mima[3];
uchar index;//控制输入密码的位数
uchar flag_3s=0;//3s标志位
uchar keydown;//确定按键变量
#define times 15//去抖时间15Ms
uchar key1_count,key2_count,key3_count,key4_count;
void init()
{
wela=0;
SMG=0xff;
TMOD=0x01;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
ET0=1;
EA=1;
TR0=1;
LED=1;
}
void main()
{
init();
while(1)
{
switch(keydown)
{
if(index>2)index=0;
case 1:
shuru_mima[index]=0;
index++;
break;
case 2:
shuru_mima[index]=1;
index++;
break;
case 3:
shuru_mima[index]=2;
index++;
break;
case 4:
shuru_mima[index]=3;
index++;
break;
}
flag_3s=0;
for(i=0;i<3;i++)
{
if(shuru_mima[i]==chushi_mima[i])
{
LED=0;
wela=1;
SMG=table[0];
if(flag_3s)
{
flag_3s=0;
wela=0;
}
}
else
{
LED=1;
wela=1;
SMG=table[1];
if(flag_3s)
{
flag_3s=0;
wela=0;
}
}
}
}
}
void timer0() interrupt 1
{
uchar count;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
if(++count>=600)
{
count=0;
flag_3s=1;
}
/*********1ms中断扫描按键(包含去抖程序)********/
if(!key1&&key1_count!=0)
{
key1_count--;
if(key1_count==0)
{
keydown=1;
}
}
else if(!key1) key1_count=times;
// key2,key3,key4你自己写吧
}
㈣ 单片机c语言密码锁程序
include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
#define KeyPort P1
sbit LATCH1=P2^2;//定义锁存使能端口 段锁存
sbit LATCH2=P2^3;// 位锁存
unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
unsigned char TempData[10]; //存储显示值的全局变量
unsigned char code password[8]={1,2,3,4,5,6,7,8};
//可以更改此密码做多组测试
void DelayUs2x(unsigned char t);//us级延时函数声明
void DelayMs(unsigned char t); //ms级延时
void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数
unsigned char KeyScan(void);//键盘扫描
unsigned char KeyPro(void);
void Init_Timer0(void);//定时器初始化
/*------------------------------------------------
主函数
------------------------------------------------*/
void main (void)
{
unsigned char num,i,j;
unsigned char temp[8];
bit Flag;
Init_Timer0();
while (1) //主循环
{
num=KeyPro();
if(num!=0xff)
{
if(i==0)
{
for(j=0;j<8;j++)//清屏
TempData[j]=0;
}
if(i<8)
{
temp[i]=dofly_DuanMa[num];//把按键值输入到临时数组中
for(j=0;j<=i;j++) //通过一定顺序把临时数组中
//的值赋值到显示缓冲区,从右往左输入
TempData[7-i+j]=temp[j];
}
i++; //输入数值累加
if(i==9)//正常等于8即可,由于我们需要空一个用于清屏,
//清屏时的按键不做输入值
{
i=0;
Flag=1;//先把比较位置1
for(j=0;j<8;j++)//循环比较8个数值,
//如果有一个不等 则最终Flag值为0
Flag=Flag&&(temp[j]==dofly_DuanMa[password[j]]);
//比较输入值和已有密码
for(j=0;j<8;j++)//清屏
TempData[j]=0;
if(Flag)//如果比较全部相同,标志位置1
{
TempData[0]=0x3f; // "o"
TempData[1]=0x73; // "p"
TempData[2]=0x79; // "E"
TempData[3]=0x54; // "n"
//说明密码正确,输入对应操作 显示"open"
}
else
{
TempData[0]=0x79; // "E"
TempData[1]=0x50; // "r"
TempData[2]=0x50; // "r"
//否则显示"Err"
}
}
}
}
}
/*------------------------------------------------
uS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
显示函数,用于动态扫描数码管
输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
如输入0表示从第一个显示。
Num表示需要显示的位数,如需要显示99两位数值则该值输入2
------------------------------------------------*/
void Display(unsigned char FirstBit,unsigned char Num)
{
static unsigned char i=0;
DataPort=0; //清空数据,防止有交替重影
LATCH1=1; //段锁存
LATCH1=0;
DataPort=dofly_WeiMa[i+FirstBit]; //取位码
LATCH2=1; //位锁存
LATCH2=0;
DataPort=TempData[i]; //取显示数据,段码
LATCH1=1; //段锁存
LATCH1=0;
i++;
if(i==Num)
i=0;
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
//TH0=0x00; //给定初值
//TL0=0x00;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
TH0=(65536-2000)/256; //重新赋值 2ms
TL0=(65536-2000)%256;
Display(0,8); // 调用数码管扫描
}
/*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char KeyScan(void) //键盘扫描函数,使用行列反转扫描法
{
unsigned char cord_h,cord_l;//行列值中间变量
KeyPort=0x0f; //行线输出全为0
cord_h=KeyPort&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
DelayMs(10); //去抖
if((KeyPort&0x0f)!=0x0f)
{
cord_h=KeyPort&0x0f; //读入列线值
KeyPort=cord_h|0xf0; //输出当前列线值
cord_l=KeyPort&0xf0; //读入行线值
while((KeyPort&0xf0)!=0xf0);//等待松开并输出
return(cord_h+cord_l);//键盘最后组合码值
}
}return(0xff); //返回该值
}
/*------------------------------------------------
按键值处理函数,返回扫键值
------------------------------------------------*/
unsigned char KeyPro(void)
{
switch(KeyScan())
{
case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值
case 0x7d:return 1;break;//1
case 0x7b:return 2;break;//2
case 0x77:return 3;break;//3
case 0xbe:return 4;break;//4
case 0xbd:return 5;break;//5
case 0xbb:return 6;break;//6
case 0xb7:return 7;break;//7
case 0xde:return 8;break;//8
case 0xdd:return 9;break;//9
case 0xdb:return 10;break;//a
case 0xd7:return 11;break;//b
case 0xee:return 12;break;//c
case 0xed:return 13;break;//d
case 0xeb:return 14;break;//e
case 0xe7:return 15;break;//f
default:return 0xff;break;
}
}
㈤ 求用51单片机控制的简单密码锁原理
还是原来学汇编的时候的程序了
今天整理看到了
送给有用的人
code_seg segment code
data_seg segment data
stack_seg segment idata
spk bit p1.3
rseg data_seg
frq:ds 1
tmp:ds 1
rseg stack_seg
stack:ds 20
cseg at 00000h
ljmp main
cseg at 0003h
ljmp zd
rseg code_seg
jmp main
PORTA EQU 8FFFH ;8255A口地址
PORTB EQU 9FFFH ;8255B口地址
PORTC EQU 0AFFFH ;8255C口地址
CADDR EQU 0BFFFH ;8255控制字地址
main: MOV A,#88H ;方式0
MOV DPTR,#CADDR
MOVX @DPTR,A
CLR P1.2
mov r0,#50h ;初始密码首地址
mov r1,#08h
szmm: mov @r0,#00h ;设置密码
inc r0
djnz r1,szmm
mov r2,#03h ;设置输入密码的次数
K:mov ie,#81h ;中断方式设置
mov tcon,#01h
k1:mov a,p1
clr p1.2 ;判断开关位置
mov r1,a
anl a,#03h
jz dmm
dec a
jz xianshi
dec a
jz xianshi
dec a
jz dmm
dmm: mov r3,#08h ;读密码 八位
mov r6,#80h ;闪动位控制
mov r0,#60h ;读入值的首地址
ll:acall display
acall KSI
jz ll
ACALL DISPLAY
acall KEYI
mov @r0,30h
inc r0
mov a,r6
rr a
mov r6,a
djnz r3,ll
pdmm:mov r1,#50h ;判断密码
mov r0,#60h
mov r3,#08h
cxpd:mov a,@r0
mov r4,a
mov a,@r1
subb a,r4
jnz baojin
inc r0
inc r1
djnz r3,cxpd
mov r0,#0ffh
god: mov r1,#0fh ;密码正确显示good
good: acall display1
djnz r1,good
djnz r0,god
mov a,p1
clr p1.2 ;判断是否改密码
anl a,#03h
jz gmm
dec a
jz xianshi
dec a
jz xianshi
dec a
jz dmm
jmp k1
baojin: mov ie,#00h ;报警
djnz r2,k3
mov r7,#0ffh
acall sg
jmp k
k3:mov r7,#0fh
acall sg
mov r5,#03h
jmp k
xianshi:mov r0,#0fh ;待机显示
as: mov r6,#00h
acall display
djnz r0, as
jmp k1
gmm:mov r3,#08h ;改密码
mov r6,#80h
mov r0,#50h
lty: acall display
acall KSI
jz lty
acall KEYI
MOV @R0,30H
inc r0
mov a,r6
rr a
mov r6,a
djnz r3,lty
jmp k1
sg:nop ;bao警子程序
ls:mov r6,#0ffh
lm: mov r5,#0ffh
djnz r5,$
cpl p1.3
djnz r6,lm
djnz r7,ls
mov p1,#0ffh
ret
zd: mov 30h,a ;复位程序
mov a,r6
rl a
mov r6,a
mov a,30h
inc r3
acall d1ms
acall d1ms
acall d1ms
acall d1ms
acall d1ms
acall d1ms
mov tcon,#01h
reti
KEYI: MOV 30h,#00H
MOV R4,#00H
ACALL DISPLAY
ACALL KSI
JNZ LK2
AJMP KEYI
LK2: MOV R1,#04H
MOV R2,#0FEH
MOV R4,#00H
LK4:MOV DPTR,#PORTC
MOV A,R2
MOVX @DPTR,A
NOP
NOP
MOVX A,@DPTR
JB ACC.4,LONE
MOV A,#00H
AJMP LKP
LONE:JB ACC.5,LTWO
MOV A,#04H
AJMP LKP
LTWO:JB ACC.6,LTHR
MOV A,#08H
AJMP LKP
LTHR:JB ACC.7,NEXT
MOV A,#0CH
LKP:
ADD A,R4
PUSH ACC
LK3:ACALL DISPLAY
ACALL KSI
JNZ LK3
POP ACC
MOV 30H,A
ret
NEXT:INC R4
MOV A,R2
JNB ACC.3,KND
RL A
MOV R2,A
DJNZ R1,LK4
KND:ret
KSI:MOV DPTR,#PORTC
MOV A,#00H
MOVX @DPTR,A
NOP
NOP
MOVX A,@DPTR
CPL A
ANL A,#0F0H
RET
display:mov r5,#02h ;显示
lool:mov r4,#0FFh
dplop: mov a,#0ffh ;取个位数
MOV A,#7fh;查个位数的7段代
MOV DPTR,#PORTA
MOVX @DPTR,A ;送出个位的7段代码
MOV DPTR,#PORTB
MOV A,r6
MOVX @DPTR ,A;开个位显示
acall d1ms ;显示162微秒
djnz r4,dplop ;循环执行250次
djnz r5,lool
mov r5,#02h
poop:mov r4,#0FFh
ppdd: mov a,#07fh ;取个位数
;查个位数的7段代
MOV DPTR,#PORTA
MOVX @DPTR,A ;送出个位的7段代码
MOV DPTR,#PORTB
MOV A,#00h
MOVX @DPTR ,A;开个位显示
acall d1ms ;显示162微秒
MOV DPTR,#PORTB
MOV A,#0FFH
MOVX @DPTR ,A;关闭个位显示,防止鬼影
djnz r4,ppdd ;循环执行250次
djnz r5,poop
ret
display1: mov r5,#08h
mov r4,#7fh
ww:mov a,r5
dec a
mov dptr,#sttab
MOVC A,@A+DPTR ;查个位数的7段代
MOV DPTR,#PORTA
MOVX @DPTR,A ;取个位数
;查个位数的7段代
MOV DPTR,#PORTB
MOV A,r4
MOVX @DPTR ,A;开个位显示
acall d1ms ;显示162微秒
MOV DPTR,#PORTB
MOV A,#0ffH
MOVX @DPTR ,A;关闭个位显示,防止鬼影
mov a,r4
rr a
mov r4,a
djnz r5,ww
ret
;2+2X80=162微秒,延时按12MHZ计算
D1MS: MOV R7,#150
DJNZ R7,$
ret
sttab: db 3dh,5ch,5ch,3fh,40h,40h,40h,40h
end
㈥ 51单片机设计一个简易6位密码锁 keil
简易密码锁 基础部分:设计一个简易密码
比较奥学校奥
㈦ 单片机q求个51单片机的程序,最简单的密码锁就行4位的 密码是固定在程序里的就行。 当输入的四位数正确
数码管显示+按键输入。
㈧ 求一个51单片机的简易密码锁程序
你好!
从你的功能要求来看,这个密码锁不简易,功能很强很全了;
你这个是仿真验证程序还是要做出实物来验证程序。
采用仿真软件模拟出的密码锁
㈨ 用单片机做个简单的密码锁设计~~~~~~~~
物品清单
ATMAGE16单片机(内部有EEPROM)
16个按键(十个数字键,加确认、取消,还有设置、保存、开锁、关锁)
三位数码管加几个LED
驱动数码管的三极管,电阻
104电容若干
5V电源(7805也可以)
程序大概就是:
设置密码,要求输入上次密码,正确后,输入新密码,确认,保存
开锁,输入密码,正确,点灯/错误,点灯
㈩ 关于51单片机C语言 数码管 4*4按键 简单的密码锁 请您帮助一下
密码锁(掉电保护功能)
功能键
S6---S15 数字键0-9
S16---更改密码 S17---更改密码完毕后确认
S18---重试密码、重新设定 S19---关闭密码锁
初始密码:000000 密码位数:6位
注意:掉电后,所设密码会丢失,重新上点时,密码恢复为原始的000000
与P1相连的8位发光LED点亮代表锁被打开;熄灭代表锁被锁上
程序功能: 本程序结合了24C02存储器的存储功能,可以掉电保存密码。
第一次运行时,若输入000000原始密码后无反应,可以试验着将主程序中前面的
一小段被注释线屏蔽的程序前的注释线删掉,然后重新编译下载(可以将密码还原为000000)。
此后,再将这小段程序屏蔽掉,再编译下载。方可正常使用。
1、开锁:
下载程序后,直接按六次S7(即代表数字1),8位LED亮,锁被打开,输入密码时,
六位数码管依次显示小横杠。
2、更改密码:
只有当开锁(LED亮)后,该功能方可使用。
首先按下更改密码键S16,然后设置相应密码,此时六位数码管会显示设置密码对应
的数字。最后设置完六位后,按下S17确认密码更改,此后新密码即生效。
3、重试密码:
当输入密码时,密码输错后按下键S18,可重新输入六位密码。
当设置密码时,设置中途想更改密码,也可按下此键重新设置。
4、关闭密码锁:
按下S19即可将打开的密码锁关闭。
推荐初级演示步骤:输入原始密码000000---按下更改密码按键S16---按0到9设置密码---按S17
确认密码更改---按S18关闭密码锁---输入新的密码打开密码锁
*******************************************************************************/
#include<reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar old1,old2,old3,old4,old5,old6; //原始密码000000
uchar new1,new2,new3,new4,new5,new6; //每次MCU采集到的密码输入
uchar a=16,b=16,c=16,d=16,e=16,f=16; //送入数码管显示的变量
uchar wei,key,temp;
bit allow,genggai,ok,wanbi,retry,close; //各个状态位
sbit la=P2^6;
sbit wela=P2^7;
sbit beep=P2^3;
sbit sda=P2^0; //IO口定义
sbit scl=P2^1;
unsigned char code table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};
/*****************IIC芯片24C02存储器驱动程序************************************/
void nop()
{
_nop_();
_nop_();
}
/////////24C02读写驱动程序////////////////////
void delay1(unsigned int m)
{ unsigned int n;
for(n=0;n<m;n++);
}
void init() //24c02初始化子程序
{
scl=1;
nop();
sda=1;
nop();
}
void start() //启动I2C总线
{
sda=1;
nop();
scl=1;
nop();
sda=0;
nop();
scl=0;
nop();
}
void stop() //停止I2C总线
{
sda=0;
nop();
scl=1;
nop();
sda=1;
nop();
}
void writebyte(unsigned char j) //写一个字节
{
unsigned char i,temp;
temp=j;
for (i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
nop();
sda=CY; //temp左移时,移出的值放入了CY中
nop();
scl=1; //待sda线上的数据稳定后,将scl拉高
nop();
}
scl=0;
nop();
sda=1;
nop();
}
unsigned char readbyte() //读一个字节
{
unsigned char i,j,k=0;
scl=0; nop(); sda=1;
for (i=0;i<8;i++)
{
nop(); scl=1; nop();
if(sda==1)
j=1;
else
j=0;
k=(k<<1)|j;
scl=0;
}
nop();
return(k);
}
void clock() //I2C总线时钟
{
unsigned char i=0;
scl=1;
nop();
while((sda==1)&&(i<255))
i++;
scl=0;
nop();
}
////////从24c02的地址address中读取一个字节数据/////
unsigned char read24c02(unsigned char address)
{
unsigned char i;
start();
writebyte(0xa0);
clock();
writebyte(address);
clock();
start();
writebyte(0xa1);
clock();
i=readbyte();
stop();
delay1(100);
return(i);
}
//////向24c02的address地址中写入一字节数据info/////
void write24c02(unsigned char address,unsigned char info)
{
start();
writebyte(0xa0);
clock();
writebyte(address);
clock();
writebyte(info);
clock();
stop();
delay1(5000); //这个延时一定要足够长,否则会出错。因为24c02在从sda上取得数据后,还需要一定时间的烧录过程。
}
/****************************密码锁程序模块********************************************************/
void delay(unsigned char i)
{
uchar j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f)
{
la=0;
P0=table[a];
la=1;
la=0;
wela=0;
P0=0xfe;
wela=1;
wela=0;
delay(5);
P0=table[b];
la=1;
la=0;
P0=0xfd;
wela=1;
wela=0;
delay(5);
P0=table[c];
la=1;
la=0;
P0=0xfb;
wela=1;
wela=0;
delay(5);
P0=table[d];
la=1;
la=0;
P0=0xf7;
wela=1;
wela=0;
delay(5);
P0=table[e];
la=1;
la=0;
P0=0xef;
wela=1;
wela=0;
delay(5);
P0=table[f];
la=1;
la=0;
P0=0xdf;
wela=1;
wela=0;
delay(5);
}
void keyscan()
{
{
P3=0xfe;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:
key=0;
wei++;
break;
case 0xde:
key=1;
wei++;
break;
case 0xbe:
key=2;
wei++;
break;
case 0x7e:
key=3;
wei++;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
}
}
P3=0xfd;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:
key=4;
wei++;
break;
case 0xdd:
key=5;
wei++;
break;
case 0xbd:
key=6;
wei++;
break;
case 0x7d:
key=7;
wei++;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
}
}
P3=0xfb;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:
key=8;
wei++;
break;
case 0xdb:
key=9;
wei++;
break;
case 0xbb:
genggai=1;
wei=0;
break;
case 0x7b:
if(allow)
ok=1;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
}
}
P3=0xf7;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:
retry=1;
break;
case 0xd7:
close=1;
break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
beep=0;
}
beep=1;
}
}
}
}
void shumima() //对按键采集来的数据进行分配
{
if(!wanbi)
{
switch(wei)
{
case 1:new1=key;
if(!allow) a=17;
else a=key; break;
case 2:new2=key;
if(a==17) b=17;
else b=key; break;
case 3:new3=key;
if(a==17) c=17;
else c=key; break;
case 4:new4=key;
if(a==17) d=17;
else d=key; break;
case 5:new5=key;
if(a==17) e=17;
else e=key; break;
case 6:new6=key;
if(a==17) f=17;
else f=key;
wanbi=1; break;
}
}
}
void yanzheng() //验证密码是否正确
{
if(wanbi) //只有当六位密码均输入完毕后方进行验证
{
if((new1==old1)&(new2==old2)&(new3==old3)&(new4==old4)&(new5==old5)&(new6==old6))
allow=1; //当输入的密码正确,会得到allowe置一
}
}
void main()
{
init(); //初始化24C02
/*********下面的一小段程序的功能为格式化密码存储区。************
******当24c02中这些存储区由于其他程序的运行而导致***************
*******所存数据发生了变化,或者密码遗忘时, ********************
******可以删掉其前面的注释线,然后重新编译下载。****************
******而将密码还原为000000后,请将下面的程序用******************
******注释屏蔽掉,重新编译、下载,方可正常使用****************/
// write24c02(110,0x00);
// write24c02(111,0x00);//24c02的第110到115地址单元作为密码存储区
// write24c02(112,0x00);
// write24c02(113,0x00);
// write24c02(114,0x00);
// write24c02(115,0x00);
/*******************************************************************/
old1=read24c02(110);
old2=read24c02(111);
old3=read24c02(112);
old4=read24c02(113);
old5=read24c02(114);
old6=read24c02(115);
while(1)
{
keyscan();
shumima();
yanzheng();
if(allow) //验证完后,若allow为1,则开锁
{
P1=0x00;
if(!genggai)
wanbi=0;
}
if(genggai) //当S16更改密码键被按下,genggai会被置一
{
if(allow) //若已经把锁打开,才有更改密码的权限
{
while(!wanbi) //当新的六位密码没有设定完,则一直在这里循环
{
keyscan();
shumima();
if(retry|close) //而当探测到重试键S18或者关闭密码锁键S19被按下时,则跳出
{ wanbi=1;
break;
}
display(a,b,c,d,e,f);
}
}
}
if(ok) //更改密码时,当所有六位新密码均被按下时,可以按下此键,结束密码更改
{ //其他时间按下此键无效
ok=0; wei=0;
genggai=0;
old1=new1;old2=new2;old3=new3; //此时,旧的密码将被代替
old4=new4;old5=new5;old6=new6;
//新密码写入存储区。
write24c02(110,old1);
write24c02(111,old2);
write24c02(112,old3);
write24c02(113,old4);
write24c02(114,old5);
write24c02(115,old6);
a=16;b=16;c=16;d=16;e=16;f=16;
}
if(retry) //当重试按键S18被按下,retry会被置位
{
retry=0; wei=0;wanbi=0;
a=16;b=16;c=16;d=16;e=16;f=16;
new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;
}
if(close) //当关闭密码锁按键被按下,close会被置位
{
close=0;genggai=0;//所有变量均被清零。
wei=0; wanbi=0;
allow=0;
P1=0xff;
a=16;b=16;c=16;d=16;e=16;f=16;
new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;
}
display(a,b,c,d,e,f); //实时显示
}
}