【51单片机8位密码锁】2023-2-22

缘由https://ask.csdn.net/questions/7889502/54080235

1.用矩阵按键来输入0~9的数字来输入密码,在数码管中显示。

2.输入密码后用独立按键K1确认密码输入。

3.如果密码正确,LED灯亮任意一盏,不与38译码器冲突。

4.如果密码错误,鸣叫三秒后进行密码重新输入。

5.如果错误三次数码管显示ERROR

cpp 复制代码
`#include "reg52.h"
unsigned char code ShuMaGuan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共阴0~15
unsigned char code ShaoMiaoZhi[]={238,237,235,231,222,221,219,215,190,189,187,183,126,125,123,119};
sbit L1=P2^2;
sbit L2=P2^3;
sbit L3=P2^4;
sbit k=P3^0;
sbit led=P2^0;
sbit beep=P2^5;
bit er=0;
unsigned long m=0;//数据2^32=4294967296
void ShuMaXianShi(unsigned char s,unsigned char w)
{
    P0=L1=L2=L3=0;
    switch(w)
    {
        case 2:{L1=0;L2=L3=1;}break;//011
        case 3:{L2=0;L1=L3=1;}break;//101
        case 4:{L1=L2=0;L3=1;}break;//001
        case 5:{L1=L2=1;L3=0;}break;//110
        case 6:{L1=L3=0;L2=1;}break;//010
        case 7:{L1=1;L2=L3=0;}break;//100
        case 8:{L1=L2=L3=0;}break;//000
        case 1:{L1=L2=L3=1;}break;//111
        default:{L1=L2=L3=0;}break;
    }//d显示小数点11,10关闭
    P0=ShuMaGuan[s];
}
void XianShi(unsigned char w)
{
    switch(w)
    {
        case 0:ShuMaXianShi(m/10000000,1);break;
        case 1:ShuMaXianShi(m/1000000%10,2);break;
        case 2:ShuMaXianShi(m/100000%10,3);break;
        case 3:ShuMaXianShi((er?14:m/10000%10),4);break;
        case 4:ShuMaXianShi((er?10:m/1000%10),5);break;
        case 5:ShuMaXianShi((er?10:m/100%10),6);break;
        case 6:ShuMaXianShi((er?0:m/10%10),7);break;
        case 7:ShuMaXianShi((er?10:m%10),8);break;
        default:P0=L1=L2=L3=0;break;
    }
}
unsigned char JianPanShaoMiao(/*使用行列反转扫描法*/)
{    
    unsigned char H=15,L=240,Ys=0;
    P1=15;
    if(P1!=15)
    {        
        while(++Ys);//消抖
        H=P1;
        P1=240;
        L=P1;
        while(P1!=240);
    }
    P1 = 255;
    return (H+L);
}
unsigned char JianPanQuZhi(/*定义按钮*/)
{    
    unsigned char Jian_Zhi=0,LinShi=JianPanShaoMiao();
    if(LinShi==255)return LinShi;else//减小对延时影响提高运行效率
    while(LinShi!=ShaoMiaoZhi[Jian_Zhi])if(++Jian_Zhi > 15)break;
    return Jian_Zhi;//按键排列
    //12 08 04 00
    //13 09 05 01
    //14 10 06 02
    //15 11 07 03
}
void main()
{
    unsigned char jz=0,xd=0,ys=0,w=0,s=0;//数据2^8=256
    unsigned int Ys=747;//数据2^16=65536
    unsigned long mm=63258741;//数据2^32=4294967296
    bit bk=0;
    while(1)
    {
        jz=JianPanQuZhi();
        if(jz<10){m=m*10+jz;}
        if(++ys>24)
        {
            if(bk)beep=!beep;
            ys=0;
            XianShi(w);if(++w>7){w=0;}
            if(bk&&++xd==0){bk=0;m=0;}
        }
        if(k==0&&++xd==0)
        {
            if(mm==m){led=!led;s=0;}
            else
            {
                if(++s<3){bk=1;}
                else er=1;
            }
            while(k==0);
        }
    }
}`

修改使得按键不影响数码管显示

cpp 复制代码
`while(P1!=240){XianShi(w);if(++w>7)w=0;}
while(k==0){XianShi(w);if(++w>7)w=0;}`

需要注意的是处理LONG数据类型比处理CHAR数据类型花费时间长,将LONG数据类型修改为4个CHAR数据类型同样能达到8位密码,不使用CHAR数组8个存储8位密码,处理时间变长一直找不到原因,对比上贴1302才觉得应该是数据类型不同处理时间也不同,虽然同样都是处理8位数码管数据。修改代码如下:证实分析是对的。

cpp 复制代码
`#include "reg52.h"
unsigned char code ShuMaGuan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char code ShaoMiaoZhi[]={238,237,235,231,222,221,219,215,190,189,187,183,126,125,123,119};
sbit L1=P2^2;
sbit L2=P2^3;
sbit L3=P2^4;
sbit k=P3^0;
sbit led=P2^0;
sbit beep=P2^5;
bit er=0;
unsigned char m1=0,m2=0,m3=0,m4=0;
void ShuMaXianShi(unsigned char s,unsigned char w)
{
    P0=L1=L2=L3=0;
    switch(w)
    {
        case 2:{L1=0;L2=L3=1;}break;
        case 3:{L2=0;L1=L3=1;}break;
        case 4:{L1=L2=0;L3=1;}break;
        case 5:{L1=L2=1;L3=0;}break;
        case 6:{L1=L3=0;L2=1;}break;
        case 7:{L1=1;L2=L3=0;}break;
        case 8:{L1=L2=L3=0;}break;
        case 1:{L1=L2=L3=1;}break;
        default:{L1=L2=L3=0;}break;
    }
    P0=ShuMaGuan[s];
}
void XianShi(unsigned char w)
{
    switch(w)
    {
        case 0:ShuMaXianShi(m4/10,1);break;
        case 1:ShuMaXianShi(m4%10,2);break;
        case 2:ShuMaXianShi(m3/10,3);break;
        case 3:ShuMaXianShi((er?14:m3%10),4);break;
        case 4:ShuMaXianShi((er?10:m2/10),5);break;
        case 5:ShuMaXianShi((er?10:m2%10),6);break;
        case 6:ShuMaXianShi((er?0:m1/10),7);break;
        case 7:ShuMaXianShi((er?10:m1%10),8);break;
        default:P0=L1=L2=L3=0;break;
    }
}
unsigned char JianPanShaoMiao()
{    
    unsigned char H=15,L=240,Ys=0,w=0;
    P1=15;
    if(P1!=15)
    {        
        while(++Ys);
        H=P1;
        P1=240;
        L=P1;
        while(P1!=240)if(++Ys==47){XianShi(w);if(++w>7)w=0;Ys=0;}
    }
    P1 = 255;
    return (H+L);
}
unsigned char JianPanQuZhi()
{    
    unsigned char Jian_Zhi=0,LinShi=JianPanShaoMiao();
    if(LinShi==255)return LinShi;else
    while(LinShi!=ShaoMiaoZhi[Jian_Zhi])if(++Jian_Zhi > 15)return 255;
    return Jian_Zhi;
}
void main()
{
    unsigned char jz=0,xd=0,ys=0,w=0,s=0,ym1=63,ym2=25,ym3=87,ym4=41;
    bit bk=0;
    while(1)
    {
        jz=JianPanQuZhi();
        if(jz<10)
        {//用4个CHAR变量存储8位密码
            if(m1>9)
            {
                if(m3>9){if(m4<10){m4=m4*10+m3/10;m3%=10;}}
                if(m2>9){if(m3<10){m3=m3*10+m2/10;m2%=10;}}
                if(m2<10)m2=m2*10+m1/10;
                m1%=10;
            }
            m1=m1*10+jz;
        }
        if(++ys>47)
        {
            if(bk)beep=!beep;
            ys=0;
            XianShi(w);if(++w>7)w=0;
            if(bk&&++xd==0){bk=0;m4=m3=m2=m1=0;}
        }
        if(k==0&&++xd==0)
        {
            if(ym4==m1&&ym3==m2&&ym2==m3&&ym1==m4){led=!led;s=0;}
            else
            {
                if(++s<3)bk=1;
                else er=1;
            }
            while(k==0)if(++xd==47){XianShi(w);if(w>7)w=0;else ++w;xd=0;}
        }
    }
}`


从2个程序2张波形对比可以看到调节到差不多周期,但是延时数值不同24和47,证实之上所述处理数据类型引起的时间不同。

相关推荐
t198751283 分钟前
STM32通过SPI读取磁编码器AS5047P获取电机角度信息
stm32·单片机·嵌入式硬件
学嵌入式的小杨同学12 分钟前
STM32 进阶封神之路(三十二):SPI 通信深度实战 —— 硬件 SPI 驱动 W25Q64 闪存(底层时序 + 寄存器配置 + 读写封装)
c++·stm32·单片机·嵌入式硬件·mcu·架构·硬件架构
不做无法实现的梦~13 分钟前
clion配置stm32(调试,烧录的详细教程)
stm32·单片机·嵌入式硬件
米粒116 分钟前
力扣算法刷题 Day 27
算法·leetcode·职场和发展
蒸蒸yyyyzwd22 分钟前
后端学习笔记 day4
linux·笔记·学习
Fuxiao___1 小时前
C 语言核心知识点讲义(循环 + 函数篇)
算法·c#
漫随流水2 小时前
c++编程:反转字符串(leetcode344)
数据结构·c++·算法
南境十里·墨染春水2 小时前
C++ 笔记 友元(面向对象)
开发语言·c++·笔记
笨笨饿2 小时前
20_Git 仓库使用手册 - 初学者指南
c语言·开发语言·嵌入式硬件·mcu·学习
C++ 老炮儿的技术栈3 小时前
分享一个安全的CString
c语言·c++·windows·git·安全·visual studio