单片机电子密码锁带时钟.docx
- 文档编号:8410247
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:20
- 大小:31.45KB
单片机电子密码锁带时钟.docx
《单片机电子密码锁带时钟.docx》由会员分享,可在线阅读,更多相关《单片机电子密码锁带时钟.docx(20页珍藏版)》请在冰豆网上搜索。
单片机电子密码锁带时钟
//――――――――――――――――――
//MAIN.c文件,主函数
//――――――――――――――――――
//--------------------------------------------------------------------------
//名称:
用1602LCD与24C04设计的电子密码锁
//--------------------------------------------------------------------------
//说明:
初始密码由24C04.bin设定为123456.
//当输入0-9中的数字时可以输入密码,不超过6位,输入完成后按下A键开锁,
//密码正确时LED点亮,液晶屏显示开锁成功。
//其他按键功能是:
B---上锁C---重新输入密码D---保存密码E---清除
//重设密码时要求先输入正确的密码成功开锁
//--------------------------------------------------------------------------
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineDelay4us(){_nop_();_nop_();_nop_();_nop_();}
ucharcodeHI_LIST[]={0,226,229,232,233,236,238,240,241,242,244,245,246,247,248};
ucharcodeLO_LIST[]={0,4,13,10,20,3,8,6,2,23,5,26,1,4,3};
ucharcodeSong_24c04[]={1,2,3,1,1,2,3,1,3,4,5,3,4,5};
ucharsidx;//读取的音符索引
ucharKeyNo=16;
uchari=0;
ucharIIC_Password[10];
ucharIS_Valid_User=0;
ucharcodeTitle_Text[]="YourPassword...";
ucharDSY_BUFFER[10]="";//显示缓冲
ucharUserPassword[10]="";//用户输入的密码
voidInitialize_LCD();
voidSet_Disp_Pos(ucharpos);
voidWrite_LCD_Data(uchardat);
voidDisplay_String(uchar*str,ucharLineNO);//在液晶指定行显示字符串
voidIIC_24C04_Init();//IIC初始化
voidBeep();
voidyinyue();
voidWrite_LCD_Command(ucharcmd);
ucharRecString(ucharSlave,ucharSubsddr,uchar*Buffer,ucharN);//从IIC读取数据
ucharSendString(ucharSlave,ucharSubsddr,uchar*Buffer,ucharN);//向IIC写入数据
ucharKeys_Scan();//键盘扫描
voidboss();
sbitLED_OPEN=P2^4;//开锁亮灯
sbitBEEP=P3^7;//蜂鸣器
sbitRS=P2^7;
sbitRW=P2^6;
sbitEN=P2^5;
sbitSCL=P3^2;
sbitSDA=P3^3;
//-------------------------------------
//延时
//-------------------------------------
voidDelayXus(uintx)
{
uchari;
while(x--)for(i=0;i<120;i++);
}
//-------------------------------------
//蜂鸣器子程序
//-------------------------------------
voidBeep()
{
uchari;
for(i=0;i<100;i++)
{
DelayXus
(1);
BEEP=~BEEP;
}
BEEP=0;
}
//-------------------------------------
//清除密码
//-------------------------------------
voidClear_Password()
{
UserPassword[0]='\0';
DSY_BUFFER[0]='\0';
}
voidDisplay_String(uchar*str,ucharLineNO)
{
uchari;
Write_LCD_Command(LineNO|0x80);
for(i=0;i<=strlen(str);i++)
{
Write_LCD_Data(str[i]);
}
}
//-----------------------------------------------------------------
//主程序
//-----------------------------------------------------------------
voidmain()
{
P0=0xFF;
P1=0xFF;
P2=0xFF;
IE=0x82;//允许T0中断
TMOD=0x00;
//TMOD=0x02;//T0设置为8位自动重装模式
//TH0=175;
//TL0=175;
//TR0=1;//启动T0
DelayXus(10);
Initialize_LCD();//初始化LCD
IIC_24C04_Init();//初始化24C04
Display_String(Title_Text,0x00);//在第1行显示标题
RecString(0xa0,0,IIC_Password,6);
IIC_Password[0]='\0';
UserPassword[0]='\0';
while
(1)
{
boss();
Beep();
DelayXus(100);
P1=0xF0;
while(P1!
=0xF0);//如果有键未释放则等待
while(P1==0xF0);//如果没有再次按下按键则等待
}
}
//----------------------------------------LCD1602.C----------------------------
//液晶控制与显示程序
//延时
//-------------------------------------
voidDelayMS(uintms)
{
uchari;
while(ms--)for(i=0;i<120;i++);
}
//------------------------------------
//忙检查
//------------------------------------
ucharBusy_Check()
{
ucharLCD_Status;
RS=0;//RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
RW=1;//R/W为读写信号线,高电平
(1)时进行读操作,低电平(0)时进行写操作
EN=1;//E(或EN)端为使能(enable)端,下降沿使能,下跳变时液晶屏开始执行命令
DelayMS
(1);
LCD_Status=P0;//DB9为高4位三态、双向数据总线7位(最高位)(也是busyflag)
EN=0;
returnLCD_Status;
}
//-----------------------------
//写LCD命令
//---------------------------------
voidWrite_LCD_Command(ucharcmd)
{
while((Busy_Check()&0x80)==0x80);//忙等待
RS=0;//低电平0时选择指令寄存器
RW=0;//低电平(0)时进行写操作
EN=0;//写指令时,E为高脉冲,即让E从0到1发生正跳变,应先置0
P0=cmd;
EN=1;//产生正跳变
DelayMS
(1);
EN=0;
}
//-----------------------------
//设置LCD显示位置
//---------------------------------
voidSet_Disp_Pos(ucharpos)
{
Write_LCD_Command(pos|0x80);
}
//-----------------------------
//发送数据
//---------------------------------
voidWrite_LCD_Data(uchardat)
{
while((Busy_Check()&0x80)==0x80);//忙等待
RS=1;//高电平1时选择数据寄存器
RW=0;//低电平(0)时进行写操作
EN=0;
P0=dat;
EN=1;
DelayMS
(1);
EN=0;
}
//-----------------------------
//LCD初始化
//---------------------------------
voidInitialize_LCD()
{
Write_LCD_Command(0x38);//设置16×2显示,5×7点阵,8位数据接口
DelayMS
(1);
Write_LCD_Command(0x01);//显示清屏,数据指针=0,所有显示=0
DelayMS
(1);
Write_LCD_Command(0x06);//写指令06H置字符输入模式:
屏幕不动,字符后移
DelayMS
(1);
Write_LCD_Command(0x0c);//显示开,关光标
DelayMS
(1);
}
/*
//----------------------------------
//显示字符串
//---------------------------------
voidShowString(ucharx,uchary,uchar*str)
{
uchari=0;
if(y==0)Write_LCD_Command(0x80|x);//以下设置显示起始位置
if(y==1)Write_LCD_Command(0xc0|x);//1602型LCD字符显示位置的确定方法规定为:
80H+地址码,注意可以设置显示位置
//第二行行首地址:
80H+40H=0CH教材
P287
for(i=0;i<16;i++)//输出字符串
{
Write_LCD_Data(str[i]);
}
}
*/
//-----------------------------------------------------------------------
//1602型LCD内部地址参照教材P287,1602型字符显示位置的确定方法规定为80H+地址码(00-0FH40-4FH)
//如要将字符显示在第2行第6列,则确定地址的指令代码应为80H+45H=C5H
//--------------------------------------------------------------------------
//----------------------------24C04.c--------------------------------
//24C04IIC读/写程序
//-------------------------------------------------------------------
//-------------------------------------
//延时
//-------------------------------------
voidDeslayMS(uintx)
{
uchari;
while(x--)for(i=0;i<120;i++);
}
//---------------------------------------------------------
//起始位
//---------------------------------------------------------
voidStart()
{
SDA=1;SCL=1;Delay4us();
SDA=0;Delay4us();SCL=0;
}
//---------------------------------------------------------
//停止位
//---------------------------------------------------------
voidStop()
{
SDA=0;SCL=1;Delay4us();
SDA=1;Delay4us();SCL=0;
}
//---------------------------------------------------------
//读取应答每次传送一个字节完毕,必须接收从机发出的一个应答位
//---------------------------------------------------------
voidRACK()
{
SDA=1;Delay4us();SCL=1;Delay4us();SCL=0;
}
//---------------------------------------------------------
//发送应答信号
//---------------------------------------------------------
voidACK()
{
SDA=0;SCL=1;Delay4us();
SCL=0;SDA=1;
}
//---------------------------------------------------------
//发送非应答信号
//---------------------------------------------------------
voidNO_ACK()
{
SDA=1;SCL=1;Delay4us();
SCL=0;SDA=0;
}
//---------------------------------------------------------
//从芯片读取1字节
//---------------------------------------------------------
ucharRecbyte()
{
uchari,rd;
rd=0x00;
SDA=1;
for(i=0;i<8;i++)
{
SCL=1;rd<<=1;
rd|=SDA;
Delay4us();
SCL=0;
Delay4us();
}
SCL=0;
Delay4us();
returnrd;
}
//---------------------------------------------------------
//向芯片发送1字节
//---------------------------------------------------------
ucharSendByte(ucharwd)
{
uchari;
bitack0;
for(i=0;i<8;i++)
{
SDA=(bit)(wd&0x80);
_nop_();_nop_();
SCL=1;Delay4us();
SCL=0;wd<<=1;
}
Delay4us();
SDA=1;//释放总线并准备读取应答
SCL=1;
Delay4us();
ack0=!
SDA;//此SDA为从机发来的应答信号,SDA为0表示应答,为1则为无应答
SCL=0;
Delay4us();
returnack0;//返回应答
}
//---------------------------------------------------------
//向芯片发送多字节数据函数(写多字节)
//---------------------------------------------------------
ucharSendString(ucharSlave,ucharSubaddr,uchar*Buffer,ucharN)
{
uchari;
Start();
if(!
SendByte(Slave))return0;//0xa0器件地址以及写入操作,0xa0即为10100000B
if(!
SendByte(Subaddr))return0;
for(i=0;i { if(! SendByte(Buffer[i]))return0; } Stop(); return1; } //--------------------------------------------------------- //接收多字节数据函数(读多字节) //--------------------------------------------------------- ucharRecString(ucharSlave,ucharSubaddr,uchar*Buffer,ucharN) { uchari; Start(); if(! SendByte(Slave))return0; if(! SendByte(Subaddr))return0; Start(); if(! SendByte(Slave+1))return0;//0xa1器件地址以及读取操作,0xa1即为10100001B for(i=0;i { Buffer[i]=Recbyte();//接收数据 ACK();//发送应答位 } Buffer[N-1]=Recbyte();// NO_ACK();//发送非应答位 Stop(); return1; } //--------------------------------------------------------- //向24C04中写一个字节数据 //数据先通过指令完成移位再从SDA串行输出。 按照时序要求, //数据在SCL低电平时变化,高电平时稳定,每个时钟脉冲传送一位。 //--------------------------------------------------------- voidWrite_A_Byte(ucharb) { uchari; for(i=0;i<8;i++) { b<<=1;SDA=CY;_nop_();SCL=1;Delay4us();SCL=0;//反汇编可以看出左移是x //SDA=(bit)(b&0x80);//通过按位“与”运算将最高位数据? //因为传送时高位在前,低位在后 } RACK(); } //--------------------------------------------------------- //向指定地址写数据 //--------------------------------------------------------- voidWrite_IIC(ucharaddr,uchardat) { Start(); Write_A_Byte(0xa0);//0xa0器件地址以及写入操作,0xa1即为10100000B Write_A_Byte(addr);//芯片内存寻址 Write_A_Byte(dat);// Stop(); DeslayMS(10); } ucharRead_A_Byte() { uchari,b; SDA=1;//可以不要 for(i=0;i<8;i++) { SCL=1;b<<=1;b|=SDA;SCL=0; } returnb; } //--------------------------------------------------------- //从任意地址读取数据 //--------------------------------------------------------- ucharRead_Current() { uchard; Start(); Write_A_Byte(0xa1);//0xa1器件地址以及读取操作,0xa1即为10100001B d=Read_A_Byte(); NO_ACK(); Stop(); returnd; } //--------------------------------------------------------- //从任意地址读取数据 //--------------------------------------------------------- ucharRandom_Read(ucharaddr) { Start(); Write_A_Byte(0xa0); Write_A_Byte(addr); Stop(); returnRead_Current(); } //-------------------------------------------------------- //中断发声换函数 //-------------------------------------------------------- voidT0_INT()interrupt1 { BEEP=! BEEP; TH0=HI_LIST[sidx]; TL0=LO_LIST[sidx]; } //--------------------------------------------------------- //IIC总线初始化 //-------------------------------
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 电子 密码锁 时钟