51单片机为什么需要头文件
为什么要有头文件.H文件
头文件是把芯片内部寄存器地址重新命名,以英文单词组合缩写形式或端口名称,方便其它文件调用。
51内核都有特殊功能寄存器,编译器加入关键字SFR来重新定义寄存器名称,以P0为例
sfr P0 = 0x80;
程序对P0赋值就是对0X80赋值,如果不重新命名,程序易读性太差,要加大量注释才能描述清楚,芯片之间移植差,51单片机中有几十个寄存器,如要都直接写寄存器地址,写程序效率太低。
所以芯片厂家都会给制作好头文件,以便于我们使用特殊功能寄存器,达到见名知易,方便编程,提高效率。
有些情况我们需要位操作,寄存器8个位,不想影响其他位,单独对某个位操作,厂家也给我们提供了定义好的名称,sbit P20 = P2^0;对P20赋值相当于对P2^0赋值,是P2口的一个位。可以灵活操作每个位,控制每个管脚高低电平,对照芯片手册,对每个寄存器控制,操作。
我们也可以自己定义一些变量,函数名,放在头文件中,方便调用。个人理解,如有问题请留言。
51单片机控制的万能密码锁(附仿真文件+源代码)
前几天有小伙伴留言说想知道单片机是怎么样控制密码锁的,正好做过一个类似的实验,下面我分享出来,希望对你们有所帮助。
51单片机控制的万能密码锁系统,PROTEUS仿真文件
初始密码:12345678
此程序用51单片机控制74LS164锁存器来实现
单片机与存储器之间通过IIC 通过通讯来建立密码系统通讯
仿真启动开始设置密码
万能密码锁参考程序源代码:
#include<AT89x51.h>
#include"intrins.h"
#include"key.h"
#include"xsh.h"
#include"24c02.h"
#define ulong unsigned long
bit BJCB=0;//报警标志
XG=0,//修改密码标志位
BJ=0,//报警标志位
SJ=0;//锁键盘标志位
// xg=0;//修改密码标志位
uchar PSWD0_0[16]={0};//密码输入缓存存储单元
//uchar code PSWD0_1[16]={1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8};//用户初始密码存储单元
//uchar PSWD1_0[16]={0};//读出密码缓存存储单元
uchar PSWD1_1[16]={1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8};////管理员初始密码存储单元
sbit OUT=P3^5;//输出端口
sbit L1=P0^2;//上电指示
sbit L2=P0^1;//开锁指示
sbit L3=P0^0;//报警指示
uint mg=0,//密码个数
KSC=0,//开锁次数
BJC=0,//报警次数
TCNTY=0,//用户按键定时次数累加
TCNTG=0,//管理员输入密码定时次数
yhsh,//用户输入标志位
glsh,//管理员输标志位
shw;//密码输入标志位
void yhmimaxig();//密码修改程序
void glmimaxig();//管理员修改程序
void bjyin(ulong t)
{
ulong c;
uint n;
for(c=0;c<t;c++)
{
for(n=0;n<50;n++); //延时
BEEP=~BEEP; //取反输出到喇叭的信号
}
}
void delay_10ms(void)
{
uint i = 1000;
while(i--);
}
//////////////定时中断服务函数//////////////////////////////////////
void timer0() interrupt 1
{
uint i;
TH0=(65536-50000)/256; //对TH0 TL0赋值50MS定时
TL0=(65536-50000)%256; //重装计数初值
if(yhsh==1)
{
TCNTY++;//用户定时计数
if(shw==1)
{
TR0=0;
TCNTY=0;
}
if(TCNTY==400)
{
TR0=0;//关闭T0定时器
TCNTY=0;
mg=0;//密码个数清零
L1=1;
for(i=0;i<2;i++)//声光报警电路
{
L3=0;
bjyin(1000);
L3=1;
delay(1000);
}
L1=0;
}
}
else if(glsh==1)
{
TCNTG++;//管理员定时计数
if(shw==1)
{
TR0=0;
TCNTG=0;
}
if(TCNTG==400)
{
TR0=0;//关闭T0定时器
TCNTG=0;
mg=0;//密码个数清零
L1=1;
for(i=0;i<2;i++)//声光报警电路
{
L3=0;
bjyin(1000);
L3=1;
delay(1000);
}
L1=0;
}
}
}
void main()
{
uint i;
TMOD=0x01; //定时器工作在方式1
ET0=1;
EA=1;
TH0=(65536-50000)/256; //对TH0 TL0赋值
TL0=(65536-50000)%256; //使定时器0.05秒中断一次
//Read_page24c02(0x00,PSWD1_1,16);//向24c02里读用户初始密码
//i2cWrite24LC16B(0,0X20);
/////////////第一次向24c02里写入初始管理员密码、用户密码、开锁次数/////////////////////
for(i=0;i<16;i++) //用一次写一个向24c02里写
{
i2cWrite24LC16B(PSWD1_1[i],i);
delay_10ms;
}
for(i=0;i<16;i++) //用一次写一个向24c02里写
{
i2cWrite24LC16B(PSWD1_1[i],0x10+i);
delay_10ms;
} //proteus仿真时用,烧程序时,第一次用,第二次不用。
KSC=i2cRead24LC16B(0X20);
loop: L1=0;//上电红灯亮
L2=1;//开锁成功后绿灯亮
L3=1;//输错时黄灯亮报警
OUT=0;//开信号关闭
display_0(KSC);//开锁前显示
///////////密码输入/////////////////
if(SJ==0)//锁键盘标志位为0
{
do
{
flag=0;//键盘标志位
key();
if(flag==1&&num==12) //判断是否为管理员功能键按下
{
goto gl;
}
if(flag==1&&num<=9)
{
PSWD0_0[mg]=num;
mg++;//密码个数
}
if(flag==1&&num==14&&mg>=1)//输入错误删除
{
mg=mg-1;
}
if(mg==1) //有密码键按下开定时器限时
{
TR0=1;
yhsh=1;
}
}
while(num!=15);
if(mg!=16)
{
for(i=mg;i<16;i++)
{
PSWD0_0[i]=0;
}
}
/////////////////密码比较电路////////////////////////////
if(flag==1&&num==15)
{ flag=0;
yhsh=0;
shw=1;
num=0;
for(i=0;i<16;i++) //从24c02里读出16个密码
{
PSWD1_1[i]=i2cRead24LC16B(i);
delay_10ms;
}
for(i=0;i<16;i++)
{
if(PSWD1_1[i]!=PSWD0_0[i])
{
BJCB=1;
break;
}
else
BJCB=0;
}
}
if(BJCB!=0)
{
BJC++;
if(BJC!=3)
{
BJCB=0; //第一次和第二次报警
delay(500);
mg=0;//密码个数清零
L1=1;
for(i=0;i<3;i++)//声光报警电路
{
L3=0;
display_3();
bjyin(1000);
L3=1;
delay(1000);
}
goto loop;
}
else if(BJC==3)
{
BJC=0;
BJCB=0;
display_5();//三次输入密码失败,自锁
SJ=1;//锁键盘标志位
mg=0;//密码个数清零
L1=1;
for(i=0;i<2;i++)//声光报警电路
{
L3=0;
bjyin(1000);
L3=1;
delay(1000);
}
goto loop;
}
}
else
if(BJCB==0)
{
KSC++;
display_1(KSC);
i2cWrite24LC16B(KSC,0X20);
if(KSC==100)
{
SJ=1;
}
L2=0;
L1=1;
OUT=1;
mg=0;//密码个数清零
loop1:do //键盘扫描等待功能键按下
{
flag=0;
key();
if(flag)
{
flag=0;
switch(num)
{
case 13:
{
display_2();
do
{
flag=0;//键盘标志位
key();
if(flag==1&&num<=9)
{
PSWD0_0[mg]=num;
mg++;//密码个数
}
if(flag==1&&num==14&&mg>=1)//输入错误删除
{
mg=mg-1;
}
if(mg==16)
{
do //键盘扫描等待功能键按下
{
flag=0;
key();
}
while(num!=15);
}
}
while(num!=15);
if(mg!=16&&num==15)
{
for(i=mg;i<16;i++)
{
PSWD0_0[i]=0;
}
}
if(flag==1&&num==15)
{
flag=0;
mg=0;
for(i=0;i<16;i++) //用一次写一个向24c02里写
{
i2cWrite24LC16B(PSWD0_0[i],i);
delay_10ms;
}
display_1(KSC);
do //键盘扫描等待功能键按下
{
flag=0;
key();
}
while(num!=11); //按下返回键,锁锁返回
{
goto loop;
}
}
};break;
case 11: {
goto loop;
//break;
}
}
}
}
while(flag!=0);//如果设置密码键按下
goto loop1;
// i2cWrite24c02_page(0x00,PSWD1_1,mg);
}
}
else
{
do
{
flag=0;
key();
}
while(num!=12);//判断是否为管理员功能键按下
gl:do//管理员输入密码
{
flag=0;
key();
if(flag==1&&num<=9)
{
PSWD0_0[mg]=num;
mg++;//密码个数
}
if(flag==1&&num==14&&mg>=1)//删除键按下
{
mg=mg-1;
}
if(mg==1)
{
TR0=1;
}//开定时器TO限5秒开锁
}
while(num!=15);
if(mg!=16&&num==15)
{
for(i=mg;i<16;i++)
{
PSWD0_0[i]=0;
}
}
//////////管理员密码比较///////////////////////
//Read_page24c02(0x10,PSWD0_1,16)
for(i=0;i<16;i++) //从24c02里读出16个密码
{
PSWD1_1[i]=i2cRead24LC16B((0x10+i));
delay_10ms;
}
if(flag==1&&num==15)
{ flag=0;
shw=1;
num=0;
for(i=0;i<mg;i++)
{
if(PSWD1_1[i]!=PSWD0_0[i])
{ BJCB=1;
break;
}
else
BJCB=0;
}
}
if(BJCB!=0)
{
BJC++;
if(BJC!=3)
{
BJCB=0; //第一次和第二次报警
mg=0;//密码个数清零
L1=1;
for(i=0;i<2;i++)//声光报警电路
{
L3=0;
display_3();
bjyin(1000);
L3=1;
delay(1000);
}
display_1(KSC);
goto loop;
}
else
{
BJCB=0;
display_5();//三次输入密码失败,自锁
mg=0;//密码个数清零
delay(10000);
display_1(KSC);
goto loop;
}
}
else
{
SJ=0;
display_4();//管理员开锁显示
mg=0;
L2=0;
L1=1;
L3=0;//密码个数清零
do //键盘扫描等待功能键按下
{
flag=0;
key();
}
while(flag==0); //如果设置密码键按下
if(flag==1&&num==13)
{
flag=0;
display_2();
do
{
flag=0;//键盘标志位
key();
if(flag==1&&num<=9)
{
PSWD0_0[mg]=num;
mg++;//密码个数
}
if(flag==1&&num==14&&mg>=1)//输入错误删除
{
mg=mg-1;
}
if(mg==16)
{
do //键盘扫描等待功能键按下
{
flag=0;
key();
}
while(num!=15);
}
}
while(num!=15);
if(mg!=16&&num==15)
{
for(i=mg;i<16;i++)
{
PSWD0_0[i]=0;
}
}
if(flag==1&&num==15)
{
flag=0;
mg=0;
for(i=0;i<16;i++) //用一次写一个向24c02里写
{
i2cWrite24LC16B(PSWD0_0[i],(0x10+i));
delay_10ms;
}
display_4();
do //键盘扫描等待功能键按下
{
flag=0;
key();
}
while(num!=11); //按下返回键,锁锁返回
{
goto loop;
}
}
}
if(flag==1&&num==10)
{
KSC=0;
i2cWrite24LC16B(KSC,0X20);
display_1(KSC);
do //键盘扫描等待功能键按下
{
flag=0;
key();
}
while(num!=11);//按下返回键,锁锁返回
goto loop;
}
if(flag==1&&num==11)//按下返回键,锁锁返回
{
goto loop;
}
}
}
}
最后,如果有什么意见或者建议欢迎您留言给我,让我们共同学习一起进步,
如果需要 完整代码或设计文件,请在下方留言或者私信我,看到后会第一时间回复。
谢谢大家!
如果喜欢我的文章请评论转发加关注哦。
相关问答
51单片机 能直接运行的 文件 格式是?51单片机能直接运行的文件是.bin,但编译软件生成的是.hex文件,它们的差别是后者包含了8位地址偏移量,而前者是纯粹的程序代码。在烧录时,下载工具装载的是.h...
C 51单片机头文件 的后缀名是什么?简述它的用途?这个可要看编译软件是什么,源文件大路是*.c,*.h之类的C文件,*.asm之类的宏汇编文件编译后的文件多为*.Hex,*.Bin文件,这些文件可以下载到51单片机...
单片机 可执行 文件 后缀名?可执行文件的扩展名是.HEX,或.BⅠN。现行51单片机编程平在程序编译之后生成的都是.HEX文件,但在程序烧录过程中,下载工具会将hex文件转换为bin格式写入单片机...
51单片机 调用52 头文件 能用吗?51单片机调用52头文件是不可行的。51单片机和52单片机是两种不同的芯片,其体系结构和指令集不同,因此无法直接调用52头文件。51单片机和52单片机是两种常见的...
51单片机 如何建立自己的库 文件 ?立自己的库文件,首先需要编写自己的函数代码,并将其保存在一个独立的文件中。然后,使用编译器将这些函数编译成目标文件,并使用库管理工具将目标文件打包成...
单片机 c语言中delay()函数的 头文件 是什么?delay()函数并不是标准库函数,是编程人员自定义的一个函数(通常是延时函数),所以其并不包含在其他头文件中。下面给出51单片机中一个常见的延时函数。delay(...
51单片机 程序清单怎么写?51单片机程序清单主要包括以下几个部分:头文件:包含单片机的一些寄存器定义和函数声明。宏定义:定义一些常量或者宏函数,方便程序的编写。全局变量:定义程序...
51 子系列 单片机 内部有多少字节ROM?51子系列单片机内部的ROM大小与具体的型号有关。例如,8051型号的51子系列单片机内部有4K字节的ROM。但请注意,不是所有的51子系列单片机都配备了ROM,例如8031...
MCS 51单片机 初始上电时,CPU执行的第1条指令所处的ROM空间地址是?MCS-51单片机上电后(或复位后),首先开始初始化各个寄存器。PC寄存器设置为0000H,于是,程序从0000H开始执行第一条指令。MCS-51单片机上电后(或复位后),首先...
51单片机 都有哪些引脚数量的芯片?一般情况下,51单片机(也称为8051单片机)具有40针、44针和52针三种引脚数量的芯片。其中40针的单片机包括基本的输入输出引脚、定时器、串行通信口等;44针的单...