基于51的智能密码锁

2019-07-18 12:48发布

电路图有了程序哪里不对然后仿真不出来了{:4:}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
我fei跃过
1楼-- · 2019-07-18 18:14
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#include<string.h>


//延时子程序
void DelayMS(uint x)       
{
        uchar i;
        while (x--) for (i =0;i<120;i++);
}        
sbit RS = P2^0;   //定义端口
sbit RW = P2^1;
sbit EN = P2^2;

#define RS_CLR RS=0
#define RS_SET RS=1

#define RW_CLR RW=0
#define RW_SET RW=1

#define EN_CLR EN=0
#define EN_SET EN=1

#define DataPort P0
/*------------------------------------------------
uS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下 T=tx2+5 uS
------------------------------------------------*/


/*------------------------------------------------
              判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void)
{
DataPort= 0xFF;
RS_CLR;
RW_SET;
EN_CLR;
_nop_();
EN_SET;
return (bit)(DataPort & 0x80);
}
/*-----------------------------------------------
              写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com)
{  
//while(LCD_Check_Busy()); //忙则等待
RS_CLR;
RW_CLR;
EN_SET;
DataPort= com;
_nop_();
EN_CLR;
}
/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data)
{
while(LCD_Check_Busy()); //忙则等待
RS_SET;
RW_CLR;
EN_SET;
DataPort=Data;
_nop_();
EN_CLR;
}

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMS(5);
}
/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{     
if (y == 0)
        {     
         LCD_Write_Com(0x80 + x);     //表示第一行
        }
else
        {      
        LCD_Write_Com(0xC0 + x);      //表示第二行
        }        
while (*s)
        {     
LCD_Write_Data( *s);     
s ++;     
        }
}
/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{     
if (y == 0)
        {     
        LCD_Write_Com(0x80 + x);     
        }   
else
        {     
        LCD_Write_Com(0xC0 + x);     
        }        
LCD_Write_Data( Data);  
}
/*------------------------------------------------
              初始化函数
------------------------------------------------*/
void LCD_Init(void)
{
   LCD_Write_Com(0x38);    /*显示模式设置*/
   DelayMS(5);
   LCD_Write_Com(0x38);
   DelayMS(5);
   LCD_Write_Com(0x38);
   DelayMS(5);
   LCD_Write_Com(0x38);  
   LCD_Write_Com(0x08);    /*显示关闭*/
   LCD_Write_Com(0x01);    /*显示清屏*/
   LCD_Write_Com(0x06);    /*显示光标移动设置*/
   DelayMS(5);
   LCD_Write_Com(0x0C);    /*显示开及光标设置*/
   }
   





//24c04 IIC读写程序

#define Delay4us(); {_nop_();_nop_(); _nop_();_nop_();}
sbit SCL =P3^2;                  //串行时钟
sbit SDA =P3^3;                  //串行数据


void Start ()  //起始
{
        SDA = 1; SCL =1;Delay4us(); SDA=0;Delay4us();SCL=0;
}

void Stop ()        //停止
{
        SDA=0 ;SCL=1;Delay4us();SDA=1;Delay4us();SCL=0;
}

void IIC_24C04_Init()//IIC总线初始
{
        SCL =0;
        Stop ();
}

void ACK()          //发送应答信号
{
        SDA=0;SCL=1;Delay4us();SCL=0;SDA=1;
}

void  NO_ACK() // 发送非应答信号
{
        SDA=1;SCL=1;Delay4us();SCL=0;SDA=0;
}

uchar RecByte() //从芯片读取1字节
{
        uchar i,rd;
        rd =0x00;
        SDA=1;
        for(i=0; i<8;i++)
        {
                SCL=1;rd<<=1;rd |=SDA; Delay4us();SCL=0; Delay4us();
        }
        SCL=0;
        Delay4us();
        return rd;
}

uchar SendByte(uchar wd)          //向芯片发送一字节
{
        uchar i;
        bit ack0;
        for(i=0;i<8;i++) //循环移入8位
        {
                SDA =(bit)(wd & 0x80);
                _nop_();
                _nop_();
                 SCL=1;
                Delay4us();
                SCL=0;
                wd<<=1;
        }
        Delay4us();
        SDA=1;//释放总线并准备读取应答
        SCL=1;
        Delay4us();
        ack0= !SDA; //0表示无应答
        SCL=0;
        Delay4us();
        return ack0; //返回应答
}

//发送多字节数据
uchar SendString(uchar Slave,uchar Subaddr,uchar *Buffer,uchar N)
{
        uchar i;
        Start();
        if (!SendByte(Slave))  return 0; //发送器件地址
        if (!SendByte(Subaddr))  return 0; //器件子地址
        for(i=0;i<N;i++)
        {
                if (!SendByte(Buffer[i])) return 0;//发送数据
        }
        Stop();
        return 1 ;
}

//接受多字节数据
uchar RecString(uchar Slave,uchar Subaddr,uchar *Buffer,uchar N)
{
        uchar i;
        Start();
        if (!SendByte(Slave))  return 0; //发送器件地址
        if (!SendByte(Subaddr))  return 0; //器件子地址
        Start();
        if (!SendByte(Slave +1))  return 0; //器件地址,读操作
        for (i=0; i<N-1;i++)
        {
                Buffer[i]=RecByte();//接受数据
                ACK();//发送应答位
        }
        Buffer[N-1]= RecByte();//接受最后一位
        NO_ACK();                          //发送非应答
        Stop();
        return 1;
}








void   DelayMS(uint x);
//键盘矩阵扫描程序
uchar Keys_Scan()
{
        uchar Tmp,KeyNo =0;
          P1 =0xF0;
        DelayMS(1);
        //按键后00001111将会变成0000xxxx,x中1个为0,3个为1
        //下面的异或操作会把3个1变成0,唯一的0变成1
        Tmp =P1 ^ 0x0F;
        //判断按键发生于0到3列中的哪一列
        switch (Tmp)
        {
                case 1:KeyNo =0;break;
                case 2:KeyNo =1;break;
                case 4:KeyNo =2;break;
                case 8:KeyNo =3;break;
                default :    KeyNo =16;//无键盘按下
        }
        //低四位置0,放入四列
        P1 =0xF0;
       
        DelayMS(1);
        //按键后00001111将会变成0000xxxx,x中1个为0,3个为1
        //下面的表达式会将高四位移至底四位,并将其中唯一的0变成1,其余为0
        Tmp =P1>> 4 ^ 0x0f;
        //对0到3行分别附加起始值0,4,8,12
        switch (Tmp)
        {
                case 1:KeyNo +=0;break;
                case 2:KeyNo +=4;break;
                case 4:KeyNo +=8;break;
                case 8:KeyNo +=12;
        }

        return KeyNo;
}



void LCD_Init();                //初始化液晶
void Display_String(uchar *str, uchar LineNo);        //在液晶的指定行显示
void Beep();    //IIC和蜂鸣器的初始化
void IIC_24C04_Init();
uchar RecString(uchar Slave,uchar Subaddr,uchar *Buffer,uchar N);
uchar SendString(uchar Slave,uchar Subaddr,uchar *Buffer,uchar N);
uchar Keys_Scan();           //扫描键盘返回

sbit LED_OPEN = P2^7;                 //开锁灯
sbit LED_WARN = P2^4;           //警示灯
sbit BEEP = P3^7;                                //蜂鸣器

uchar Pre_KeyNo=16, KeyNo=16;
uchar code Title_Text[] = "Your Password... ";                 //上电液晶显示标题
uchar DSY_BUFFER[10] = "";//显示缓存                                                                                                                                          
uchar UserPassword[10] = "";//用户输入的密码


//蜂鸣器子程序
void Beep()
{
        uchar i;
        for (i =0;i<100;i++)
        {
                DelayMS(1); BEEP = ~BEEP;
        }
        BEEP = 1;
}

//清除密码
void Clear_Password()
{
        UserPassword[0] = '';
        DSY_BUFFER[0] ='';
}

//主程序
void main()
{
        uchar i = 0;
        uchar IIC_Password[10];
        uchar IS_Valid_User = 0;
        int M=0;
        RS=1;
        RW=0;
        EN=0;
        TMOD = 0x02;//to设置为8位自动重装模式
        TH0 = 175;
        TL0 =175;           //启动T0
        TR0 =1;
        DelayMS(10);
        LCD_Init();
        IIC_24C04_Init();          //初始LCD和24c04
        LCD_Write_String(Title_Text,0x00);         //在液晶的第一行显示标题
       
        // 24c04的内容已由初始化的bin文件导入
        //将24c04中预先写入的密码读入到IIC_Password
       
        RecString(0xa0, 0 ,IIC_Password, 6);
        IIC_Password[6] = '';

        while(1)
        {
                P1= 0XF0;
                if(P1 != 0XF0) KeyNo = Keys_Scan(); //扫描键盘获取键盘号KeyNo
                if(Pre_KeyNo !=KeyNo)
                {
                        if (i<10)
                        {
                                switch ( KeyNo )
                                {
                                        case 0: case 1: case 2: case 3: case 4:
                                        case 5: case 6: case 7: case 8: case 9:
                                                //若i为0则执行一次清屏
                                                if (i==0)
                                                {
                                                        LCD_Write_String(0,0,"     ");
                                                }
                                                UserPassword[i] = KeyNo + '0';
                                                UserPassword[i+1] = '';
                                                DSY_BUFFER[i] = '*';
                                                DSY_BUFFER[i+1] = '';
                                                LCD_Write_String(0,1,DSY_BUFFER);
                                                i++;
                                                break;

                                        case 10:   //按开锁键
                                                if (strcmp(UserPassword,IIC_Password) ==0)    //strcmp 前面大返回1相等返回0后面大返回-1
                                                {
                                                        LED_OPEN =0;//黄颜 {MOD}灯亮
                                                        Clear_Password();
                                                        LCD_Write_String(0,1,"LOAD OK!   ");        
                                                        IS_Valid_User = 1;        
                                                }
                                                else
                                                {
                                                        LED_OPEN =1;//关闭黄颜 {MOD}灯亮
                                                        Clear_Password();
                                                        LCD_Write_String(0,1,"Unlock OK!   ");
                                                        IS_Valid_User = 0;   
                                                        M++;

                                                }
                                                i=0;
                                        break;

                                        case 11: //按上锁键
                                                LED_OPEN =1;
                                                Clear_Password();
                                                LCD_Write_String(0,0,Title_Text);
                                                LCD_Write_String(0,1,"         ");
                                                i =0;
                                                IS_Valid_User =0;
                                        break;

                                        case 12: //按重新设置密码
                                                if (!IS_Valid_User ) LCD_Write_String(0,1,"No rights !");
                                                else
                                                {
                                                        i=0;
                                                                LCD_Write_String(0,0,"New Password:   ");
                                                        LCD_Write_String(0,1,"       ");
                                                }
                                        break;

                                        case 13: //保存新密码
                                                if( !IS_Valid_User )LCD_Write_String(0,1,"NO ringhts !");
                                                else
                                                {
                                                        SendString(0xa0, 0 , UserPassword, 6);
                                                        RecString(0xa0, 0 , IIC_Password, 6);
                                                        IIC_Password[6] = '';
                                                        i=0;
                                                        LCD_Write_String(0,0,Title_Text);
                                                        LCD_Write_String(0,1,"Password Saved !");
                                                }
                                        break;

                                        case 14://按删除键删除所有输入的
                                        i=0;
                                        Clear_Password();
                                        LCD_Write_String(0,1,"         ");
                                }

                        }
                        Beep();
                        if (M>2)   LED_WARN=0;

                        Pre_KeyNo =KeyNo;
                }
                DelayMS(100);
        }
}


QQ图片20140514091155.jpg
mengqiqi
2楼-- · 2019-07-18 20:13
这个很简单 我可以帮你搞定 加Q 1925276216详谈

一周热门 更多>