找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11147|回复: 16
打印 上一主题 下一主题
收起左侧

基于单片机的密码锁程序-1602液晶显示

  [复制链接]
跳转到指定楼层
楼主


一共分为好几个文件
#include "delay.h"文件:
/*------------------------------------------------
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);
}
}



#include "eeprom.h"文件:
#include "delay.h"
void Start(void) //I2开始
{
    SDA=1;
    SCL=1;
    NOP4();
    SDA=0;
    NOP4();
    SCL=0;
}
void Stop(void)     //I2C停止
{
    SDA=0;
    SCL=0;
    NOP4();
    SCL=1;
    NOP4();
    SDA=1;
}
void RACK(void)      //读取应答
{
    SDA=1;
    NOP4();
    SCL=1;
    NOP4();
    SCL=0;
}
void NO_ACK(void)       //发送非应答信号
{
    SDA=1;
    SCL=1;
    NOP4();
    SCL=0;
    SDA=0;
}
void Write_A_Byte(uchar b)      //写一个字节数据
{
    uchar i;
    for(i=0;i<8;i++)
    {
       b<<=1;
       SDA=CY;     //CY进位程序状态字寄存器
       _nop_();
       SCL=1;
       NOP4();
       SCL=0;
    }
    RACK();
}
void Write_IIC(uchar addr,uchar dat)   //向指写地地址写数据
{
    Start();
    Write_A_Byte(0xa0);
    Write_A_Byte(addr);
    Write_A_Byte(dat);
    Stop();
    DelayMs(10);
}
uchar Read_A_Byte(void)        //读取一个字节
{
    uchar i,b;
    for(i=0;i<8;i++)
    {
       SCL=1;
       b<<=1;
       b|=SDA;
       SCL=0;
    }
    return b;
}
uchar Read_Current(void)   //从当前地址取数据
{
    uchar d;
    Start();
    Write_A_Byte(0xa1);
    d=Read_A_Byte();
    NO_ACK();
    Stop();
    return d;
}
uchar Random_Read(uchar addr)      //从任意地址读取数据
{
    Start();
    Write_A_Byte(0xa0);
    Write_A_Byte(addr);
    Stop();
    return Read_Current();
}
#include "key.h"
unsigned char key_scan()
{
    unsigned char temp,keyno;

    P1=0x0f;
    DelayMs(1);
    temp=P1^0x0f;
    switch(temp)                    //纵行
       {
           case1:keyno=1/*1*/;break; //第一纵行  
           case2:keyno=2/*2*/;break; //第二纵行
           case4:keyno=3/*3*/;break; //第三纵行
           case8:keyno=4/*3*/;break; //第四纵行  
       }
    P1=0xf0;
    DelayMs(1);
    temp=P1>>4^0x0f;
    switch(temp)
       {                            //横行
           case 1:keyno+=0  /*A*/;break;//第一行横行
           case 2:keyno+=4  /*B*/;break;//第一行横行
           case 4:keyno+=8  /*C*/;break;//第一行横行
           case 8:keyno+=12  /*D*/;break;//第一行横行   
       }
       P1=0x0f;
       return keyno;
}   





#include"LCD.H"文件
void write_com(unsigned char com) //写命令
{
    RS_CLR;
    RW_CLR;
    P0=com;
    DelayMs(5);
    EN_SET;
    DelayMs(5);
    EN_CLR;
}
void write_data(unsigned char date)    //写一个字符
{
    RS_SET;
    RW_CLR;
    P0=date;
    DelayMs(5);
    EN_SET;
    DelayMs(5);
    EN_CLR;
}
void init()          //初始化
{
    write_com(0x38);
    write_com(0x0c);
    write_com(0x06);
    write_com(0x01);
}
/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsignedchar x,unsigned char y,unsigned char *s)
{     
if (y == 0)
    {     
     write_com(0x80 + x);     
    }
else
    {     
    write_com(0xC0+ x);     
    }        
while (*s)
    {     
write_data( *s);     
s ++;     
    }
}
/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned charx,unsigned char y,unsigned char Data)
{     
if (y == 0)
    {     
    write_com(0x80+ x);     
    }   
else
    {     
    write_com(0xC0+ x);     
    }        
write_data(Data);  
}



主文件
#include <REGX52.H>
#include <intrins.h>
#include "lcd.h"
#include "key.h"
#include "delay.h"
#include "eeprom.h"
void int0(void);
unsigned char password[6]/*={0x01,0x01,0x01,0x01,0x01,0x01}*/;
unsigned char password1[6];
unsigned char code aa[]="Password   ";
unsigned char code gg[]="New";
unsigned char code bb[]="ERROR  ";
unsigned char code cc[]="OK      ";
unsigned char code dd[]="       ";
unsigned char code ee[]="Next   ";
unsigned char code ff[]="success ";
unsigned char keydata;
main()
{
    unsigned char i,j,k,l,m,n,o,a1;
    /*for(i=0;i<6;i++)
    {
    Write_IIC(i,password[ i]);
    }*/
    init();//LCD初始化
    int0();
    P3_6=0;
    P3_7=0;
    P1=0x0f;
    LCD_Write_String(0,0,aa);
    LCD_Write_String(1,1,dd);
    write_com(0xc0+1);
    while(1)
    {
start: LCD_Write_String(0,0,aa);
       LCD_Write_String(1,1,dd);
       write_com(0xc0+1);

       while(1)
       {
           if((0<keydata)&&(4>keydata)||(4<keydata)&&(8>keydata)||(8<keydata)&&(12>keydata)||keydata==14)
                  //在0-9之间的数字通过
           {   
              password=keydata;//键盘值进行保存
              keydata=0;        //把键盘值置其它值,不被其它利用,以一样
              i++;
              write_data('*');  //在LCD上显示*这字符代表输入了一个密码      
              if(i==6)          //这里限制了六位密码
              {
                  i=0;
                  goto panduan;
              }

           }
           if(keydata==33)      //确定进入密码比较
           {
              keydata=0;
panduan:      i=0;
              for(j=0;j<6;j++)
              {
                  l+=password[j];
                  k+=Random_Read(j);
              }
              if(l!=k)      //密码不同进行处理
              {
                  l=0;
                  k=0;
                  LCD_Write_String(0,0,bb);
                  DelayMs(1000);
                  a1+=1;
                  if(a1==2){while(1)P3_7=1;P3_6=0;}//两次错误发出报警
                  goto start;               //第二次输入密码
              }
              if(l==k)   //密码对了,进入运行状态,这里绿灯代表该状态
              {
                   l=0;
                   k=0;
                   a1=0;
                   P3_6=1;
                   P3_7=0;
                   LCD_Write_String(0,0,cc);
                   LCD_Write_String(1,1,dd);
                   if(o==1)
                   {
                    o=0;
                    LCD_Write_String(0,0,gg);
                    LCD_Write_String(4,0,aa);
                    LCD_Write_String(1,1,dd);
                    write_com(0xc0+1);
                    goto text2;
                   }
                   goto yingxing;        //跳到下面函数中,yingxing里
              }
           }

       }
yingxing:while(1)
       {
           if(keydata==4)    //锁定功能
           {
              P3_6=0;
              goto start;
           }
           if(keydata==15)      //修改密码
           {   
              o++;
              if(o==1) goto start;
text2:        keydata=0;
              while(1)
              {
                  if((0<keydata)&&(4>keydata)||(4<keydata)&&(8>keydata)||(8<keydata)&&(12>keydata)||keydata==14)
                         //上面表达式0-9之间的数字通过
                  {   
                     password[m]=keydata;  //读取键盘值
                     keydata=0;
                     m++;
                     write_data('*');         
                     if(m==6)           //到密码输入到六位的时候进行判断是否再输入,或者判断前后两次密码是否一致
                     {
                         m=0;
                         n++;
                         if(n==2)goto panduan1;  //输入第二次的时候进行前后两次密码进判断
                         for(i=0;i<6;i++)      //储存前一次密码
                         {
                            password1=password[ i];
                         }
                         LCD_Write_String(1,1,dd);
                         LCD_Write_String(0,0,ee);
                         DelayMs(1000);
                         LCD_Write_String(0,0,aa);
                         write_com(0xc0+1);  
                     }   

                   }
                  if(keydata==13)     //重新输入改密
                   {
text:                 m=0;
                     n=0;
                     LCD_Write_String(1,1,dd);
                     write_com(0xc0+1);

                   }
                  if(keydata==33)    //退出不改密码
                  {
out:                 m=0;
                     n=0;
                     o=0;
                     LCD_Write_String(0,0,cc);
                     LCD_Write_String(1,1,dd);
                     goto yingxing;
                  }
                  if(keydata==33)
                  {
                     keydata=0;
panduan1:            for(j=0;j<6;j++)//第一次与第二次密码比较
                     {
                         l+=password[j];
                         k+=password1[j];
                     }
                     if(l!=k)      //第一次与第二次密码输入错误
                     {
                         l=0;
                         k=0;
                         LCD_Write_String(0,0,bb);
                         DelayMs(1000);
                         LCD_Write_String(0,0,aa);
                         goto text;
                     }
                      else
                     {
                         for(i=0;i<6;i++)
                         {
                            Write_IIC(i,password[ i]);
                         }
                           LCD_Write_String(0,0,ff);
                           DelayMs(1000);
                           goto out;   
                     }

                  }

              }
           }   
       }   
    }      
}
void int0(void)
{
    EA=1;
    EX0=1;
    IT0=1;
}
void ISR_INT0(void) interrupt 0
{
    keydata=key_scan();      
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:68208 发表于 2014-11-1 09:47 | 显示全部楼层
漂亮,非常有用啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表