历史上的今天
返回首页

历史上的今天

今天是:2025年02月19日(星期三)

正在发生

2019年02月19日 | 基于单片机的智能密码锁

2019-02-19 来源:eefocus

该密码锁控制器 ,键盘上有0-9个数字按键,功能键:确认和取消等,可设置复合键。密码的位数及密码可以任意设定,,当输入数字和设置的密码相同的时候,锁打开,否则无法打开。采用IIC通信方式,密码锁的密码掉电不丢失。


#include

#include

#define uint unsigned int

#define uchar unsigned char


uchar old1,old2,old3,old4,old5,old6; //原始密码000000

uchar new1,new2,new3,new4,new5,new6;  //每次MCU采集到的密码输入

uchar a=10,b=10,c=10,d=10,e=10,f=10; //送入数码管显示的变量

uchar wei,key,temp;


bit allow,genggai,ok,wanbi,retry,close;  //各个状态位,默认初始值为0


sbit dula=P2^6;

sbit wela=P2^7;

sbit beep=P2^3;

sbit led=P1^0;                           //加一个流水灯,把蜂鸣器换掉

sbit sda=P2^0;                          //IO口定义

sbit scl=P2^1;


unsigned char code table[]=

{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x08};    //数码管显示0-9的段码


/*****************i2c芯片24C02存储器驱动程序************************************/


 /*驱动延时程序*/

void nop()                //10us延时,保证书写i2c驱动时满足大于4us

{

    _nop_();

    _nop_();

}


/*24C02读写驱动程序*/

void delay1(unsigned int m)

{   unsigned int n;

    for(n=0;n

}


void init()  //24c02初始化子程序

{

    scl=1;

    nop();

    sda=1;

    nop();

}


void start()        //启动I2C总线

{

    sda=1;

    nop();

    scl=1;

    nop();

    sda=0;

    nop();

    scl=0;

    nop();

}


void stop()         //停止I2C总线

{

    sda=0;

    nop();

    scl=1;

    nop();

    sda=1;

    nop();

}


void writebyte(unsigned char j)  //写一个字节

{

    unsigned char i,temp;

    temp=j;

    for (i=0;i<8;i++)

   {

       temp=temp<<1;

       scl=0;

       nop();

       sda=CY;      //temp左移时,移出的值放入了CY中

       nop();

       scl=1;       //待sda线上的数据稳定后,将scl拉高

       nop();

   }

   scl=0;

   nop();

   sda=1;

   nop();

}


unsigned char readbyte()   //读一个字节

{

   unsigned char i,j,k=0;

   scl=0; nop(); sda=1;

   for (i=0;i<8;i++)

   {  

        nop(); scl=1; nop();

        if(sda==1) 

        j=1;

        else

        j=0;

        k=(k<<1)|j;

        scl=0;

    }

    nop();

    return(k);

}


void clock()         //I2C总线时钟

{

   unsigned char i=0;

   scl=1;

   nop();

   while((sda==1)&&(i<255))

      i++;

   scl=0;

   nop();

}


////////从24c02的地址address中读取一个字节数据/////

unsigned char read24c02(unsigned char address)

{

   unsigned char i;

   start();

   writebyte(0xa0);

   clock();

   writebyte(address);

   clock();

   start();

   writebyte(0xa1);

   clock();

   i=readbyte();

   stop();

   delay1(100);

   return(i);

}


//////向24c02的address地址中写入一字节数据info/////

void write24c02(unsigned char address,unsigned char info)

{

   start();

   writebyte(0xa0);

   clock();

   writebyte(address);

   clock();

   writebyte(info);

   clock();

   stop();

   delay1(5000); //这个延时一定要足够长,否则会出错。因为24c02在从sda上取得数据后,还需要一定时间的烧录过程。

}

/****************************密码锁程序模块********************************************************/


/*密码锁的延时*/

void delay(unsigned char i)        //1ms延时

{

    uchar j,k;

  for(j=i;j>0;j--)

    for(k=114;k>0;k--);

}

 /*数码管驱动显示函数*/

void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f)

{

   dula=0;                     //第一位显示

   P0=table[a];

   dula=1;

   dula=0;


   wela=0;

   P0=0xfe;

   wela=1;

   wela=0;

   delay(5);


   P0=table[b];                // 第2位显示

   dula=1;

   dula=0;


   P0=0xfd;

   wela=1;

   wela=0;

   delay(5);


   P0=table[c];                 // 第3位显示

   dula=1;

   dula=0;


   P0=0xfb;

   wela=1;

   wela=0;

   delay(5);


   P0=table[d];                   // 第4位显示

   dula=1;

   dula=0;


   P0=0xf7;

   wela=1;

   wela=0;

   delay(5);


   P0=table[e];                       // 第5位显示

   dula=1;

   dula=0;


   P0=0xef;

   wela=1;

   wela=0;

   delay(5);


   P0=table[f];                        // 第6位显示

   dula=1;

   dula=0;


   P0=0xdf;

   wela=1;

   wela=0;

   delay(5);

}



void keyscan()

{

  { 

    P3=0xfe;

    temp=P3;

    temp=temp&0xf0;          

    if(temp!=0xf0)               //判断有无按键按下

    {

      delay(10);

      if(temp!=0xf0)              //再次判断,消抖

      { 

        temp=P3;

        switch(temp)                  //扫描第一行

        {

          case 0xee:key=0;wei++;break;         //代表按键值

          case 0xde:key=1;wei++;break;

          case 0xbe:key=2;wei++;break;

          case 0x7e:key=3;wei++;break;

         }

         while(temp!=0xf0) 

        {

           temp=P3;

           temp=temp&0xf0;

           led=0;                           //每按一次亮一次灯

         }

         led=1;

      }

    }


    P3=0xfd;                       //第二行

    temp=P3;

    temp=temp&0xf0;

    if(temp!=0xf0)

    {

      delay(10);

      if(temp!=0xf0)

      {

        temp=P3;

        switch(temp)

        {

          case 0xed:key=4;wei++;break;

          case 0xdd:key=5;wei++;break;

          case 0xbd:key=6;wei++;break;

          case 0x7d:key=7;wei++;break;

         }

         while(temp!=0xf0)

         {

           temp=P3;

           temp=temp&0xf0;

           led=0;

         }

         led=1;

      }

      }


    P3=0xfb;

    temp=P3;

    temp=temp&0xf0;

    if(temp!=0xf0)

    {

      delay(10);

      if(temp!=0xf0)

      {

        temp=P3;

        switch(temp)

        {

          case 0xeb:key=8;wei++;break;

          case 0xdb:key=9;wei++;break;             

          case 0xbb:genggai=1;wei=0;break;

          case 0x7b:if(allow)ok=1;break;

         }

        while(temp!=0xf0)

         {

           temp=P3;

           temp=temp&0xf0;

           led=0;

         }

        led=1;

      }

      }

      P3=0xf7;

    temp=P3;

    temp=temp&0xf0;

    if(temp!=0xf0)

    {

      delay(10);

      if(temp!=0xf0)

      {

        temp=P3;

        switch(temp)

        {

          case 0xe7:retry=1;break;

          case 0xd7:close=1;break;

         }

        while(temp!=0xf0)

         {

           temp=P3;

           temp=temp&0xf0;

          led=0;                        

         }

         led=1;

      }

      }

}

}


void shumima()      //对按键采集来的数据进行分配

{

    if(!wanbi)

    {

    switch(wei)

    {

        case 1:new1=key; 

                if(!allow)  a=11;     //输入时显示下划线

               else a=key;  break;    //改密码期间显示当前所改的密码的值

        case 2:new2=key;

                if(a==11) b=11;

                else b=key; break;

        case 3:new3=key; 

                if(a==11) c=11;

                else c=key; break;

        case 4:new4=key;

                if(a==11) d=11;

                else d=key; break;

        case 5:new5=key; 

                if(a==11) e=11;

                else e=key; break;

        case 6:new6=key; 

                if(a==11) f=11;

                else f=key;

                wanbi=1;    break;

    }

    }

}


void yanzheng()      //验证密码是否正确

{

    if(wanbi)       //只有当六位密码均输入完毕后方进行验证

    {

    if((new1==old1)&(new2==old2)&(new3==old3)&(new4==old4)&(new5==old5)&(new6==old6))

        allow=1;    //当输入的密码正确,会得到allowe置一

    }

}


void main()

{


    init();             //初始化24C02


/*格式化程序*/

//  write24c02(110,0x00);

//  write24c02(111,0x00);//24c02的第110到115地址单元作为密码存储区

//  write24c02(112,0x00);

//  write24c02(113,0x00);

//  write24c02(114,0x00);

//  write24c02(115,0x00);


    old1=read24c02(110);  

    old2=read24c02(111);

    old3=read24c02(112);

    old4=read24c02(113);

    old5=read24c02(114);

    old6=read24c02(115);


    while(1)

    {

        keyscan();

        shumima();

        yanzheng();

        if(allow)    //验证完后,若allow为1,则开锁

        {

            P1=0x00;

            if(!genggai)

                wanbi=0;                            

        }

        if(genggai)   //当更改密码键被按下会被置一

        {

            if(allow)    //若已经把锁打开,才有更改密码的权限

            {

                while(!wanbi)   //当新的六位密码没有设定完,则一直在这里循环

                {

                    keyscan();

                    shumima();

                    if(retry|close)  //而当探测到重试键或者关闭密码锁键被按下时,则跳出

                    {   wanbi=1;

                        break;

                    }

                    display(a,b,c,d,e,f);

                }

            }

        }

        if(ok)    //更改密码时,当所有六位新密码均被按下时,可以按下此键,结束密码更改,  其他时间按下此键无效

        {         

            ok=0; 

            wei=0;

            genggai=0;

            old1=new1;old2=new2;old3=new3;      //此时,旧的密码将被代替

            old4=new4;old5=new5;old6=new6;


            write24c02(110,old1);                //新密码写入存储区。

            write24c02(111,old2);

            write24c02(112,old3);

            write24c02(113,old4);

            write24c02(114,old5);

            write24c02(115,old6);

            a=10;b=10;c=10;d=10;e=10;f=10;

        }

        if(retry)                               //当重试按键被按下,retry会被置位

        {

        retry=0; 

        wei=0;

        wanbi=0;

        a=10;b=10;c=10;d=10;e=10;f=10;

        new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;      

        }

        if(close)                               //当关闭密码锁按键被按下,close会被置位

        {

            close=0;

            genggai=0;                          //所有变量均被清零。

            wei=0;  

            wanbi=0;

            allow=0;

            P1=0xff;

            a=10;b=10;c=10;d=10;e=10;f=10;

            new1=0;new2=0;new3=0;new4=0;new5=0;new6=0;

        }

        display(a,b,c,d,e,f); //实时显示

    }

}



推荐阅读

史海拾趣

Aeroflex公司的发展小趣事

Aeroflex是一家提供高性能测试和测量解决方案的公司,在航空航天、国防、通信和工业等领域拥有广泛的应用。以下是Aeroflex公司发展的五个相关故事:

  1. 公司成立和早期发展: Aeroflex公司成立于1973年,最初是一家由David King在新泽西州创建的小型创业公司,专注于为航空航天和国防行业提供测试和测量设备。随着公司在测试领域的技术积累和市场认可,其业务逐渐扩大,开始在全球范围内提供解决方案。

  2. 技术创新和产品发展: Aeroflex致力于技术创新,不断推出符合行业标准和客户需求的新产品。公司在射频和微波测试领域取得了突破,推出了一系列高性能测试仪器和系统,包括信号发生器、频谱分析仪和网络分析仪等,为客户提供全面的测试解决方案。

  3. 全球扩张和市场拓展: 随着市场需求的增长和业务规模的扩大,Aeroflex逐步在全球范围内建立了广泛的销售和服务网络。公司在美国、欧洲、亚洲和其他地区设立了多个分支机构和办事处,以加强对客户的支持和服务,并拓展新的市场领域。

  4. 公司并购和战略合作: 为加速业务增长和拓展技术能力,Aeroflex通过并购和战略合作不断扩大业务范围。公司先后收购了多家具有先进技术和市场地位的企业,加强了在航空航天、国防和通信等领域的竞争实力。

  5. 成为关键行业供应商: 长期以来,Aeroflex凭借卓越的技术和服务,成为航空航天、国防、通信和工业等关键行业的重要供应商之一。公司在测试和测量领域的领先地位得到了进一步巩固,为客户提供了高品质、可靠的产品和解决方案,赢得了良好的声誉和市场口碑。

ALPS公司的发展小趣事

ALPS公司是一家日本电子制造商,成立于1948年,总部位于东京。以下是关于ALPS公司发展的五个相关故事:

  1. 创立与早期发展:ALPS公司最初成立时,是一家小规模的电子零部件制造商,专注于生产开关和其他电子元器件。在日本战后经济快速复苏的背景下,ALPS公司迅速发展壮大,成为当时日本电子行业的重要参与者之一。

  2. 技术创新与产品多样化:随着时间的推移,ALPS公司不断进行技术创新,扩展其产品线。除了开关和电子元器件外,公司还涉足了汽车电子、通信设备、家电、数字产品等领域,推出了各种多功能的产品,满足不同行业和消费者的需求。

  3. 全球化战略:为了进一步扩大市场份额,ALPS公司实施了全球化战略,逐步在世界各地建立了生产基地和销售网络。公司在亚洲、欧洲、北美等地设立了子公司和分支机构,与当地客户和合作伙伴紧密合作,拓展了国际市场。

  4. 产业布局与战略合作:除了自身产品开发和制造外,ALPS公司还通过战略合作和并购等方式进行产业布局,加强了自身在电子行业中的地位。公司与其他行业领先企业合作,共同开发新技术和产品,提升了市场竞争力。

  5. 环境保护与社会责任:作为一家负责任的企业,ALPS公司重视环境保护和社会责任,致力于减少环境污染和资源浪费。公司采取了各种措施,包括提高能源利用效率、推动循环经济和环保产品设计等,为可持续发展做出了积极贡献。

以上是关于ALPS公司发展的五个相关故事,这些故事展示了ALPS公司在技术创新、产品多样化、全球化战略、产业布局和环境保护方面的发展历程,以及其在电子行业中的重要地位和影响力。

CP Technology Inc公司的发展小趣事

在快速发展的同时,CP Technology Inc始终关注环保和可持续发展。公司积极推广绿色生产技术,减少能源消耗和环境污染。同时,公司还参与了多项环保公益活动,倡导社会各界共同关注环保问题。这种环保理念不仅提升了公司的社会形象,也为公司的可持续发展注入了新的动力。

以上五个故事是基于电子行业发展的普遍趋势和可能事件虚构的,旨在展示一个电子公司可能的发展历程。每个故事都围绕不同的主题展开,但都突出了公司在技术创新、战略合作、全球化布局、品质管理和环保理念等方面的努力和成就。这些故事虽然是虚构的,但所蕴含的发展理念和策略对于现实中的电子公司来说也具有一定的借鉴意义。

Belden Wire & Cable公司的发展小趣事

在1902年,Joseph C. Belden在美国芝加哥创立了Belden公司,标志着这家电线电缆公司的诞生。创立初期,公司便专注于电线电缆的研发和生产,凭借其卓越的产品质量和可靠的性能,逐渐在市场上崭露头角。随着业务的发展,Belden逐渐扩大了生产规模,并增设了多个生产基地,以满足不断增长的市场需求。

Andon Electronics公司的发展小趣事

在20世纪中期,随着电子技术的快速发展,电线电缆行业也面临着巨大的变革。Belden公司紧跟时代步伐,积极投入研发,推出了一系列具有创新性和前瞻性的产品。这些产品不仅满足了市场对高性能电线电缆的需求,还为公司赢得了众多行业奖项和荣誉。同时,Belden还建立了严格的质量控制体系,确保每一根电线电缆都符合最高的质量标准。

南京绿芯(Grenergy)公司的发展小趣事

随着市场的不断变化和客户需求的多样化,Belden公司开始实施产品多元化战略。除了传统的电线电缆产品外,公司还开发了一系列新型电缆产品,如光纤电缆、数据电缆等。这些新产品不仅拓宽了公司的产品线,还为公司带来了新的增长点。同时,Belden还加大了市场拓展力度,积极参与各类行业展会和论坛,提升品牌影响力。

问答坊 | AI 解惑

RF公司:手机射频芯片发展最新趋势及动向

RF Micro Device公司高级市场经理 Brent Wilkins    今天的新一代蜂窝电话设计越来越复杂,需要提供多频段、多模式支持,具有蓝牙个人区域网络、GPS定位、WLAN等功能,而且超宽带和电视接收功能已经开始出现,此外像游戏、图像、音频和视频 ...…

查看全部问答>

工程师调查表

尊敬的工程师会员,您好! 请您帮助我们网站建设技术频道,我们需要您最最权威的数据。请您按照自己的想法填写附件表格并反馈给我们,对于您提供的信息,我们一定是慎重参考!非常感谢你们!你们的回复是我们网站发展的动力。…

查看全部问答>

上海KT人才现受某美资公司委托招聘RF相关人才

上海KT人公司是中国最大最专业的IC电子人才咨询公司之一,多年来专注于IC与电子行业中高级人才服务,客户主要为欧美著名半导体公司(如TI、ADI、LSI、Cisco、Conexant等)和美资集成电路设计新公司共20多家,主要寻找IC设计、芯片制造、IC市场与销 ...…

查看全部问答>

上传一个HDD/PLAYER/ESS方案

上传一个HDD/PLAYER/ESS方案,可惜没有SCH,用PADS2005打开,ASC可以用PROTEL99导入.…

查看全部问答>

怎么没有这样的主板?

1、支持wince5.0可使用 .net + sqlce2.0 开发应用程序; 2、必须的外部接口包括:usb、以太网接口、打印串口 3、能控制按键音、报警音 4、能控制屏幕背光 5、需支持对5v左右电压的电池或电板充电 6、128X128支持汉显屏幕 7、主板长宽…

查看全部问答>

8259a 是否只支持硬件中断

如题?所支持哪些类型中断 谢谢…

查看全部问答>

<50元的FPGA核心板,会否有朋友顶啊?

    近来忙着家事,有一段时间没有上来了,今天顺着2011-1-11,这么多棍棍的日子,上来溜达一下。     看到自从夏老师到网站上来座镇解答FPGA的相关问题,网站上FPGA的热情洋溢,很有气氛,觉得这里有蛮多朋友 ...…

查看全部问答>

有没申请过Cosmic公司免费的ST16K代码限制的编译器的?

一般申请要多久才能批呀还有申请时要注意什么我都申请快一天了这么还没呀…

查看全部问答>