基于51单片机的简易智能密码锁设计

本文介绍了基于STC89C52单片机的简易智能密码锁设计。阐述了设计任务与要求,对比两种方案后选择性价比更高的方案二。详细分析各硬件电路设计,进行性能测试,达到各项指标。还分享了设计中遇到的问题及解决方法,并提出课题改进方向。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、设计任务与要求

1.设计任务:

2.设计要求:

二、方案设计与论证

总体方案设计: 

各硬件电路方案设计及论证:

1.单片机内部软件资源分配

2.单片机外围晶振和复位电路

3.按键阵列扫描电路

4.数码管显示电路

5.报警提示和开锁电路

三、总原理图及元器件清单

四、程序流程图

五、性能测试与分析

六、设计作品图片  

七、结论与心得

八、程序代码

 

一、设计任务与要求

1.设计任务:

利用STC89C52单片机搭配合理的外围电路,在各方面参数合理的情况下,制作一个简易的智能密码锁,该智能密码锁能够进行仿真模拟密码的输入、报警提示和锁打开及关闭。同时,装置还具有密码显示和系统锁定的功能,在搭建继电器等相关装置之后,具有实物的锁定功能。

2.设计要求:

  1. 对于单片机的按键输入密码的有效位数为6位;
  2. 单片机中的密码与当前单片机定时器系统时间相关,每隔1分钟,密码自动更新;
  3. 如果密码正确,蜂鸣器响0.5秒,开锁继电器吸合,5秒后开锁继电器关;
  4. 密码尝试5次出错,则停止尝试1分钟。

二、方案设计与论证

总体方案设计: 

 本作品设计的简易智能密码锁是一种应用于安全领域的电子设备,广泛应用于家庭、办公场所、酒店、银行等各种场合。它通过电子技术和密码算法,取代了传统的机械锁,提供更高的安全性和便捷性。

 本简易智能密码锁在设计之初,采用两种设计方案,在综合实际的代码编写、焊接、材料成本之后,采用了第二种设计方案。

方案一:在界面信息显示界面,用一个LCD1602显示屏幕来完成相关输入密码信息和开锁提示信息的显示,可以用于输入字符和数字信息;操作按键采用16位矩阵按键装置,采用动态扫描的方式来完成输入;在单片机外部设定一个DS1302的实时时钟芯片,用于每隔1分钟,密码自动更新;报警、提醒和开锁电路采用扬声器、LED灯泡和继电器装置来完成。

方案二:在界面信息显示界面,用一个较为普通的6段共阴极数码管来显示密码,应用动态扫描完成信息显示;操作按键共设12个,除0~9这10个数字键外,还有随机数显示按键和密码输入按键;在单片机内部设定定时器运行,用于与单片机自身的系统时钟保持同步,并在每隔1分钟,密码自动更新;报警、提醒和开锁电路采用扬声器、LED灯泡和继电器完成。

选择方案二的原因:对比上面两种方案,采用方案二的性价比会更高。首先,由于本装置只需要完成0~9数字和相关特定字符的显示,采用一个较为普通的6段共阴极数码管便可以完成需求,不用使用较为昂贵的LCD显示屏。此外,本装置只需要使用12个按键,利用矩阵按键会造成资源的浪费,虽然12个按键会使用较多的IO口,但是本实验可以满足设计的要求。最后,可以直接使用单片机内部的定时器时钟来完成随机数的更新,由于系统是属于独立工作的状态,不需要实时显示时间,因此可以舍弃DS1302实时时钟芯片,便可以满足要求。由此,综合上面的分析和比较,选择方案二是最佳的,因此舍弃方案一。

478bb48986fc4fee8861a883e014725c.png

各硬件电路方案设计及论证:

1.单片机内部软件资源分配

装置的整体控制器采用STC89C52单片机,它有着以下的众多优点,高性能:STC89C52单片机采用了高速的8051内核,最高主频可达33MHz,具有快速的运算能力和响应速度。 低功耗:STC89C52单片机采用了低功耗设计,工作电流仅为1-10mA,具有较低的功耗和较长的电池寿命。

其中,包含按键阵列扫描函数、数码管扫描显示函数、随机数产生函数(采用单片机内部定时器和随机数算法)、输入密码比对函数、报警提示和开锁函数、正确密码生成函数、主函数。其中,主函数连接各个函数,实现简易智能密码锁。方案条理清晰,设计依照上述的流程进行,方案设计合理。

2.单片机外围晶振和复位电路

在STC89C52单片机中,首先需要搭建外围电路,在XTAL1、XTAL2两个端口,连接12MHz的晶振和两个电容值在30pF以下的瓷片电容。同时,在单片机的RST端口连接单片机的复位电路,采用一个10k欧姆的电阻和10uF的极性电容构成。其他的端口分别设置为IO口,分配给各工作电路进行使用。

对于此连接方式,采用官方给出的数据手册进行连接,保证了单片机的正常工作,设计方案合理。

e1f3780a1112460f9f11abc7645f4843.png   

3.按键阵列扫描电路

 由于单片机端口数量足够,键盘电路直接使用查询式按键扫描电路。其中,小按键开关的一端接单片机端口,另一端接地,当按下按键时,通过单片机查询来确定哪个端口键按下了,然后执行相应的控制程序。其中,2个为功能键,10个为0~9数字键,每个按键均接上拉电阻,用于防止外部干扰的扰动。端口P1.0~P1.7分别对应数字键0~7,端口P3.0、P3.1分别对应数字键8、9;端口P3.2、P3.3分别对应随机数显示和输入密码界面。在开锁时先按一下随机数显示按键,查看此时的随机数显示的情况,根据自带的密码计算算法(在本系统采用后两位数字与前两位数字更换),计算出此时的正确密码。然后再按下输入密码操作键,输人6位的数字密码,当6位密码输入完毕时,系统会自动将新密码存入存储器,用于比对密码正确性。

 在本方案中,各个按键分开独立工作,并无影响,将输入的按键信号传入单片机,方案设计合理。

图示为操作按键连接电路图:

62055e22464448eda65848df8a641b78.png

4.数码管显示电路

 数码管显示采用共阴极四位一体的显示器7SEG-MPX4-CA-RED,输入6位密码,共有两个数码管。其中,P0口负责输出显示数码管的段码,端口接上拉电阻;P2口为数码管的位控扫描控制口,对每个数码管进行约1ms的轮流正电压供电,共使用6个端口来进行控制。两个数码管的左边的8个引脚分别对应段码输出最低位至最高位,DP为小数点位,而两个数码管的右边的4条引脚分别为4位数码管的阴极供电端,用于控制数码管的位控输出。

在数码管的显示控制中,分别使用单片机的P0口、P2口来完成数码管的扫描输出,合理调节扫描时间,可以正确显示数字的情况,方案设计合理。

图为数码管引脚情况和显示电路:

c010f4e009cd46f5a6fe39bc3ec3fb53.png

5.报警提示和开锁电路

蜂鸣器驱动电路:端口P3.5对应蜂鸣器驱动,起到信息警示,作为密码输入正确或错误的声音提示,密码正确时响一下声音,且时间较长;密码输入错误时响短暂声音,后可再次输入密码,但总共只有5次机会,5次密码错误后,系统自动锁死,60s之后便可以重新输入密码。其中,在每一次随机数进行更新时,与P3.6连接的二极管会闪烁一下,用于提示。

继电器开锁电路:端口P3.4对应继电器(使用发光二极管代替)开锁,起到开锁的作用。在本系统中,连接灯泡,用于锁开启提示,亮时表示开启成功,实际应用时可接电磁开锁线圈驱动电路,开启5s之后,灯泡闪烁,继电器关闭。

本方案在连接蜂鸣器和继电器时,要合理的参照器件特性,按照下图进行连接,方案设计合理。图示为蜂鸣器与红色发光二极管提示电路:

dc561d8896fe488182ad27a069bc0b46.png

三、总原理图及元器件清单

    1.总原理图(软件proteus)

1c9bcaab7d004a8ba99dfe6a4897b814.jpg

 

2.元件选择耗材及价格清单

元件序号

型号

主要参数

数量

单价

备注

R1~R14

RES40

10k欧姆

12

0.05元

R15~R17

RES40

1k欧姆

3

0.05元

C1~C2

CAP10

47pF

2

0.1元

C3

CAP10

10uF

1

0.1元

Button1~12

Button

4脚

12

0.1元

CRYSTAL

CRYSTAL

12MHZ

1

0.3元

7SEG-MPX4--CC

S4041AS

4位共阴极

2

0.5元

AT89C52

STC89C52RC.X90C

单片机

1

2元

LED

LED

Led灯

4

0.3元

BUZZER

TMB 12A03

蜂鸣器

1

1.5元

2N5551

S 9014 C331

三极管

1

0.3元

RESPACK-8

RESPACK

排阻

1

0.2元

单面绿油板

单面绿油板

15*20cm

1

5元

导线、锡丝

导线、锡丝

导线、锡丝

若干

若干

 

 

三、总原理图及元器件清单

 

 

 

四、

四、程序流程图

ebb95cf314754effac4b6ae98dd09f18.png

五、性能测试与分析

指标1:对于单片机的按键输入密码的有效位数为6位;在下面的界面显示中,具有6位密码界面输入和显示。达到此性能指标。

aab9b48da91d48a680dbd9a96d7ead28.png

指标2单片机中的密码与当前单片机定时器系统时间相关,每隔1分钟,密码自动更新。

当前显示的随机数为361524,此时的正确密码是241536。在间隔1分钟之后,密码更新,此时的随机数显示为375892,此时的正确密码是925837。达到此性能指标。

 af02fdfbe18644fe8fc6ad1e2ce70c1c.png

指标3如果密码正确,蜂鸣器响0.5秒,开锁继电器吸合,5秒后开锁继电器关闭。在下面的显示中,当输入密码正确时,代表开锁继电器的灯泡会亮起,5秒之后,灯泡熄灭。达到此性能指标。

77d9b6f51c9e4571b5a6b0c1a1477749.png

指标4密码尝试5次出错,则停止尝试1分钟。达到此性能指标。

 b382346b3d6b4a46b349930fbb9f11eb.png

其他性能指标:

在基于指标3中,在输入密码正确的情况下,加入了更加人性化的界面信息,ONONON表示此时开锁,同时,在关闭继电器时,灯泡和蜂鸣器均会闪烁,提醒使用者。

在基于指标4中,当输入密码错误时,显示ERRERR,,表示此时输入密码错误,同时,在5次输入密码错误时,系统锁定,界面显示倒计时信息,60s倒计时结束之后,可再次输入密码。

总体来说,提高部分的指标加强了本装置的人机交互的能力,将人性化的思想得到很大程度的体现。

六、设计作品图片  

f8de9ce9d50846698098be221255d5cc.png

七、结论与心得


问题1:焊接单片机的晶振和复位电路。单片机不能够进行程序烧录。

解决方法:了解到此问题之后,我在网上查阅相关的资料。资料显示单片机不能正常工作,与外围的晶振和复位电路有很大的关系。同时,在咨询老师的意见之后,我对单片机的晶振和复位电路进行了详细的检查。其中两个瓷片电容应该焊接在晶振的后面,同时晶振应该离单片机的引脚非常接近,否则电容不起振,晶振也无法正常工作,同时电容所采取的电容值应该按照说明书文档上所标注的33pF以下。

问题2:数码管电路焊接。共阴极,共阳极没有区分,同时数码管的亮度非常低。

解决方法针对于此现象的产生,在网上查询相关的数码管使用方法,掌握了数码管共阴极,共阳极的测量方法。共阴极数码管的测量方法应该是:用电源的负极夹住数码管的位控端,同时用1V左右的电源正极依次触碰数码管的八个段码口,如果数码管此时各段正常亮起,则说明数码管是共阴极数码管,反之是共阳极数码管。在正确焊接到单片机电路板上的时候,应该检查数码管是否正常,在我使用的数码管中有一个损坏,经过多次检查才发现。同时单片机IO口输出的电流非常小,需要采取通过电流较小的数码管来进行显示,此处我采用型号为数码管S4041AS来实现以上电路。

问题3:单片机重要程序编写。在本次项目设计中,程序编写难度最大的部分,我认为应该在于数码管随机数的产生、显示以及按键密码的比对函数。

解决方法:参照网上现有的资料,我认真学习单片机定时器的相关使用,同时针对于随机数的产生,我也认真的学习了相关的算法,在反复编译文件中得到此次问题的解决。同时,在密码比对函数中我创造性的提出了利用多维数组来进行密码比对,分别设置存储密码和比对的新密码,同时设定标志位,并在外围运用多次循环用于控制密码错误的次数,进而形成一个按键输入比对的函数,可以很好的被单片机来进行调用。

 

课题改进我觉得可以将数码管显示电路替换为LCD屏幕进行多信息、多维度的展示,让人机交互界面更加的人性化。同时基于实验室现有器材可以将灯泡更换为继电器,真正让智能密码锁具有继电器开锁的相关功能。

课题背景:该项目具有广大的背景,因为在现在的生活中,安全性成为一个不可忽视的问题。生活中许多多的物品需要用“锁”来锁住。智能密码锁提供了一个很好的解决方案,它具有高效、便捷、不易被破解等相关功能,本次课题设计为这种方案的实现提供了一个很好的参考,在以后的实际应用中,更换更加坚固可靠的材料,可以将此产品真正的走向实用化。

八、程序代码

#include <reg52.h>

#include <stdlib.h>   //rand()函数导入,产生随机数
#include <math.h>

sbit P10 = P1 ^ 0; // 数字0  // 按键定义
sbit P11 = P1 ^ 1; // 数字1
sbit P12 = P1 ^ 2; // 数字2
sbit P13 = P1 ^ 3; // 数字3
sbit P14 = P1 ^ 4; // 数字4
sbit P15 = P1 ^ 5; // 数字5
sbit P16 = P1 ^ 6; // 数字6
sbit P17 = P1 ^ 7; // 数字7
sbit P30 = P3 ^ 0; // 数字8
sbit P31 = P3 ^ 1; // 数字9

sbit P32 = P3 ^ 2; // 随机数显示界面
 
sbit P33 = P3 ^ 3; // 密码输入界面

sbit P34 = P3 ^ 4; // 继电器驱动

sbit P35 = P3 ^ 5; // 蜂鸣器驱动
sbit P36 = P3 ^ 6; //定时器更新时,灯闪一下

sbit P37 = P3 ^ 7;   //预留口--暂时未使用

sbit P00 = P0 ^ 0; // 数码管段码
sbit P01 = P0 ^ 1;
sbit P02 = P0 ^ 2;
sbit P03 = P0 ^ 3;
sbit P04 = P0 ^ 4;
sbit P05 = P0 ^ 5;
sbit P06 = P0 ^ 6;
sbit P07 = P0 ^ 7;

sbit P20 = P2 ^ 0; // 数码管位码  工作电压值
sbit P21 = P2 ^ 1;
sbit P22 = P2 ^ 2;
sbit P23 = P2 ^ 3;
sbit P24 = P2 ^ 4;
sbit P25 = P2 ^ 5;
sbit P26 = P2 ^ 6;
sbit P27 = P2 ^ 7;

// 共阴显示段码表: 0 1 2 3 4 5 6 7 8 9 - n 不亮 三 E r  f      
char code dis_7[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,   //0~9
                       0x40, 0xb7, 0xff, 0x49, 0x79, 0x70,0x71};

// 控制七段数码管的工作电压,0x01表示最左端数码显示  从左往右显示顺序
char code scan_con[6] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf};

// 储存显示于数码管上面的值,最开始显示“888888”,顺便检验数码管有没有损坏的现象
unsigned char dia[6] = {8, 8, 8, 8, 8, 8};

// 用于储存密码和算法输入密码的数值情况,data1[0][]为算法设定的密码,data1[1][]为输入的密码
unsigned char dat1[2][6] = {0, 0, 0, 0, 0, 0};

unsigned char dat2[6]; // 显示缓存

bit flag = 0, flag1 = 0; // 标志位

int c = 0;

int count;   //随机数生成--定时器
int count1;   
int count2; // 定时器计数标志位  初始化

int a1 ;   //倒计时总时间

int n;  //延时for循环

void delay(int t) // 延时程序
{
    int i, j;
    for (i = 0; i < t; i++)
        for (j = 0; j < 120; j++)  ;}

// 数码管扫描  段码和位码
void scan(void)
{
    unsigned  char k;
    for (k = 0; k < 6; k++) // 6个小数码管扫描
    {
        P0 = dis_7[dia[k]]; // 段码
        P2 = scan_con[k];   // 位码
        delay(1);
        P0 = 0x00;  // 扫描后关闭当前口,避免闪烁!!!!
    }
}

// 密码输入提示显示信息       --不需要更改
// 当输入设定值之后显示“------”,等待输入密码显示“------”
void displayinput(void)
{
    dia[0] = 0x0a;    
    dia[1] = 0x0a;
    dia[2] = 0x0a;
    dia[3] = 0x0a;
    dia[4] = 0x0a;
    dia[5] = 0x0a;
    scan();
}

// 按键输入处理程序            
void input(char x) // x=1表示输入密码
{
    char i, j = 0; // j作为是否有按键输入的标志位
    for (i = 0; i < 6; i++, j = 0)

        while (j == 0)
        {
            scan();
            if (P10 == 0) // P10端口表示设定0     //低电平时有密码输入
            {
                while (P10 == 0)
                    scan();
                if (x == 0)
                    dia[i] = 13;
                else
                    dia[i] = 0;
                j = 1;
                dat1[x][i] = 0;
            }
            if (P11 == 0) // P11端口表示设定1
            {
                while (P11 == 0)
                    scan();
                if (x == 0)
                    dia[i] = 13;
                else
                    dia[i] = 1;
                j = 1;
                dat1[x][i] = 1;
            }
            if (P12 == 0) // P12端口表示设定2
            {
                while (P12 == 0)
                    scan();
                if (x == 0)
                    dia[i] = 13;
                else
                    dia[i] = 2;
                j = 1;
                dat1[x][i] = 2;
            }
            if (P13 == 0) // P13端口表示设定3
            {
                while (P13 == 0)
                    scan();
                if (x == 0)
                    dia[i] = 13;
                else
                    dia[i] = 3;
                j = 1;
                dat1[x][i] = 3;
            }
            if (P14 == 0) // P14端口表示设定4
            {
                while (P14 == 0)
                    scan();
                if (x == 0)
                    dia[i] = 13;
                else
                    dia[i] = 4;
                j = 1;
                dat1[x][i] = 4;
            }
            if (P15 == 0) // P15端口表示设定5
            {
                while (P15 == 0)
                    scan();
                if (x == 0)
                    dia[i] = 13;
                else
                    dia[i] = 5;
                j = 1;
                dat1[x][i] = 5;
            }
            if (P16 == 0) // P16端口表示设定6
            {
                while (P16 == 0)
                    scan();
                if (x == 0)
                    dia[i] = 13;
                else
                    dia[i] = 6;
                j = 1;
                dat1[x][i] = 6;
            }
            if (P17 == 0) // P17端口表示设定7
            {
                while (P17 == 0)
                    scan();
                if (x == 0)
                    dia[i] = 13;
                else
                    dia[i] = 7;
                j = 1;
                dat1[x][i] = 7;
            }
            if (P30 == 0) // P30端口表示设定8
            {
                while (P30 == 0)
                    scan();
                if (x == 0)
                    dia[i] = 13;
                else
                    dia[i] = 8;
                j = 1;
                dat1[x][i] = 8;
            }
            if (P31 == 0) // P31端口表示设定9
            {
                while (P31 == 0)
                    scan();
                if (x == 0)
                    dia[i] = 13;
                else
                    dia[i] = 9;
                j = 1;
                dat1[x][i] = 9;
            }
        }
}

// 将随机数设定的密码与输入界面的密码核对
void jiemi(void)
{
    char i, j, m = 0;
    for (i = 0; i < 2; i++)
    {
        input(1);    // 输入密码
        for (j = 0; j < 6; j++)
        {
            if (dat1[0][j] != dat1[1][j]) // 随机数密码与输入密码比较
            {
                m = 1; // 不对
                break;
            }
        }
        if (m == 1)       // 核对错误
        {
            if (i < 1) // 错两次
            {
               int n;
                // 以下显示Err约3s,蜂鸣器响3s
                for (n = 0; n < 300; n++)
                {
                    dia[0] = 0x0e;   //显示ErrErr
                    dia[1] = 0x0f;
                    dia[2] = 0x0f;
                    dia[3] = 0x0e;
                    dia[4] = 0x0f;
                    dia[5] = 0x0f;

                    P35 = 1;       //蜂鸣器响
                    scan();
                }
								
                // 以下显示“------” ,等待输入新的密码
                dia[0] = 0x0a;
                dia[1] = 0x0a;
                dia[2] = 0x0a;
                dia[3] = 0x0a;
                dia[4] = 0x0a;
                dia[5] = 0x0a;
                scan();
								
                P35 = 0;     //蜂鸣器关闭
                m = 0;   //标志位不翻转,再次输入密码
            }

            else // 错三次      在此处,需要一直显示Err,蜂鸣器二者持续3S
            //由于系统锁死1分钟,因此在数码上面显示倒计时60s,再打开系统。
            {
                flag = 1;    //标志位先为1,无法输入数据
							
                // 以下显示Err约3s,蜂鸣器响3s
                for ( n = 0; n < 100; n++)
                {
                    dia[0] = 0x0e;   //显示ErrErr
                    dia[1] = 0x0f;
                    dia[2] = 0x0f;
                    dia[3] = 0x0e;
                    dia[4] = 0x0f;
                    dia[5] = 0x0f;

                    P35 = 1;       //蜂鸣器响
                    scan();
                }
                P35 = 0;   //蜂鸣器关闭

                a1 = 60;
                count2 = 0;
                while (count2 <= 1000)    // 系统锁死   定时60秒  60ms每次
                {    
                    scan();      
         
	//!!!!注意在这里不能直接让count2为0进入,否则while进不去,  因为scan();会耗时
					while(count2 == (61-a1)*16)   //每到1s
                    {
                        dia[0] = a1 / 10;     //60的倒计时显示
                        dia[1] = a1 % 10;
                        
                        dia[2] = 0x0a;  // 中间显示 "-"
                        dia[3] = 0x00;  //在界面显示off
                        dia[4] = 16;
                        dia[5] = 16;
                        scan();

                        a1--;  //倒计时自减
                    }                  
                }							
                flag = 0;   //标志位反转,可以输入密码
                // 以下显示“------” ,等待输入新的密码
                dia[0] = 0x0a;
                dia[1] = 0x0a;
                dia[2] = 0x0a;
                dia[3] = 0x0a;
                dia[4] = 0x0a;
                dia[5] = 0x0a;
                scan();
								
				        break;
            }
        }
				
        else if (m == 0)    // 核对正确时
        {
            count1 = 0;   //界面显示计时
            while (count1 <= 50) // 密码正确  定时3秒  60ms每次
            {
                dia[0] = 0x00;    //在界面显示ononon
                dia[1] = 0x0b;
                dia[2] = 0x00;
                dia[3] = 0x0b;
                dia[4] = 0x00;
                dia[5] = 0x0b;
                scan();

                P35 = 1;     //蜂鸣器响
                P34 = 0;    //继电器--灯亮
            }

            while (count1 <= 70)      // 密码正确  定时2秒  60ms每次
            {											               
                for ( n = 0; n < 30; n++)
                {
					P35 = 1;     //蜂鸣器间断响
					delay(150);
					P35 = 0; 
									
					P34 = 0;     //灯间断闪亮
					delay(150);
					P34 = 1;
									
                }
								
            } 

            P35 = 1;   //蜂鸣器和灯泡(继电器均关闭)
            P34 = 1; 

            // 以下显示“------” ,等待输入新的密码
                dia[0] = 0x0a;
                dia[1] = 0x0a;
                dia[2] = 0x0a;
                dia[3] = 0x0a;
                dia[4] = 0x0a;
                dia[5] = 0x0a;
                scan();

                break;
        }
    }
}

unsigned long int random_number = 112233; // 初始的随机数

void time_random_number() interrupt 1 using 1 // 定时器生成随机数
{
    TH0 = (65536 - 60000) / 256;    // 先实现60ms
    TL0 = (65536 - 60000) % 256;
    count++;  // 随机数叠加的计数
    count1++; // 蜂鸣器的叠加计数
    count2++; // 继电器的叠加计数

    if (count == 1000 )   // 定时3分钟3000,定时1分钟1000,定时3秒50,定时30秒500
    {
        // 生成随机数    // 使用此系列值作为随机数种子
        int i; 
        int digits[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        int num_digits = 9; // 手动指定数组元素数量
        // Fisher-Yates洗牌算法
        for (i = num_digits - 1; i > 0; --i)
        {
            int j = rand() % (i + 1);
            int temp = digits[i];
            digits[i] = digits[j];
            digits[j] = temp;
        }
				
        // 取前6位数字作为随机数
        for (i = 0; i < 6; ++i)
        {
            random_number = random_number * 10 + digits[i];
        }

        count = 0;

        P36 = 0;      // 每次在随机数进行更新的时候,灯会闪一下
        delay(150);
        P36 = 1;
    }
}
void main(void)
{
    // 定时器模块初始化
    TMOD = 0x01;                    // 定时器0工作在模式1
    TH0 = (65536 - 60000) / 256;    // 先实现60ms
    TL0 = (65536 - 60000) % 256;
    TR0 = 1; // 启动定时器0
    IE = 0x82;		        //允许T0中断

    while (1)
    {
	      P35 = 0;       //先关闭蜂鸣器
			  P34 = 1;       //先关闭灯
             
        scan(); // 储存数码管的值显示

        // 随机数位置交换                                                                                           
        if (random_number != 0) // 判断是否有随机数生成
        {
            // 随机数的交换算法设计
            // 提取前两位和后两位数字
            unsigned long int first_two_digits = random_number / 10000;         // 前两位数字
            unsigned long int zhongjian_two_digits = random_number / 100 % 100; // 中两位数字
            unsigned long int last_two_digits = random_number % 100;            // 后两位数字

            // 交换前两位和后两位数字: 新密码
            unsigned long int swapped_number = last_two_digits * 10000 + zhongjian_two_digits * 100 
                                                            + first_two_digits;
					
            dat1[0][0] = swapped_number / 100000;      //算法交换的密码缓存  
            dat1[0][1] = swapped_number / 10000 % 10;
            dat1[0][2] = swapped_number / 1000 % 10;
            dat1[0][3] = swapped_number / 100 % 10;
            dat1[0][4] = swapped_number / 10 % 10;
            dat1[0][5] = swapped_number / 1 % 10;

            dat2[0] = random_number / 100000;      // 随机数显示缓存 
            dat2[1] = random_number / 10000 % 10;
            dat2[2] = random_number / 1000 % 10;
            dat2[3] = random_number / 100 % 10;
            dat2[4] = random_number / 10 % 10;
            dat2[5] = random_number / 1 % 10;
						
            random_number = 0;   //将随机数清0,用于判断是否有随机数生成
        }

        if (P32 == 0) // 随机数显示界面
        {             // 将dat1[0][i]送出数码管显示
            unsigned int k;

            for (k = 0; k < 6; k++) // 6个扫描
            {
                dia[k] = dat2[k]; //  数字传入scan()函数扫描random_number
            }            
        }

        if (P33 == 0) // 密码输入界面
        {
            if (flag == 0)
            {
                displayinput();   // 显示"------"
                jiemi();        // 调用input函数输入密码,在jiemi函数中比对
            }
        }
    }
}

 

 

 

 

### bin-ace-editor 使用指南 #### 安装与下载 为了使用 `bin-ace-editor`,首先需要安装依赖项。由于这是一个基于 Web 的开源代码编辑器,通常可以通过 npm 或 yarn 来安装。 ```bash npm install --save wangbin3162-bin-ace-editor ``` 或者通过 yarn: ```bash yarn add wangbin3162-bin-ace-editor ``` 请注意,具体的包名可能有所不同,建议查阅官方文档或 GitHub 页面确认最新名称[^1]。 #### 配置与初始化 在项目中集成此编辑器时,可以采用全局引入的方式,在项目的入口文件(如 `main.js`)中配置如下所示: ```javascript import Editor from 'wangbin3162-bin-ace-editor'; Vue.use(Editor); ``` 如果是在单个组件内局部加载,则可以在相应组件里这样写: ```javascript components: { Editor, }, ``` 这使得开发者可以根据实际需求灵活选择引入方式[^2]。 #### 示例教程 下面提供了一个简单的例子来展示如何创建并自定义一个基本的 `bin-ace-editor` 组件实例: ```html <template> <div id="app"> <!-- 创建编辑区域 --> <editor v-model="code" @init="editorInit"></editor> </div> </template> <script> export default { data() { return { code: '' } }, methods: { editorInit(editor) { // 初始化设置 editor.setTheme('ace/theme/monokai'); editor.getSession().setMode('ace/mode/javascript'); } } } </script> ``` 上述代码片段展示了如何设定主题和语法高亮模式,这些都可以根据个人喜好调整[^3]。 #### 获取选中的内容 对于一些高级操作,比如获取用户当前选中的文本或行号,可通过调用特定的方法实现: ```javascript // 获取选中文本 const selectedText = editor.session.getTextRange(editor.getSelectionRange()); // 获取选定行的信息 function getCurrentLineInfo(editor){ let cursorPosition = editor.getCursorPosition(); let currentRow = cursorPosition.row; console.log(`Current Line Number:${currentRow}`); } getCurrentLineInfo(editor); ``` 这段脚本说明了怎样访问用户的交互数据,这对于开发更复杂的应用程序很有帮助[^4]。
评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无名氏AA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值