导航:首页 > 操作系统 > 密码锁单片机程序

密码锁单片机程序

发布时间:2023-04-26 12:07:01

‘壹’ 单片机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;
}
}

‘贰’ c语言单片机密码锁控制程序,用4个按键输入状态分别代表4位二进制数,可组成16种密码,范围0000

用51单片机,假设启握弯p1·0至p1·3接4个开关,悄闷P2·0接开锁按键S1
While(s1!=0);//等待按开锁按钮
delayms(10);//延时
While(s1==0);//等待按键抬起
mima=0x0F&P1;//读取P1低4位
if(mima==12)lock=1;//如果与设皮档定密码相等开锁
else Fmq=1;//否则,报警

‘叁’ 基于51单片机的密码锁程序

用STC52编的,下面是C程序,调试已经成功,自己看程序吧……
#include<reg52.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

#define LCD_data P0
sbit SDA=P3^5;
sbit SCL=P3^4;//24C08控制口设置
sbit LCD_RS = P3^3; //寄存器选择输入
sbit LCD_RW = P3^6; //液晶读/写控制
sbit LCD_EN = P3^7; //液晶使能控制
sbit LCD_PSB = P3^2; //串/并方式控制
sbit FM=P2^4;//蜂鸣器控制口
sbit RS=P2^5;
sbit T_CLK = P2^0; //实时时钟时钟线引脚 //
sbit T_IO = P2^1; //实时时钟数据线引脚 //
sbit T_RST = P2^2; //实时时钟复位线引脚 //
sbit ds=P2^3;
sbit EN=P2^6;
sbit ZZ=P2^7;
sbit FZ=P3^1;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;

uint temp1,s_temp; //定义整形变量
float f_temp; //定义浮点型变量

uchar time[]=" : : ";
uchar day[]=" 20 / / ( ) ";
uchar temp0[]=" 温度: . 度 ";
uchar num,num1,flag,count,a,b;
uchar unlock_i;//解密标志位

uchar t[4];
uchar t1[4];

void delay_ms(uint z)//长延时
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}

void delay() //短延时,大约5us
{
; ;
}
void reshi()
{
if(RS==1)
{ unlock_i=1;
}
else
{
unlock_i=0;
}
}
uchar code mima[]={'0','1','2','3','4','5','6','7','8','9','0','*'};

void lcd_xieping0(uchar x,uchar y,uchar date);
void lcd_xieping(uchar x,uchar y,uchar *str);
//********************************************************
// 开机显示
//********************************************************
void kjxs()
{
uint i,j;
lcd_xieping(0,0,"****************");
lcd_xieping(1,0," 欢迎进入 ");
lcd_xieping(2,0," 密码锁系统! ");
lcd_xieping(3,0,"****************");
delay_ms(4000);
lcd_xieping(0,0," 系统初始化中 ");
lcd_xieping(1,0," 请稍后… ");
lcd_xieping(2,0,"————————");
lcd_xieping(3,0," ");
for(j=3;j>0;j--)
{
for(i=0;i<8;i++)
{
lcd_xieping(3,i,"*");
delay_ms(250);
}
lcd_xieping(3,0," ");
}
}
//********************************************************
// 12864显示
//********************************************************
void write_cmd(uchar cmd)
{
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
P0 = cmd;
delay_ms(5);
LCD_EN = 1;
delay_ms(5);
LCD_EN = 0;
}
void write_dat(uchar dat)
{
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delay_ms(5);
LCD_EN = 1;
delay_ms(5);
LCD_EN = 0;
}
void lcd_xieping0(uchar x,uchar y,uchar date)
{
switch(x)
{
case 0: write_cmd(0x80+y); break;
case 1: write_cmd(0x90+y); break;
case 2: write_cmd(0x88+y); break;
case 3: write_cmd(0x98+y); break;
}
write_dat(date);
}
void lcd_xieping(uchar x,uchar y,uchar *str)
{
switch(x)
{
case 0: write_cmd(0x80+y); break;
case 1: write_cmd(0x90+y); break;
case 2: write_cmd(0x88+y); break;
case 3: write_cmd(0x98+y); break;
}
while (*str)
{
write_dat(*str);
str++;
}
}
void lcd_init()
{
LCD_PSB = 1; //并口方式
write_cmd(0x30); //基本指令操作
delay_ms(5);
write_cmd(0x0C); //显示开,关光标
delay_ms(5);
write_cmd(0x01); //清除LCD的显示内容
delay_ms(5);
}
//**************************************************************
// 键盘扫描函数
//**************************************************************
uchar keyscan1() //矩阵键盘扫描函数
{
uchar temp;
while(!num)
{P1=0xfe; //赋值
temp=P1; //读回数据
temp=temp&0xf0; //与运算
if(temp!=0xf0) //判断
{
delay_ms(2); //延时消抖
temp=P1; //读回数据
temp=temp&0xf0;
if(temp!=0xf0)
{
switch(temp) //多分支选择
{
case 0x70:num=1;break; //跳出
case 0xb0:num=2;break;
case 0xd0:num=3;break;
case 0xe0:num=4;break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}//等待按键释放
}
}
P1=0xfd; //赋值
temp=P1; //读回数据
temp=temp&0xf0; //与运算
if(temp!=0xf0) //判断
{
delay_ms(2); //延时消抖
temp=P1; //读回数据
temp=temp&0xf0;
if(temp!=0xf0)
{
switch(temp) //多分支选择
{
case 0x70:num=5;break; //跳出
case 0xb0:num=6;break;
case 0xd0:num=7;break;
case 0xe0:num=8;break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}//等待按键释放
}
}
P1=0xfb; //赋值
temp=P1; //读回数据
temp=temp&0xf0; //与运算
if(temp!=0xf0) //判断
{
delay_ms(2); //延时消抖
temp=P1; //读回数据
temp=temp&0xf0;
if(temp!=0xf0)
{
switch(temp) //多分支选择
{
case 0x70:num=9;break; //跳出
case 0xb0:num=10;break;
case 0xd0:num=11;break;
case 0xe0:num=12;break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}//等待按键释放
}
}
}
return(num); //返回值
}

uchar keyscan2()
{
uchar temp;
while(!num1)
{P1=0xf7; //赋值
temp=P1; //读回数据
temp=temp&0xf0; //与运算
if(temp!=0xf0) //判断
{
delay_ms(2); //延时消抖
temp=P1; //读回数据
temp=temp&0xf0;
if(temp!=0xf0)
{
switch(temp) //多分支选择
{
case 0x70:num1=1;break; //跳出
case 0xb0:num1=2;break;
case 0xd0:num1=3;break;
case 0xe0:num1=4;break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}//等待按键释放
}
}
}
return(num1);
}
//**************************************************************
// 直流电机
//**************************************************************
void dianjiZZ()
{
EN=1;
ZZ=1;
FZ=0;
}
void dianjiFZ()
{
EN=1;
ZZ=0;
FZ=1;
}
void dianji_stop()
{
EN=0;
}
//**************************************************************
// EPPROM
//**************************************************************
void start() //启动信号
{
SDA=1;
delay();
SCL=1;
delay();
SDA=0;
delay();
}

void stop() //停止信号
{
SDA=0;
delay();
SCL=1;
delay();
SDA=1;
delay();
}

void respons() //响应信号
{
uchar i;
SCL=1;
delay();
while((SDA==1)&&(i<250))
i++;
SCL=0;
delay();

}

void writebyte(uchar date) //写一个字节
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
SCL=0;
delay();
SDA=CY;
delay();
SCL=1;
delay();
}
SCL=0;
delay();
SDA=1; //释放总线
delay();

}

uchar readbyte() //读一个字节
{
uchar i,k;
SCL=0;
delay();
SDA=1;
for(i=0;i<8;i++)
{
SCL=1;
delay();
k=(k<<1)|SDA;
SCL=0;
delay();
}
delay();
return(k);

}
void write(uchar add,uchar date) //在一个地址写一个字节
{
start();
writebyte(0xa0);
respons();
writebyte(add);
respons();
writebyte(date);
respons();
stop();

}
uchar read(uchar add) //在一个地址读一个字节
{
start();
writebyte(0xa0);
respons();
writebyte(add);
respons();
start();
writebyte(0xa1);
respons();
b=readbyte();
respons();
stop();
return(b);
}
//**************************************************************
// 时间日期函数
//**************************************************************
void v_WTInputByte(uchar ucDa)
{
uchar i;
ACC= ucDa;
for(i=8; i>0; i--)
{
T_IO = ACC0; //*相当于汇编中的 RRC
T_CLK = 1;
T_CLK = 0;
ACC =ACC>> 1;
}
}
uchar uc_RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC>>1; //*相当于汇编中的 RRC
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
void v_W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_WTInputByte(ucAddr); /* 地址,命令 */
v_WTInputByte(ucDa); /* 写1Byte数据*/
T_CLK = 1;
T_RST =0;
}
uchar uc_R1302(uchar ucAddr)
{
uchar ucDa;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
v_WTInputByte(ucAddr); // 地址,命令 //
ucDa = uc_RTOutputByte(); // 读1Byte数据 //
T_CLK = 1;
T_RST =0;
return(ucDa);
}
void Init1302(void)
{
v_W1302(0x8e,0x00); //控制写入WP=0
v_W1302(0x80,0x80);
v_W1302(0x90,0xa9);
v_W1302(0x80,0x00); //秒
v_W1302(0x82,0x24); //分
v_W1302(0x84,0x12); //时
v_W1302(0x86,0x29); //日
v_W1302(0x88,0x10); //月
v_W1302(0x8a,0x05); //星期
v_W1302(0x8c,0x10); //年 //
v_W1302(0x8e,0x80);
}
void donetime(void)
{
uchar d;
d=uc_R1302(0x87);
day[10]=(d&0x0f)+48;
day[9]=((d>>4)&0x03)+48;
d=uc_R1302(0x89);
day[7]=(d&0x0f)+48;
day[6]=((d>>4)&0x01)+48;
d=uc_R1302(0x8b);
day[13]=(d&0x07)+48;
d=uc_R1302(0x8d);
day[4]=(d&0x0f)+48;
day[3]=(d>>4)+48;
d=uc_R1302(0x81);
time[15]=(d&0x0f)+48;
time[14]=(d>>4)+48;
d=uc_R1302(0x83);
time[12]=(d&0x0f)+48;
time[11]=(d>>4)+48;
d=uc_R1302(0x85);
time[9]=(d&0x0f)+48;
time[8]=(d>>4)+48;
}
//**************************************************************
// 温度检测函数
//**************************************************************
void dsreset(void) //18B20复位,初始化函数
{
uint i;
ds=0;
i=103;
while(i>0)i--;
ds=1;
i=4;
while(i>0)i--;
}
bit tempreadbit(void) //读1位函数
{
uint i;
bit dat;
ds=0;i++; //i++ 起延时作用
ds=1;i++;i++;
dat=ds; //读数据
i=8;while(i>0)i--;
return (dat);
}
uchar tempread(void) //读1个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tempreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}
void tempwritebyte(uchar dat) //向18B20写一个字节数据
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01; //判断最后一位是1还是0
dat=dat>>1;
if(testb) //写 1
{
ds=0;
i++;i++;
ds=1;
i=8;while(i>0)i--;
}
else
{
ds=0; //写 0
i=8;while(i>0)i--;
ds=1;
i++;i++;
}
}
}

void tempchange(void) //DS18B20 开始获取温度并转换
{
dsreset(); //初始化,每次对18B20的操作都首先要初始化
delay_ms(1);
tempwritebyte(0xcc); // 写跳过读ROM指令
tempwritebyte(0x44); // 写温度转换指令
}
void get_temp() //读取寄存器中存储的温度数据
{
uchar a,b;
dsreset(); //初始化
delay_ms(1);
tempwritebyte(0xcc); // 写跳过读ROM指令
tempwritebyte(0xbe); //写读指令
a=tempread(); //读低8位
b=tempread(); //读高8位
temp1=b;
temp1<<=8; //两个字节组合为1个字
temp1=temp1|a;
f_temp=temp1*0.0625; //温度在寄存器中为12位 分辨率位0.0625°
}
//**************************************************************
// 解密函数
//**************************************************************
void unlock()
{
uchar in,i;
if(num==0)
{
lcd_xieping(0,0,"**密码锁系统** ");
lcd_xieping(1,0,"—————————");
lcd_xieping(2,0," 请输入密码: ");
lcd_xieping(3,0," ");
for(i=0;i<4;i++)
{
t1[i]=keyscan1();
lcd_xieping(3,i,"*");
num=0;
}//输密码
}
in=keyscan1();
if(in==12)//in-确定键标志位
{
in=0;
num=0;
if((t1[0]==t[0])&&(t1[1]==t[1])&&(t1[2]==t[2])&&(t1[3]==t[3]))
{
flag=1;//解密成功与否标志位
//unlock_i=1;
a=0;//功能键标志
lcd_xieping(0,0,"**密码锁系统** ");
lcd_xieping(1,0,"——————————");
lcd_xieping(2,0," 密码正确! ");
lcd_xieping(3,0," 您的身份已确认");
delay_ms(1500);
lcd_xieping(1,0,"————————");
lcd_xieping(2,0,"功能 I 开锁 ");
lcd_xieping(3,0," II修改密码");
}
else
{
flag=0;
count++;
if(count==3)
{
count=0;
num=1;
lcd_xieping(1,0,"——————————");
lcd_xieping(2,0,"您的机会已用完 ");
lcd_xieping(3,0,"对不起**无法进入");
FM=0;
delay_ms(1000);
FM=1;
}
}
}
}
//**************************************************************
// 修改密码函数
//**************************************************************
void xiugaimima()
{ uchar i,j,l,im,ib;
uchar t2[4];
uchar t3[4];
num=0;
lcd_xieping(1,0,"————————");
lcd_xieping(2,0,"请输入新密码: ");
lcd_xieping(3,0," ");
for(i=0;i<4;i++)
{
t2[i]=keyscan1();
lcd_xieping0(3,i,mima[num]);
num=0;
}
im=keyscan1();
if(im==12)//im,in,ib,同为确定键标志位
{
im=0;
num=0;
lcd_xieping(1,0,"————————");
lcd_xieping(2,0,"请再次输入新密码");
lcd_xieping(3,0," ");
for(i=0;i<4;i++)
{
t3[i]=keyscan1();
lcd_xieping0(3,i,mima[num]);
num=0;
}
}
ib=keyscan1();
if(ib==12)
{
ib=0;
num=0;
if(t2[0]==t3[0]&&t2[1]==t3[1]&&t2[2]==t3[2]&&t2[3]==t3[3])
{
t[0]=t3[0];
t[1]=t3[1];
t[2]=t3[2];
t[3]=t3[3];
lcd_xieping(1,0,"————————");
lcd_xieping(2,0," 祝贺您! ");
lcd_xieping(3,0," 密码修改成功 ");
flag=0;
for(j=0;j<4;j++)
{
l=j+1;
write(l,t[j]);
delay_ms(10);
}//24C08写数据
delay_ms(1000);
}
else
{
lcd_xieping(2,0,"两次输入密码不同");
lcd_xieping(3,0," 密码修改失败 ");
flag=1;
delay_ms(500);
}
}
}
//**************************************************************
// 显示函数
//**************************************************************
void xianshi()
{
donetime();
tempchange();
get_temp();
s_temp=f_temp*100;
temp0[7]=(s_temp/1000)+48;
temp0[8]=(s_temp%1000/100)+48;
temp0[10]=(s_temp%100/10)+48;
temp0[11]=(s_temp%10)+48;
lcd_xieping(0,0,"**密码锁系统** ");
lcd_xieping(1,0,temp0);
lcd_xieping(2,0,day);
lcd_xieping(3,0,time);
num=0;
}
//**************************************************************
// 开锁函数
//**************************************************************
void kaisuo()
{
uchar i;
lcd_xieping(2,0," 开锁中…… ");
lcd_xieping(3,0,"——耐心等待——");
for(i=3;i>0;i--)
{
FM=0;
delay_ms(100);
FM=1;
delay_ms(100);
flag=0;
}
dianjiZZ();
delay_ms(10000);
dianji_stop();
lcd_xieping(2,0,"—开锁过程结束—");
lcd_xieping(3,0," 请开门 ");
delay_ms(5000);
dianjiFZ();
delay_ms(10000);
dianji_stop();
flag=0;
}
//**************************************************************
// 主函数
//**************************************************************
void main()
{
uchar m;
unlock_i=1;
lcd_init(); //液晶初始化
//Init1302();
kjxs(); //开机显示
for(m=0;m<4;m++)
{
t[m]=read(m+1);
delay_ms(10);
}//24C08读数据
while(1)
{
reshi();
if(!unlock_i)
{
unlock();//解密函数
}
else
{
xianshi();//时间、日期、温度显示函数
}
if(flag==1)
{
num1=0;
a=keyscan2();
if(a==1)
{
kaisuo();//开锁函数
}
if(a==2)
{
xiugaimima();//修改密码函数
}
}
}
}

‘肆’ 求51单片机C语言编的简易密码锁程序

假设晶振为12M,数码管共阴,且由P1口控制器;LED高电平点亮。
#include<reg51.h>
void
delay(int);
/*延时程序*/
sbit
P3_0=P3^0;
int
main()
{
P3_0=0;
/*发光二极管的初始状态为灭,即:未解锁*/
while(1)
/*等待解锁*/
{
P0=0x0FF;
/*P0初始化,先全写1,等待输入*/团汪
if(P0&0x0f==0x02)
/*验证密码是否为2*/
break;
P1=0x79;
/*密码错误,数码管显示为E*/
delay(3);
/*延时大约3秒*/
}
P1=0x73;
/*密搜敬码正确,数码管显示为P*/
delay(3);
/*延时大世或慎约3秒*/
P3_0=1;
/*LED点亮,密码锁解开*/
...
/*解锁后的其他任务*/
return
0;
}
void
delay(int
t)
{
int
i=125;
for(;t>0;t--)
for(;i>0;i--);
}

‘伍’ 51单片机4*3矩阵键盘6位密码锁c语言程序

#include<stdio.h>
#include<reg51.h>
#define uchar unsigned char

uchar key;
int i=0;
char b[4]={'0','0','0','0'};//输入的密码放这里和初始的比较来判断是否密码正确
void keyscan() //扫描按键是否按下
{
uchar temp;
P3=0xfe; //扫描第一行
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0) //判断按键是否按下
{
delayms(10);//去抖动
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)//确认按键按下
{
temp=P3;
switch(temp)
{
case 0xee:key='0';break;
case 0xde:key='1';break;
case 0xbe:key='2';break;
case 0x7e:key='3';break;
}
while(temp!=0xf0) //判断按键是否松开
{
temp=P3;
temp=temp&0xf0;
}
b[i]=key;i++;if(i==3)i=0;
}
}
P3=0xfd; //扫描第二行
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:key='4';break;
case 0xdd:key='5';break;
case 0xbd:key='6';break;
case 0x7d:key='7';break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
b[i]=key;i++;if(i==3)i=0;
}
}
P3=0xfb; //扫描第三行
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:key='8' ;break;
case 0xdb:key='9' ;break;
case 0xbb:key='A';break;
case 0x7b:key='B';break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
b[i]=key;i++;if(i==3)i=0;
}
}
P3=0xf7; //扫描第四行
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delayms(10);
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:key='C';break;
case 0xd7:key='D';break;
case 0xb7:key='E';break;
case 0x77:key='F';break;
}
while(temp!=0xf0)
{
temp=P3;
temp=temp&0xf0;
}
b[i]=key;i++;if(i==3)i=0;
}
}
}

main()
{
char a[4]={'3','5','A','C'}; //这个做初始密码
while(1)//无限循环,保证了b 0-3 四个数有值
{
keyscan();
if(a[0]==b[0]&&a[1]==b[1]&&a[2]==b[2]&&a[3]==b[3])
{
//这里写密码正确程序要怎么处理
}
}
}

‘陆’ 51单片机的电子密码锁程序,用KEIL C写的

以前帮别人做过一个类似的

#include<reg52.h>

#include <def.h>

#include"lcd.c"

uchar key;

uchar num;

sbit alarm=P2^4;

sbit open=P2^1;

uchar code table[]={' ','1','2','3',

'4','5','6','7',

'8','9','0'};

void keyscan();

uchar hptable[10];

uchar password[6];

uchar wordbuf[6];

uchar fom[]="input password:";

uchar change[]="set mask:";

uchar state1[]="right";

uchar state2[]="error";

uchar sflag;

uchar dflag,cnt;

uchar setf,fset;

uchar flag;

void main ()

{

uchar hp;

alarm=0;

flag=0;

setf=0;

fset=0;

dflag=0;

lcden=0;

lcdrw=1;

lcdrs=1;

P3=0x0f;

for(hp=0;hp<6;hp++)

{

password[hp]='8';

}

write(0x38,0); //0为写命令

delay(9);

write(0x08,0);

write(0x01,0);

write(0x06,0);

write(0x0c,0);

write(0x80,0);

for(hp=0;hp<15;hp++)

{

write(fom[hp],1);

}



while(1)

{

// alarm=!alarm;

keyscan();

if(setf==0)

{

if(num>=1&&num<=10)

{

write(0x80+0x40+cnt,0);

write('*',1);

wordbuf[cnt]=table[num];

cnt++;

num=0;


}

}

else

{

write(0x01,0);

write(0x80,0);

for(hp=0;hp<9;hp++)

{

write(change[hp],1);

}

fset=1;

cnt=0;

while(fset)

{

keyscan();

if(num>=1&&num<=10)

{

write(0x80+0x40+cnt,0);

write('*',1);

password[cnt]=table[num];

cnt++;

num=0;


}

if(num==11)

{

write(0x80+0x40+cnt-1,0);

write('',1);

cnt--;

num=0;

}

if(num==13)

{



flag=1;

num=0;

fset=0;

setf=0;

// goto chuz;

}


}

cnt=0;

}

if(flag==1)

{

write(0x01,0);

write(0x80,0);

for(hp=0;hp<15;hp++)

{

write(fom[hp],1);

}

flag=0;

}

if(num==11)

{

write(0x80+0x40+cnt-1,0);

write('',1);

cnt--;

num=0;

}

if(num==12)

{

if(dflag==1)

setf=1;

num=0;

}

if(num==13)

{

num=0;

write(0x80+0x40+10,0);

if(wordbuf[0]==password[0]&&wordbuf[1]==password[1]&&wordbuf[2]==password[2]&&wordbuf[3]==password[3]&&wordbuf[4]==password[4]&&wordbuf[5]==password[5])

{


for(hp=0;hp<5;hp++)

{

write(state1[hp],1);

}

sflag=0;

dflag=1;

}

else

{

for(hp=0;hp<5;hp++)

{

write(state2[hp],1);

}

sflag++;


}

}

if(sflag==3)

{

alarm=!alarm;

//delay(9);

}

if(num==14)

{

num=0;

cnt=0;

write(0x01,0);

write(0x80,0);

for(hp=0;hp<15;hp++)

{

write(fom[hp],1);

}

}

if(num==15)

{

if(dflag==1)

{

open=0;

dflag=0;

}

}

}

}


void keyscan ()


{

uchar tem,temp;

P3=0xfe;

temp=P3;

tem=temp&0xf0;

if (tem!=0xf0) //没有键按下时它的值是不变的,即仍为0XF0,而有键接下时要变

{

delay(5); //延时消抖

temp=P3;

tem=temp&0xf0;

if (tem!=0xf0) //确认有键按下

{

temp=P3;

tem=temp&0xf0; //这里也可以不要这一步,但下面的case里的值也要变

switch (tem)

{

case 0xe0: num=0; break;

case 0xd0: num=1; break;

case 0xb0: num=2; break;

case 0x70: num=3; break;

default : ; break ;



}

while(tem!=0xf0) //等待松手

{

temp=P3;

tem=temp&0xf0;


}

}


}

P3=0xfd;

temp=P3;

tem=temp&0xf0;

if (tem!=0xf0)

{

delay(5);

temp=P3;

tem=temp&0xf0;

if (tem!=0xf0)

{

temp=P3;

tem=temp&0xf0;

switch (tem)

{

case 0xe0: num=4; break;

case 0xd0: num=5; break;

case 0xb0: num=6; break;

case 0x70: num=7; break;

default : ; break ;



}

while(tem!=0xf0)

{

temp=P3;

tem=temp&0xf0;


}

}


}

P3=0xfb;

temp=P3;

tem=temp&0xf0;

if (tem!=0xf0)

{

delay(5);

temp=P3;

tem=temp&0xf0;

if (tem!=0xf0)

{

temp=P3;

tem=temp&0xf0;

switch (tem)

{

case 0xe0: num=8; break;

case 0xd0: num=9; break;

case 0xb0: num=10; break;

case 0x70: num=11; break;

default : ; break ;



}

while(tem!=0xf0)

{

temp=P3;

tem=temp&0xf0;


}

}


}

P3=0xf7;

temp=P3;

tem=temp&0xf0;

if (tem!=0xf0)

{

delay(5);

temp=P3;

tem=temp&0xf0;

if (tem!=0xf0)

{

temp=P3;

tem=temp&0xf0;

switch (tem)

{

case 0xe0: num=12; break;

case 0xd0: num=13; break;

case 0xb0: num=14; break;

case 0x70: num=15; break;

default : ; break ;



}

while(tem!=0xf0)

{

temp=P3;

tem=temp&0xf0;


}

}


}

}

‘柒’ 求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你自己写吧
}

‘捌’ 求一个51单片机的简易密码锁程序

你好!

从你的功能要求来看,这个密码锁不简易,功能很强很全了;

你这个是仿真验证程序还是要做出实物来验证程序。

采用仿真软件模拟出的密码锁

‘玖’ 89C51单片机 电子密码锁 汇编程序求解

TLOW EQU 00H
THIGH EQU 0EEH
COUN0 EQU 200 ;5ms * 200 = 1S
COUN1 EQU 3FH ;密码的位数
D_TIME EQU 3EH ;设置密码时的时间限制
SEC EQU 3DH ;秒单元

PASS_OLD EQU 30H
PASS_NEW EQU 40H

SDA EQU P3.4 ;24C01的串行数据线
SCLK24 EQU P3.3 ;24C01的串行时钟线

;20H.0 为时间限制标记
;20H.1 为按错键标记
;20H.2 为比较对错标记
;20H.3 为3秒时间标记首祥

RS EQU P2.0
RW EQU P2.1
EN EQU P2.2
X EQU 2FH ;LCD 地址变量
BEEP EQU P3.7
;--------------------------------------------------
ORG 0000H
JMP MAIN
ORG 0BH
JMP T0_INT
;--------------------------------------------------
MAIN:
MOV SP,#60H
MOV A,#00H
MOV D_TIME,A
MOV SEC,A
MOV COUN1,A
MOV R5,#06H
MOV R0,#PASS_OLD

CLR_01: MOV @R0,A
INC R0
DJNZ R5,CLR_01
CLR EN
CLR 20H.0
CLR 20H.1
CLR 20H.2
CLR 20H.3
CALL INIT_TIMER
CALL SET_LCD
CALL MENU1
CALL PASS_READ ;读出预携芹姿定密码。
LOOP1:
CALL SCAN_KEY
CALL DELAY2
CJNE A,#0fH,LOOP1 ;按F键启动进入输入密码程序
SETB TR0

LP0: CALL SCAN_KEY ;按住F键3秒以上蜂鸣器不响为止
CALL DELAY2
CJNE A,#0fH,LP3
JB 20H.3,LP1 ;3秒到,20H.3置1。
JMP LP0

LP1: CLR TR0 ;停止中断
MOV SEC,#00H ;秒单元清零
CLR 20H.3 ;清3秒标记位

LP2: MOV P1,#0F0H ;等待键释放
MOV A,P1
CJNE A,#0F0H,LP2
CALL PASS_IN
JB 20H.2,LOOP2 ;密码正确后方可转下一步
JMP LP4

LP3: CLR TR0 ;停止中断
CLR 20H.3 ;清3秒标记位
MOV SEC,#00H ;秒单元清零
LP4: CALL SYS_RST ;系统复位
RET
NOP
NOP
NOP
LJMP MAIN
LOOP2: MOV R4,#06H ;模拟输出蜂鸣器响六声
LOOP3: CALL BZ
DJNZ R4,LOOP3

MOV A,#00H

LOOP4: CALL SCAN_KEY
CJNE A,#0AH,LOOP6 ;按A键进入PASS_LOOK
CALL PASS_LOOK

LOOP5: CALL SCAN_KEY
CJNE A,#0EH,LOOP5 ;按E键辩绝退出PASS_LOOK
CALL MENU1
CALL MENU2

LOOP6: CJNE A,#0BH,LOOP8 ;按B键进入PASS_SET
CALL PASS_SET

LOOP7: CALL SCAN_KEY
CJNE A,#0EH,LOOP7 ;按E键退出PASS_SET
CALL MENU1
CALL MENU2

LOOP8: CJNE A,#0DH,LOOP4 ;按D键退出
ACALL MAIN ;PASS_LOOK和PASS_SET状态

JMP LOOP4
SYS_RST:
RST1: CALL SCAN_KEY
CJNE A,#0DH,RST1 ;"D" 键
LJMP MAIN
RET
NOP
NOP
NOP
LJMP MAIN
PASS_IN:

MOV 21H,#03H ;允许输入三次密码
P_IN1: MOV DPTR,#IN_PASS0 ;
MOV A,#1 ;
CALL LCD_SHOW
MOV DPTR,#INFO2 ;指针指到显示信息2
MOV A,#2 ;显示在第二行
CALL LCD_SHOW

MOV R0,#PASS_OLD
MOV R3,#00H
MOV R2,#09H ;设置LCD地址
MOV COUN1,#06H ;6位密码
SETB TR0

P_IN2: JB 20H.0,P_IN4
MOV P1,#0F0H
MOV A,P1
CJNE A,#0F0H,P_IN3
jmp P_IN2
P_IN3:
CALL KEY_IN
CALL SETDATA0
CALL BZ
JB 20H.1,P_IN4
DJNZ COUN1,P_IN2
CLR TR0
CLR 20H.0
CALL PASS_COMP
JNB 20H.2,P_IN4 ;比较对错标记
RET
P_IN4: CLR TR0
CLR 20H.0 ;
CLR 20H.1 ;
CALL INPUT_ERR
DJNZ 21H,P_IN1 ;
RET
IN_PASS0:
DB " INPUT PASSWORD ",0
PASS_COMP:
MOV COUN1,#06H ;比较6位数值
MOV R0,#PASS_OLD
MOV R1,#PASS_NEW
P_COMP0: MOV A,@R0
MOV B,@R1
CJNE A,B,P_COMP1
INC R0
INC R1
DJNZ COUN1,P_COMP0
CALL INPUT_OK
SETB 20H.2
RET
P_COMP1: CLR 20H.2
;CALL INPUT_ERR
RET
PASS_SET:

MOV 21H,#05H ;允许输入三次密码

P_SET1: MOV DPTR,#SET_PASS0 ;
MOV A,#1 ;
CALL LCD_SHOW
MOV DPTR,#INFO2 ;指针指到显示信息2
MOV A,#2 ;显示在第二行
CALL LCD_SHOW

MOV R3,#00H
MOV R2,#09H ;设置LCD地址
MOV R1,#PASS_NEW
MOV COUN1,#06H ;6位密码
SETB TR0

P_SET2: JB 20H.0,P_SET4
MOV P1,#0F0H
MOV A,P1
CJNE A,#0F0H,P_SET3
jmp P_SET2
P_SET3:
CALL KEY_IN
CALL SETDATA1
CALL BZ
JB 20H.1,P_SET4
;MOV R5,#04H
;CALL DELAY
DJNZ COUN1,P_SET2
CLR TR0
CLR 20H.0
CALL RESET_OK
CALL EEPW
RET
P_SET4: CLR TR0
CLR 20H.0 ;
CLR 20H.1 ;
CALL RESET_ERR
DJNZ 21H,P_SET1 ;
RET

SET_PASS0:
DB " RESET PASSWORD ",0
MENU1: ;LCD 显示工作菜单信息
MOV DPTR,#MENU01
MOV A,#1 ;在第一行显示信息
CALL LCD_SHOW
RET
MENU01: DB "PASSWORD CONTROL",0
MENU2: ;LCD 显示工作菜单信息
MOV DPTR,#MENU02
MOV A,#2 ;在第一行显示信息
CALL LCD_SHOW
RET
SETDATA1:
MOV A,R3
ANL A,#0FH ;取出低四位二进制数
PUSH ACC
CLR C
SUBB A,#0AH ;减10
POP ACC
JC ASCII3 ;该数小于10,转ASCII0
SETB 20H.1
RET
ADD A,#07H ;大于10的数加上37H
ASCII3: ADD A,#30H ;小于10的数加上30H
MOV @R1,A
MOV B,R2
CALL LCDP2
INC R2
INC R1
RET

SETDATA0:

MOV A,R3
ANL A,#0FH ;取出低四位二进制数
PUSH ACC
CLR C
SUBB A,#0AH ;减10
POP ACC
JC ASCII4 ;该数小于10,转ASCII4
SETB 20H.1
RET
ASCII4: ADD A,#30H ;小于10的数加上30H
MOV @R0,A ;保存密码值
MOV A,#2AH ;显示" * "
MOV B,R2
CALL LCDP2
INC R2
INC R0
RET
PASS_LOOK:
MOV DPTR,#LOOK1 ;指针指到显示信息1
MOV A,#1 ;显示在第一行
CALL LCD_SHOW
MOV DPTR,#LOOK2 ;指针指到显示信息2
MOV A,#2 ;显示在第二行
CALL LCD_SHOW
MOV R1,#PASS_NEW
MOV R2,#09
MOV COUN1,#06
LOOK0: MOV A,@R1
MOV B,R2
CALL LCDP2
INC R2
INC R1
DJNZ COUN1,LOOK0
RET

LOOK1: DB " LOOK PASSWORD ",0 ;LCD 第一行显示信息
LOOK2: DB "PASSWORD ------ ",0 ;LCD 第二行显示信息
SCAN_KEY:
SCAN_K: MOV P1,#0F0H
MOV A,P1
CJNE A,#0F0H,KEY_NUM0 ;有键按下转
JMP KEY_END
KEY_NUM0: CALL KEY_IN
CALL BZ
MOV R5,#04H
CALL DELAY
KEY_END: RET
KEY_IN: MOV P1,#0F0H ;置列线为0,行线为1
MOV A,P1
ANL A,#0F0H
MOV B,A
MOV P1,#0FH ;置列线为1,行线为0
MOV A,P1
ANL A,#0FH
ORL A,B ;高四位与低四位重新组合
CJNE A,#0FFH,KEY_IN1 ;0FFH为末按键
RET
KEY_IN1: MOV B,A
MOV DPTR,#KEYTABLE
MOV R3,#0FFH
KEY_IN2: INC R3
MOV A,R3
MOVC A,@A+DPTR
CJNE A,B,KEY_IN3
MOV A,R3 ;找到,取顺序码
RET
KEY_IN3: CJNE A,#0FFH,KEY_IN2 ;末完,继续查
RET ;0FFH为结束码
SET_LCD:
CLR EN
CALL INIT_LCD ;初始化 LCD
CALL DELAY1
MOV DPTR,#INFO1 ;指针指到显示信息1
MOV A,#1 ;显示在第一行
CALL LCD_SHOW
MOV DPTR,#INFO2 ;指针指到显示信息2
MOV A,#2 ;显示在第二行
CALL LCD_SHOW
RET
INFO1: DB " ",0 ;LCD 第一行显示信息
INFO2: DB "PASSWORD ------ ",0 ;LCD 第二行显示信息INIT_LCD: ;8位I/O控制 LCD 接口初始化
MOV A,#38H ;双列显示,字形5*7点阵
CALL WCOM
CALL DELAY1
MOV A,#38H ;双列显示,字形5*7点阵
CALL WCOM
CALL DELAY1
MOV A,#38H ;双列显示,字形5*7点阵
CALL WCOM
CALL DELAY1
MOV A,#0CH ;开显示,关光标,
CALL WCOM
CALL DELAY1
MOV A,#01H ;清除 LCD 显示屏
CALL WCOM
CALL DELAY1
RET
LCD_SHOW: ;在LCD的第一行或第二行显示信息字符

CJNE A,#1,LINE2 ;判断是否为第一行
LINE1: MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
JMP FILL
LINE2: MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM
FILL: CLR A ;填入字符
MOVC A,@A+DPTR ;由消息区取出字符
CJNE A,#0,LC1 ;判断是否为结束码
RET
LC1: CALL WDATA ;写入数据
INC DPTR ;指针加1
JMP FILL ;继续填入字符
RET
CLR_LINE: ;清除该行 LCD 的字符
MOV R0,#24
CL1: MOV A,#' '
CALL WDATA
DJNZ R0,CL1
RET
ENABLE: ;写指令使能
CLR RS ;RS=L,RW=L,D0-D7=指令码,E=高脉冲
CLR RW
SETB EN
CALL DELAY0
CLR EN
RET
ENABLE1: ;写数据使能
SETB RS ;RS=H,RW=L,D0-D7=数据,E=高脉冲
CLR RW
SETB EN
CALL DELAY0
CLR EN
RET

DELAY0: MOV R7,#250 ;延时500微秒
DJNZ R7,$
RET
WCOM: ;以8位控制方式将命令写至LCD
MOV P0,A ;写入命令
CALL ENABLE
RET
WDATA: ;以8位控制方式将数据写至LCD
MOV P0,A ;写入数据
CALL ENABLE1
RET
LCDP2: ;在LCD的第二行显示字符
PUSH ACC ;
MOV A,B ;设置显示地址
ADD A,#0C0H ;设置LCD的第二行地址
CALL WCOM ;写入命令
POP ACC ;由堆栈取出A
CALL WDATA ;写入数据
RET
CONV:
MOV X,#9 ;设置显示起始位置
MOV A,R3
ANL A,#0F0H ;取出高四位二进制数
SWAP A ;高四位与低四位互换
PUSH ACC ;压入堆栈
CLR C ;C=0
SUBB A,#0AH ;减10
POP ACC ;弹出堆栈
JC ASCII0 ;该数小于10,转ASCII0
ADD A,#07H ;大于10的数加上37H
ASCII0: ADD A,#30H ;小于10的数加上30H
MOV B,X
CALL LCDP2

MOV A,R3
ANL A,#0FH ;取出低四位二进制数
PUSH ACC
CLR C
SUBB A,#0AH ;减10
POP ACC
JC ASCII1 ;该数小于10,转ASCII1
ADD A,#07H ;大于10的数加上37H
ASCII1: ADD A,#30H ;小于10的数加上30H
INC X
MOV B,X
CALL LCDP2
RET
DELAY2: MOV R5,#15H
DELAY: ;延时R5×10MS
MOV R6,#50
D1: MOV R7,#100
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,DELAY
RET
DELAY1: ;延时5MS
MOV R6,#25
D2: MOV R7,#100
DJNZ R7,$
DJNZ R6,D2
RET
KEYTABLE:
DB 0EEH,0EDH,0EBH,0E7H,0DEH ;0,1,2,3,4, 顺序码
DB 0DDH,0DBH,0D7H,0BEH,0BDH ;5,6,7,8,9,
DB 0BBH,0B7H,07EH,07DH,07BH ;A,B,C,D,E,
DB 077H,0FFH ;F 0FF为结束码

DB 0DBH,0EEH,0DEH,0BEH,07EH ;0,1,2,3,4, 顺序码
DB 0EDH,0DDH,0BDH,07DH,0EBH ;5,6,7,8,9,
DB 0BBH,07BH,0E7H,0D7H,0B7H ;A,B,C,D,E,
DB 077H,067H,066H,065H,0FFH ;F,C+F,1+F,8+C
INIT_TIMER: ;初始化定时器
MOV TMOD,#01H ;设置定时器0 工作模式为模式1
MOV IE, #82H ;启用定时器0 中断产生
MOV TL0,#TLOW
MOV TH0,#THIGH
RET
T0_INT:
PUSH ACC
MOV TL0,#TLOW
MOV TH0,#THIGH
INC D_TIME
MOV A,D_TIME ;5ms 计数值加1
CJNE A,#COUN0,T0_T
MOV D_TIME,#0
INC SEC ;秒加1
MOV A,SEC
CJNE A,#03H,TO_INT0
SETB 20H.3
TO_INT0: CJNE A,#8,T0_T ;是否到8秒?
MOV SEC,#0 ;秒单元清0
SETB 20H.0
T0_T: POP ACC
RETI
PASS_READ:
CALL EEPR
RET

MOV COUN1,#06H ;6位密码数值
MOV R7,#00H
MOV R1,#PASS_NEW
P_READ: MOV A,R7
MOV DPTR,#R_TABLE
MOVC A,@A+DPTR
MOV @R1,A
INC R1
INC R7
DJNZ COUN1,P_READ
RET
R_TABLE:
DB 35H,36H,34H,34H,38H,38H
COMP_ERR:
MOV DPTR,#COMP_ERR1 ;
MOV A,#2 ;
CALL LCD_SHOW
RET
COMP_ERR1:
DB " PASSWORD ERROR ",0
COMP_OK:
MOV DPTR,#COMP_OK0 ;
MOV A,#2 ;
CALL LCD_SHOW
RET
COMP_OK0:
DB " PASSWORD RIGHT ",0
RESET_ERR:
MOV DPTR,#RESET_ERR0 ;
MOV A,#2 ;
CALL LCD_SHOW
RET
RESET_ERR0:
DB " RESET ERROR ",0
RESET_OK:
MOV DPTR,#RESET_OK0 ;
MOV A,#2 ;
CALL LCD_SHOW
RET
RESET_OK0:
DB " RESET RIGHT ",0
INPUT_ERR:
MOV DPTR,#INPUT_ERR0 ;
MOV A,#2 ;
CALL LCD_SHOW
RET
INPUT_ERR0:
DB " INPUT ERROR ",0
INPUT_OK:
MOV DPTR,#INPUT_OK0 ;
MOV A,#2 ;
CALL LCD_SHOW
RET
INPUT_OK0:
DB " INPUT RIGHT ",0
EEPW: PUSH ACC
PUSH PSW
CLR PSW.3
SETB PSW.4
MOV R1,#PASS_NEW
MOV R7,#06H ;连续写8个字节
LCALL START
MOV A,#0A0H ;送器件地址
ACALL SUBS
MOV A,#00H ;送片内字节地址
ACALL SUBS
AGAIN1:
MOV A,@R1
ACALL SUBS ;调发送单字节子程序
INC R1
DJNZ R7,AGAIN1 ;连续写8个字节
LCALL STOP ;发停止信号
POP PSW
POP ACC
RET
SUBS:
MOV R0,#08H ;发送单字节子程序
LOOP: CLR SCLK24
RLC A
MOV SDA,C
NOP
SETB SCLK24
ACALL DELAY24
DJNZ R0,LOOP ;循环8次送8个bit
CLR SCLK24
ACALL DELAY24
SETB SCLK24
REP: MOV C,SDA
JC REP ;判应答到否,未到则等待
CLR SCLK24
RET

DELAY24:
NOP
NOP
RET
EEPR: PUSH ACC
PUSH PSW
CLR PSW.3
SETB PSW.4
MOV R7,#06H
MOV R1,#PASS_NEW
LCALL START ;发开始信号
MOV A,#0A0H ;送器件地址
ACALL SUBS ;调发送单字节子程序
MOV A,#00H ;送片内字节地址
ACALL SUBS
LCALL START ;再发开始信号
MOV A,#0A1H
ACALL SUBS
MORE: ACALL SUBR
MOV @R1,A
MOV A,#00H
INC R1
DJNZ R7,MORE
LCALL STOP ;送停止信号
POP PSW
POP ACC
RET

SUBR: MOV R0,#08H ;接受单字节子程序
SUBR2: SETB SCLK24
ACALL DELAY24
MOV C,SDA
RLC A
CLR SCLK24
ACALL DELAY24
DJNZ R0,SUBR2
CJNE R7,#01H,ALOW
SETB SDA ;若是最后一个字节置SDA=1
AJMP SETOK
ALOW:
CLR SDA ;否则置SDA=0
SETOK: ACALL DELAY24
SETB SCLK24
ACALL DELAY24
CLR SCLK24
ACALL DELAY24
SETB SDA ;应答毕,SDA置1
RET
START:
CLR SDA
ACALL DELAY24
SETB SDA
SETB SCLK24
ACALL DELAY24
CLR SDA
SETB SCLK24
RET
STOP:
CLR SDA
SETB SCLK24
ACALL DELAY24
SETB SDA
ACALL DELAY24
RET
BZ: ;蜂鸣器
MOV R6,#100
B1: CALL DEX
CPL BEEP
DJNZ R6,B1
MOV R5,#20
CALL DELAY
RET
DEX: MOV R7,#180
DE1: NOP
DJNZ R7,DE1
RET
END

‘拾’ 求51单片机C语言编的密码锁程序

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
#define BIN(a,b,c,d,e,f,g,h) ((a<<7)+(b<<6)+(c<<5)+(d<<4)+(e<<3)+(f<<2)+(g<<1)+(h<<0))
//下面的code表示数组存放在ROM中,因为这个数组的值不需要改写
uchar code KeyCode[16]={15,14,12,8,30,28,24,16,60,56,48,32,120,112,96,64};//值为m*(n+1)的乘积,用于Key()
uchar dis[6];
msdelay(uint x)//延时子函数
{uchar j;
while(x--)
{for(j=0;j<125;j++){;}
}
}
//键盘子程序一,键盘值与数组值对比得到
uchar Key(void)
{uchar temp,m,n,i,j,matrix,k;
P1=0xF0; /*行线电平为高,列线为低*/
temp=P1&0xf0;
if (temp==0xf0) return(16); /*行仍为高,无按健,退出*/
else msdelay(10);
for(i=1;i<16;i=i*2)
{m=i;
for(j=1;j<16;j=j*2)
{n=(~j)&0x0f;
P1=(m<<4)|n; /*m为P1的行值由i循环得到,n为列值,由j循环并取反得到*/
temp=P1&0xf0;
if (!temp)
{do{temp=P1&0xf0;}while(!temp);
matrix=m*(n+1);/*为避免乘积重复,n+1*/
for(k=0;k<16;k++){if (matrix==KeyCode[k]) return(k);} //KeyCode:见前
return(16);
} //if loop
}//j loop
}//i loop
}//Key end
//用Switch...case语句得到键盘值*/
uchar Key1(void)
{uchar temp,m,n,i,j,matrix;
P1=0xF0; /*行线电平为高,列线为低*/
temp=P1&0xf0;
if (temp==0xf0) return(16); /*行仍为高,无按健,退出*/
else msdelay(10);
for(i=1;i<16;i=i*2)
{m=i;
for(j=1;j<16;j=j*2)
{n=(~j)&0x0f;
P1=(m<<4)|n;/*m为P1的行值由i循环得到,n为列值,由j循环并取反得到*/
temp=P1&0xf0;
if (!temp)
{do{temp=P1&0xf0;}while(!temp);
matrix=m*(n+1);
switch(matrix) //此方法的基本思路:
{case 15:return(1); break; //由循环得到的m,n值赋于P1端口实现逐个键扫描
case 14:return(2); break; //同时由m,n+1的值相乘得到对应键点de的积
case 12:return(3); break; //m*(n+1)值扫描键点对应而得出键值
case 8:return(4); break; //
case 30:return(5); break; //
case 28:return(6); break; //
case 24:return(7); break; //
case 16:return(8); break;
case 60:return(9); break;
case 56:return(0); break;
case 48:return(10); break;
case 32:return(11); break;
case 120:return(12); break;
case 112:return(13); break;
case 96:return(14); break;
case 64:return(15); break;
default:return(16);
} //switch end
} //if loop
}//j loop
}//i loop
}//Key end
//依次扫描16个按键
uchar Key2(void)
{uchar temp;
P1=0xF0; /*使P1=1111 0000,行线电平为高,列线为低*/
temp=P1&0xf0;
if (temp==0xf0) return(16); /*读P1=1111 xxxx,表示行仍为高,无按健,退出(x表示不关心)?/
else msdelay(10);
P1=0x1e; /*P1=0001 1110,行一为高,列一为低,扫描第一个按键*/
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(1);}
P1=0x1d; /*P1=0001 1101,行一为高,列二为低,扫描第二个按键,下面扫描其余按键*/
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(2);}
P1=0x1b;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(3);}
P1=0x17;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(4);}
P1=0x2e;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(5);}
P1=0x2d;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(6);}
P1=0x2b;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(7);}
P1=0x27;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(8);}
P1=0x4e;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(9);}
P1=0x4d;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(0);}
P1=0x4b;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(10);}
P1=0x47;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(11);}
P1=0x8e;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(12);}
P1=0x8d;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(13);}
P1=0x8b;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(14);}
P1=0x87;
temp=P1&0xf0;
if (!temp) {do{temp=P1&0xf0;}while(!temp);
return(15);}

return(16); //扫描all按键都未按下,则输出16
}//Key2 end.
////////时钟中断显示子程序
void T0_int() interrupt 1
{static uchar i;
if (i==6){i=0;}
P0=5-i;
P0=P0|(dis[i]<<4);
i++;
TL0=0;
TH0=252;}

void distri(uint disnum)
{uint temp;
dis[0]=0;
dis[1]=disnum/10000;
temp=disnum%10000;
dis[2]=temp/1000;
temp=temp%1000;
dis[3]=temp/100;
temp=temp%100;
dis[4]=temp/10;
dis[5]=temp%10;
}
Main()
{uchar KeyVal,i=0;
TMOD=0x01;
IE=0x82;
TH0=252;
TL0=0;
TR0=1;
distri(0);
do{
KeyVal=Key();
if (KeyVal!=16) dis[1]=KeyVal; //注意:当有按键时才赋于显示位dis[1],否则出错,请分析!
}while(1);
}

阅读全文

与密码锁单片机程序相关的资料

热点内容
安卓手机没有声音均衡器怎么办 浏览:504
吃鸡国际服为什么会服务器匆忙 浏览:246
微信中如何打开定位服务器 浏览:203
java并发编程书籍 浏览:280
android601源码 浏览:788
程序员离职了还能干嘛 浏览:156
少林功法pdf 浏览:471
安卓80版本小游戏怎么玩 浏览:632
奇书pdf 浏览:836
服务器的管理口有什么用 浏览:641
澳洲加密资产新政策 浏览:155
哈利波特连接服务器失败什么意思 浏览:234
提取手机上安装的app并反编译 浏览:964
人工智能算法书 浏览:604
安卓如何传输图片给苹果 浏览:829
可编程控制器原理应用网络 浏览:587
社畜解压是什么意思 浏览:436
吉利博越用哪个app啊 浏览:513
西安单片机晶振电容 浏览:187
分地面积的算法 浏览:179