找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4377|回复: 2
收起左侧

单片机密码锁报警部分小问题

[复制链接]
ID:351936 发表于 2018-6-15 09:54 | 显示全部楼层 |阅读模式
2黑币
现在程序可以运行,主要就是密码正确LED亮,密码错误三次报警10S,如果在报警时间内按键,则重载报警时间,这个不知道怎么改程序,求大佬们帮帮忙。以下是程序代码:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,
                                    0x6d,0x7d,0x07,0x7f,0x6f};     //字模定义
void delay(uint z);                                  //延时函数
void get_key();                                   // 键盘扫描子程序
void fun_key();                                 //按键C,D子程序
void init();                                          // 初始化设置
void exter0();                                //定时器T0中断服务
void disp(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f);
                                               //6位数字显示子函数
void rest_cipher();                             // 重置密码子程序
uchar cou_dis(uchar);                           //数字右移函数                       
void display(uchar);                                // 数码管显示程序
void alarm();                                      //报警电路程序
void delay_us(uchar);                             //延时函数
uchar hang,lie,addres,num,temp,flag,sum,fun,mark,con,N,km;
uint to,aa;
uchar a,b,c,d,e,f;                          //数码管显示位数
uchar a1,b1,c1,d1,e1,f1;
sbit D0=P3^0;               
sbit K=P3^1;

void main()
{        init();                                       //初始化设置
        while(1)
                {       
                        get_key();                              //键盘扫描子程序
                        if(N<6)
                        cou_dis(num);                         //数字右移函数
                        fun_key();                                       //按键C,D子程序       
                    display(N);                             // 数码管显示程序
                                  if(to==2000)
                                {
                                        to=0;
                                        D0=1;                    //数码管熄灭
                                        TR0=0;
                                        mark=0;

                                }
                                        alarm();                                     // 报警电路程序                       
        if(num=='A')
                                        {         to=0;               
                                             TR0=0;
                                                while(mark)
                                                        {                          
                                                               rest_cipher();      // 重置密码子程序
                                                                   mark=0;
                                                        }          
                                        }
                }
}


void init()                                      // 初始化设置
{       
        K=0;                                      // p3.1口置零
        con=1;
        mark=0;
        temp=0xfe;
        flag=0;
        fun=0;
        a1=6;                               //从右往左数第六位密码
        b1=5;                             //第五位密码
        c1=4;                            //第四位密码
        d1=3;                             //第三位密码
        e1=2;                                //第二位密码
        f1=1;                              //第一位密码
        TMOD=0x01;          
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        EA=1;
        ET0=1;
        TR0=0;       
}

void rest_cipher()                                   // 重置密码子程序
{                a=b=c=d=e=f=0;                     //熄灭数码管
                N=0;                                            //输入密码个数清零
                D0=1;                              //熄灭led灯
                while(con)
                        {       
                                get_key();                    //键盘扫描子程序
                                if(N<6)                            //判断输入密码的个数
                            cou_dis(num);          //数字右移函数
                                disp(a,b,c,d,e,f);     //数字显示函数
                                 if(num=='D')
                                         {con=0;}         
                                        if(num=='C')
                                                {a=b=c=d=e=f=0;            //熄灭数码管
                                                   N=0;}
                                                           a1=a;  
                                                        b1=b;
                                                        c1=c;
                                                        d1=d;
                                                        e1=e;
                                                        f1=f;
                                }
                                          a=b=c=d=e=f=0;
                                          N=0;
                                                       
}

void delay(uint z)                                  // 延时函数
{
        uint x,y;
        for(x=100;x>0;x--)
                for(y=z;y>0;y--);
}
uchar  cou_dis(uchar num)                  //数字右移函数
{                 
                if((num==0)||(num==1)||(num==2)||(num==3)||(num==4)||(num==5)
                ||(num==6)||(num==7)||(num==8)||(num==9))
                                    //判断是否输入的是其中一个数字
                        {           //N=1;                   //输入密码个数为1
                                        if(flag!=0)                //说明有数输入
                                {    N++;                  //输入密码个数加1
                                        flag=0;                        
                                        f=e;
                                        e=d;
                                        d=c;
                                        c=b;
                                        b=a;
                                        a=num;                                      //输入密码右移                       
                                }
       
                        }
}
void get_key()                                 //键盘扫描子程序
{
                P1=0xf0;   
                lie=P1;
                P1=0x0f;
                hang=P1;
                addres=hang|lie;                    //行列寄存器中的值相或得到按键值
                        while(addres!=0xff)
//判断是否有键按下,若adres的值不为0xff则有键按下
                          {
                                                   delay(5);                                // 延时消抖
                                                P1=0xf0;
                                                lie=P1;
                                                P1=0x0f;
                                                hang=P1;
                                        addres=hang|lie;
                                                if(addres!=0xff)
                                         {                        flag++;
                                                                                  switch(addres)       // 读取键值      
                                                {       
                                                        case 0xee:num=1;break; //按键1动作,设num=1
                                                        case 0xde:num=2;break; //按键2动作,设num=2
                                                        case 0xbe:num=3;break; //按键3动作,设num=3
                                                case 0x7e:num='A';break; // 按键A动作,设num=A
                                                        case 0xed:num=4;break; //按键4动作,设num=4
                                                        case 0xdd:num=5;break; //按键5动作,设num=5
                                                        case 0xbd:num=6;break; // 按键6动作,设num=6
                                                case 0x7d:num='B';break; // 按键B动作,设num=B
                                                        case 0xeb:num=7;break; //按键7动作,设num=7
                                                        case 0xdb:num=8;break; // 按键8动作,设num=8
                                                        case 0xbb:num=9;break; //按键9动作,设num=9
                                                case 0x7b:num='C';break; // 按键C动作,设num=C
                                                        case 0xd7:num=0;break; //按键0动作,设num=0
                                                case 0x77:num='D';break; // 按键D动作,设num=D
                                                                                                }
                                                         }

                          }
                               


}

void fun_key()                                  //按键C,D子程序
{          
        if(num=='C')                    //判断按键是否为C
                {
                        a=b=c=d=e=f=0;              //按键为C熄灭数码管
                        N=0;                       //输入密码个数为0
                }
        if(num=='D')                             //按键是否为D
                {        num=0xff;
                                if((a1==a)&&(b1==b)&&(c1==c)&&(d1==d)&&(e1==e)&&(f1==f))
                                                //比较密码是否正确
                                        {                 mark=1;
                                                         TR0=1;
                                                         to=0;     
                                                         D0=0;                 //led灯点亮
                                                         a=b=c=d=e=f=0;       //数码管熄灭
                                                         N=0;                 //输入密码个数为0
                                                         km=0;                 //输入密码错误次数为0
                                        }
                                if((a1!=a)||(b1!=b)||(c1!=c)||(d1!=d)||(e1!=e)||(f1=!f))
                                                     //密码错误
                                        {         if(D0!=0)               //led灯不亮
                                        {        km++;                       //错误次数累加
                                                N=0;                       //输入密码个数为0
                                                a=b=c=d=e=f=0;              //数码管熄灭
                                        } }
                }
}

void display(uchar N)                       // 数码管显示程序
{
           if(N==1)                           //判断输入密码个数是否为1
                {   temp=0xfe;
                        P0=0x40;                       //点亮g段使显示为“—”
                        P2=temp;
                        delay(1);
                        P2=0xff;                     //点亮数码管右边N位使显示“—”
                }
                 if(N==2)                          //判断输入密码个数是否为2
                 {          temp=0xfe;
                           P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);                    //带循环,使其挨个点亮
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);

                 }
                 if(N==3)                       // 判断输入密码个数是否为3
                 {           temp=0xfe;
                           P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);

                 }
                  if(N==4)                      // 判断输入密码个数是否为4
                 {         temp=0xfe;
                          P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                 }

                if(N==5)                          //判断输入密码个数是否为5
                 {         temp=0xfe;
                          P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        }

                  if(N==6)                          //判断输入密码个数是否为6
                 {         temp=0xfe;
                          P0=0x40;
                        P2=temp;
                        delay(1);
                         P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        P0=0x40;
                        P2=temp;
                        delay(1);
                        P2=0xff;
                        temp=_crol_(temp,1);
                        }


}

void exter0() interrupt 1                       //定时器T0中断服务
{
                   TH0=(65536-10000)/256;
                TL0=(65536-10000)%256;
                to++;                       
}

void alarm()                                  //报警电路子程序
{
                if(km==3)                       //判断输入错误密码的次数
                        {        uchar n,m;
                                km=0;
                                for(m=50;m>0;m--)
                                 {
                                                 for(n=200;n>0;n--)
                                        {
                                                K=~K;                 //p3.1口取反
                                                delay_us(1000);             // 调用延时函数
                                        }
                                        K=0;                       //p3.1口置零
                                        delay(100);                  // 调用延时函数
                                        }       
                               
                        }
}

void disp(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f) //数字显示
{
                P0=table[a];                       //输入从左往右第一个数
                P2=temp;                  
                delay(1);
                P2=0xff;                        //打开数码管所有位
                temp=_crol_(temp,1);
                P0=table[b];                       //输入从左往右第一个数

           P2=temp;
                delay(1);
                P2=0xff;
                temp=_crol_(temp,1);
                P0=table[c];                      //输入从左往右第一个数
                P2=temp;
                delay(1);
                P2=0xff;
                temp=_crol_(temp,1);
                P0=table[d];                      //输入从左往右第一个数
                P2=temp;
                delay(1);
                P2=0xff;
                temp=_crol_(temp,1);
                P0=table[e];                         //输入从左往右第一个数
                P2=temp;
                delay(1);
                P2=0xff;
                temp=_crol_(temp,1);
                P0=table[f];                      //输入从左往右第一个数
                P2=temp;
                delay(1);
                P2=0xff;
                if(temp=0xef)
                        temp=0xfe;
}

void delay_us(uchar z)                     //延时子函数
{
        while(--z);       
}



回复

使用道具 举报

ID:351936 发表于 2018-6-15 14:46 | 显示全部楼层
void alarm()                                  //报警电路子程序
{
                if(km==3)                       //判断输入错误密码的次数
                        {        uchar n,m;
                                km=0;
                                for(m=50;m>0;m--)
                                 {
                                                 for(n=200;n>0;n--)
                                               
                                        {                 get_key();
                                       if(num!='F')
                                        {if(num=='C')
                                        { n=0;
                                        m=0;}
                                        else if((num==0)||(num==1)||(num==2)||(num==3)||(num==4)||(num==5)
                ||(num==6)||(num==7)||(num==8)||(num==9))

                                        {n=200;
                                        m=50;}
                                        }
                                       
                                          
                                                K=~K;                 //p3.1口取反
                                                delay_us(1000);             // 调用延时函数
                                                num='F';
                                        }
                                        K=0;                       //p3.1口置零
                                        delay(100);                  // 调用延时函数
                                        }                                       
                               
                               
                        }
}

经由大佬帮忙,改出来了。
回复

使用道具 举报

ID:111634 发表于 2018-6-15 22:45 | 显示全部楼层
本帖最后由 zl2168 于 2018-6-15 22:50 编辑

功能齐全的电子密码锁
⑴ 电路设计    …
电子密码锁电路.jpg 电子密码锁电路说明.jpg
⑵ 功能设计    …
电子密码锁功能1.jpg 电子密码锁功能2.jpg 电子密码锁功能3.jpg

⑶ 程序设计    …
电子密码锁流程图.jpg
⑷ Proteus仿真    …

Proteus仿真一下,确认有效,验证上述功能。
我的电子密码锁功能比网上的好多了,你可以Proteus仿真核查,但程序在书中。
电子密码锁1.rar (1.13 MB, 下载次数: 7)
电子密码锁Proteus仿真.jpg


以上摘自张志良编著《80C51单片机实用教程》ISBN 978-7-04-044532-9,高教社出版。书中电路和程序设计有详细说明,程序语句条条有注解。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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