AT89C51单片机制作一个密码锁)
前言
设计一个基本实现密码锁功能的程序开发,作者实测实物有效,且在后来添加了红外功能,其再次可开发性是很好的。采用模块式编程,易懂易理解,作者大二写的,所以可以用作课程设计。
所需基础
1、C语言基础
2、有一点单片机编程语法基础
3、了解AT89C51芯片的管脚分布以及其电平驱动逻辑
工具准备
1、Keil uVision4
2、如果是刚开始学习单片机的伙伴对于89的管脚不是很熟悉的话,建议这个项目还是安装一下Protel99se,这个工具的使用阐述了,网上有很多基础教程,一看就懂。老手跳过。
代码截图
模块使用介绍
项目由几个模块组成,如截图所示:LCD1602+24C02+MODIFYKEY+MAIN,1602用于信息的显示,是一块显示屏;24c02是一块小芯片,用于保存密码;modifykey是密码修改模块,将他单独放出也是为了避免一下不必要的错误,main函数主要是键值判断和存储密码。设计不涉及中断,当然你要去加别的模块,当然是需要中断的,不介绍了。
由于找不到原来的电路图了,只有这个带红外的了,网上找了一张,参考一下,如果代码看懂了,那你也知道哪个线在哪。键盘矩阵的话当时要求自己焊接,但是自己焊接的真的太丑了,不如买一个薄膜的又好看又好用。
必学几部分
接下来就开始讲主要的函数,主要分为:1、键值判断 2、密码修改 3、1602显示屏显示函数 4、24c02存储
键值判断
全局变量定义
#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
#include "i2c.h"
#include "1602.h"
#include "modifykey.h"
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit led=P2^2;
sbit Beep_P=P2^4;
u8 p[]={" pass "} ;
u8 l[]={" loss "} ;
u8 start[]={"input password: "} ;
u16 num=0;
u8 keybord,s=0;
u16 passkey=12345;
int adminkey=199607;
键值判断函数Getch
void Getch ( ) //取键值函数
{char a=0,b=0,c=0;
u8 X,Y,Z;
GPIO_KEY=0x0f; //先对P3 置数 行扫描
if(GPIO_KEY!=0x0f) //判断是否有键按下
{
delay1(1000); //延时,软件去干扰
if(GPIO_KEY!=0x0f) //确认按键按下
{
X=GPIO_KEY; //保存行扫描时有键按下时状态
GPIO_KEY=0xf0; //列扫描
Y=GPIO_KEY; //保存列扫描时有键按下时状态
Z=X|Y; //取出键值
/*********************************************************************/
switch ( Z ) //判断键值(那一个键按下)
{
case 0xeb: keybord=0;num=num*10+keybord;LcdWriteData('*');delay1(1000); break; //对键值赋值
case 0x77: keybord=1;num=num*10+keybord;LcdWriteData('*');delay1(1000); break;
case 0x7b: keybord=2;num=num*10+keybord;LcdWriteData('*');delay1(1000); break;
case 0x7d: keybord=3;num=num*10+keybord;LcdWriteData('*');delay1(1000); break;
case 0xb7: keybord=4;num=num*10+keybord;LcdWriteData('*');delay1(1000); break;
case 0xbb: keybord=5;num=num*10+keybord;LcdWriteData('*');delay1(1000); break;
case 0xbd: keybord=6;num=num*10+keybord;LcdWriteData('*');delay1(1000); break;
case 0xd7: keybord=7;num=num*10+keybord;LcdWriteData('*');delay1(1000); break;
case 0xdb: keybord=8;num=num*10+keybord;LcdWriteData('*');delay1(1000); break;
case 0xdd: keybord=9;num=num*10+keybord;LcdWriteData('*');delay1(1000);break;
case 0xde: num=num/10;b=0;c=num;LcdWriteCom(0x01);while(c!=0){c=c/10;b++;}for(;b>0;b--){LcdWriteData('*');delay1(1000);}b=0;c=0;break; //除位
case 0x7e: if(num==passkey||num==adminkey){led=1;
while(p[b]!='\0'){LcdWriteData(p[b]);b++;};delay1(40000);delay1(40000);b=0;delay1(40000);LcdWriteCom(0x01);
delay1(1000);passkey=modifypassword();storageInit(passkey);delay1(10000);delay1(20000);delay1(20000);delay1(20000);led=0;}
else {while(l[b]!='\0'){LcdWriteData(l[b]);b++;};MingJiao();delay1(40000);delay1(40000);b=0;delay1(40000);LcdWriteCom(0x01);delay1(1000);}
num=0;LcdWriteCom(0x01);break; //密码确认
default : num=num;break;
}
while((a<50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测
{
delay1(1000);
a++;
}
}
}
}
头文件意义
#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
#include "i2c.h"
#include "1602.h"
#include "modifykey.h"
为什么引入头文件,单片机中引入模块,引入函数,就一定引入头文件,因为有哪些函数,用什么格式,针对哪种单片机都是在头文件中定义的,24c02举例,I2C.H
#ifndef __I2C_H_
#define __I2C_H_
#include <reg52.h>
sbit SCL=P2^1;
sbit SDA=P2^0;
void I2cStart();
void I2cStop();
unsigned char I2cSendByte(unsigned char dat);
unsigned char I2cReadByte();
void At24c02Write(unsigned char addr,unsigned char dat);
unsigned char At24c02Read(unsigned char addr);
#endif
声明名称
引入reg52头文件,带入管脚
定义24c02芯片连接管脚,SCL时钟管脚连接2.1,SDA数据管脚连接2.0
定义相关函数
结束定义 endif
typedef 和 sbit方法
typedef用于简化变量的定义,typedef unsigned int u16; 那么 u16 a 等同于 unsigned int a
sbit 定义管脚名称
当然模块头文件也可以声明如此定义,但是不建议,避免不必要的麻烦,建议使用全名,仅仅在main函数去定义,但是这种头文件定义是可以的
//---重定义关键词---//
//#ifndef uchar
//#define uchar unsigned char
//#endif
//#ifndef uint
//#define uint unsigned int
//#endif
键值判断case 0xeb
那么0xeb怎么来的呢,我们看到电路图,
现在我把P17置高电平,也就是置1,当我按下s14的时候,p17和p10之间导通,p10接收到来自于p17的高电平,这时候单片机可以进行判断,if p10 = 1:XXX;而现实中,我们一般将P14到P17置1,P10到P13置0,也就是P1为0x0f,oxfo是转化为2进制也就是:0000 1111;很显然了就,同样电平由于按键更改P1的值也就发生了短暂的变化。
modifykey
一个修改密码的函数为什么要单独拿出来呢,首先是逻辑,先修改临时密码变量,然后再进行判断。其次,加强可读性,最后也是最重要的,当你按键的时候,是两个操作在进行,1、在lcd上显示*表示你键入了一个值,2、在密码变量中保存这个值。同时我们知道这两个操作是没有办法同时进行的,所以分解。
LCD1602、24C02
这两个模块建议单独进行练习和学习,也是很独立的两个模块,别人已经单独给你封装好勒读懂直接用。
学习建议
淘宝买一个开发板进行学习,也就60块钱,不打广告,随便推一个吧,反正客服嗯哼大家也知道,产品无质量问题就行了。https://detail.tmall.com/item.htm?spm=a230r.1.14.15.7f3a4a62vSMiOV&id=36522460231&ns=1&abbucket=8
祝各位学习愉快,代码地址 提取码:f6ax