STM32项目分享:基于stm32的智能门锁系统

“我们不做一锤子买卖,只做技术成长的长期伙伴!”

目录

一、视频展示

二、项目简介

三、原理图设计

四、PCB硬件设计

五、程序设计

六、资料分享


一、视频展示

基于stm32的智能门锁系统-视频分享

二、项目简介

该设计由STM32F103C8T6作为主控芯片和蜂鸣器电路以及供电电路,0.96oled显示屏,4*4矩阵键盘,RC522刷卡模块,指纹模块,蓝牙,一个继电器模拟电子锁开关状态。

本设计的功能:
 1、 屏幕显示
    显示当前密码输入状态,指纹录入或删除状态,指纹解锁,刷卡状态,添加卡片或者删除卡片,电子锁开关状态,按键修改密码,按键输入密码;
 2、密码修改
    在主页面按下 KEY_SAVE对应按键会进行密码修改,或者按键删除或者添加指纹或者卡片。
3、继电器模拟电子锁
    当密码或指纹或者对应的卡片成功解锁后,继电器会打开,然后在三秒后会关闭,模拟电子锁的安全状态。
4、蜂鸣器提醒
    当密码错误时,蜂鸣器会滴滴叫,提示密码错误,按按键也会有滴滴声。
5、指纹识别
    按下 KEY_SET键进行识别。
6、指纹添加
    按下KEY_ADD进行指纹添加。
7、指纹删除
    按下 KEY_DEC进行指纹添加。
8、卡片识别
    按下KEY_Asterisk键进入卡片选项,此时按下KEY_SET进行识别开锁,按下KEY_ADD进行卡片添加,按下 KEY_DEC进行卡片删除,按下KEY_SAVE退出此模式。
9、蓝牙解锁

三、原理图设计

四、PCB硬件设计

五、程序设计


#include "stm32f10x.h"                  // 设备头文件
#include "delay.h"                      // 延迟函数库
#include "lcd.h"                        // LCD显示库
#include "IOput.h"                      // 输入输出控制库
#include "timer.h"                      // 定时器库
#include <string.h>                     // 字符串库
#include <stdbool.h>                    // 布尔类型库
#include "as608.h"                      // 指纹模块库
#include "usart.h"                      // 串口通信库
#include "RC522.H"                      // RC522刷卡模块库
  

bool CARDScanFlag, OpenDoorFlag;         // 卡片扫描标志和开门标志

char status;                             // 状态变量
unsigned char snr, read_buf[16], write_buf[16], TagType[2], SelectedSnr[4], DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // RFID相关变量

u8 door_state;                           // 门状态变量
u8 Code[6] = {0, 0, 0, 0, 0, 0};         // 正确密码
u8 CodeBuf[6];                           // 用户输入的密码缓存
u8 CodeIndex = 0;                        // 用户当前输入的密码长度
u8 tryCount = 0;                         // 尝试输入密码的次数

bool BlinkState;                         // 闪烁状态变量
#define CodeBufX1Pos 16
#define CodeBufX2Pos 32
#define CodeBufX3Pos 48
#define CodeBufX4Pos 64
#define CodeBufX5Pos 80
#define CodeBufX6Pos 96
#define CodeBufYPos 5

u8 SystemRequirement = 0;                // 系统需求变量
#define NoRequirement 1
#define UnlockWithCode 2
#define UnlockWithFingerprint 3
#define AddFingerprint 4
#define DecFingerprint 5
#define ChangePassword 6
#define UnlockWithAliyun 7
#define IDCARD 9

u8 CodeCompareState = 0;                 // 密码比较状态变量
#define NoNeedToCompare 0
#define WaitToCompare 1
#define CodeRight 2
#define CodeWrong 3
#define WrongThreeTimes 4
#define UpdateCode 5

void ShowOrignState(void)                // 初始界面显示函数
{
    OLED_ShowCH(0, 0, "   电子密码锁");
    OLED_ShowCH(0, 2, "  指纹    刷卡 ");
    OLED_ShowCH(0, 4, "      密码     ");
    OLED_ShowCH(0, 6, " 请按键操作解锁");
    JDQ = 1;                             // 关闭继电器
}

void ShowFingerRightState(void)          // 指纹正确显示函数
{
    OLED_ShowCH(0, 0, " 电 子 密 码 锁");
    OLED_ShowCH(0, 2, " 指纹正确");
    OLED_ShowCH(0, 4, " 门已开,请进");
    JDQ = 0;                             // 打开继电器
}

void ShowFingerWrongState(void)          // 指纹错误显示函数
{
    OLED_ShowCH(0, 0, " 电 子 密 码 锁");
    OLED_ShowCH(0, 2, " 指纹错误");
    OLED_ShowCH(0, 4, " 请重试");
}

void CompareCodeAndGetResult(void)       // 密码比较函数
{
    if(memcmp(Code, CodeBuf, 6) == 0)    // 比较输入的密码和正确的密码
    {
        OLED_Clear();
        tryCount = 0;
        CodeCompareState = CodeRight;    // 密码正确
    }
    else
    {
        OLED_Clear();
        if(tryCount >= 3)                // 如果错误尝试次数超过3次
        {
            CodeCompareState = WrongThreeTimes; // 锁定
        }
        else
        {
            CodeCompareState = CodeWrong; // 密码错误
            tryCount++;
        }
    }
}

void BEEPDD(void)                        // 蜂鸣器滴滴声函数
{
    BEEP = 0;
    delay_ms(100);
    BEEP = 1;
    delay_ms(100);
    BEEP = 0;
    delay_ms(100);
    BEEP = 1;
    delay_ms(100);
    BEEP = 0;
    delay_ms(100);
    BEEP = 1;
    delay_ms(100);
}

void ShowInputCode(void)                 // 显示输入密码函数
{
    TIM_Cmd(TIM2, ENABLE);               // 使能TIM2定时器
    while(1)
    {
        key_num = key_scan(1);           // 扫描按键
        if(time_count >= 20)
        {
            time_count = 0;
            BlinkState = !BlinkState;    // 切换闪烁状态
        }
        if((key_num != KEY_NONE) && key_num <= 9)
        {
            CodeBuf[CodeIndex++] = key_num; // 存储按键值
            key_num = KEY_NONE;          // 清除键值
            
            if(CodeIndex == 6)           // 如果输入了6个数字
            {
                CodeIndex = 0;
                break;
            }
        }
        switch(CodeIndex)
        {
            case 0 :
                if(BlinkState)
                    OLED_ShowCH(CodeBufX1Pos, CodeBufYPos, " ");
                else
                    OLED_ShowCH(CodeBufX1Pos, CodeBufYPos, "-");
                OLED_ShowCH(CodeBufX2Pos, CodeBufYPos, "- - - - -");
                break;
            case 1 :
                OLED_ShowCH(CodeBufX1Pos, CodeBufYPos, "*");
                if(BlinkState)
                    OLED_ShowCH(CodeBufX2Pos, CodeBufYPos, " ");
                else
                    OLED_ShowCH(CodeBufX2Pos, CodeBufYPos, "-");
                OLED_ShowCH(CodeBufX3Pos, CodeBufYPos, "- - - -");
                break;
            case 2 :
                OLED_ShowCH(CodeBufX1Pos, CodeBufYPos, "* *");
                if(BlinkState)
                    OLED_ShowCH(CodeBufX3Pos, CodeBufYPos, " ");
                else
                    OLED_ShowCH(CodeBufX3Pos, CodeBufYPos, "-");
                OLED_ShowCH(CodeBufX4Pos, CodeBufYPos, "- - -");
                break;
            case 3 :
                OLED_ShowCH(CodeBufX1Pos, CodeBufYPos, "* * *");
                if(BlinkState)
                    OLED_ShowCH(CodeBufX4Pos, CodeBufYPos, " ");
                else
                    OLED_ShowCH(CodeBufX4Pos, CodeBufYPos, "-");
                OLED_ShowCH(CodeBufX5Pos, CodeBufYPos, "- -");
                break;
            case 4 :
                OLED_ShowCH(CodeBufX1Pos, CodeBufYPos, "* * * *");
                if(BlinkState)
                    OLED_ShowCH(CodeBufX5Pos, CodeBufYPos, " ");
               

 else
                    OLED_ShowCH(CodeBufX5Pos, CodeBufYPos, "-");
                OLED_ShowCH(CodeBufX6Pos, CodeBufYPos, "-");
                break;
            case 5 :
                OLED_ShowCH(CodeBufX1Pos, CodeBufYPos, "* * * * *");
                if(BlinkState)
                    OLED_ShowCH(CodeBufX6Pos, CodeBufYPos, " ");
                else
                    OLED_ShowCH(CodeBufX6Pos, CodeBufYPos, "-");
                break;
            default: break;
        }
    }
}

void SystemUpdateCode(void)              // 系统更新密码函数
{
    for(u8 i = 0; i < 6; i++)
        Code[i] = CodeBuf[i];
    OLED_ShowCH(0, 4, " 修改密码成功");
}

int main (void)
{
    delay_init();                        // 初始化延时函数
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置中断优先级组
    
    output_init();                       // 初始化输出
    input_init();                        // 初始化输入
    OLED_Init();                         // 初始化OLED显示屏
    delay_ms(1);                         // 延时1ms
    OLED_Clear();                        // 清屏
    Usart1_Init(9600);                   // 初始化串口1,波特率9600
    Usart2_Init(57600);                  // 初始化串口2,波特率57600
    TIM4_Int_Init(99, 7199);             // 初始化定时器4,10ms中断
    USART2_RX_STA = 0;                   // 清零
    TIM_Cmd(TIM4, DISABLE);              // 关闭定时器4
    TIM2_Int_Init(71, 9999);             // 初始化定时器2
    ShowOrignState();                    // 显示初始界面
    
    PcdInit();                           // 初始化RC522
    PcdAntennaOff();                     // 关闭天线
    PcdAntennaOn();                      // 打开天线
    PcdReset();                          // 重置RC522
    M500PcdConfigISOType('A');           // 配置ISO类型

    while(1)
    {
        key_num = key_scan(1);           // 扫描按键
        if(key_num == KEY_Hashtag)
        {
            key_num = KEY_NONE;
            SystemRequirement = UnlockWithCode; // 密码解锁
        }
        else if(key_num == KEY_SET)
        {
            key_num = KEY_NONE;
            SystemRequirement = UnlockWithFingerprint; // 指纹解锁
        }
        else if(key_num == KEY_ADD)
        {
            key_num = KEY_NONE;
            SystemRequirement = AddFingerprint; // 添加指纹
        }
        else if(key_num == KEY_DEC)
        {
            key_num = KEY_NONE;
            SystemRequirement = DecFingerprint; // 删除指纹
        }
        else if(key_num == KEY_Asterisk)
        {
            key_num = KEY_NONE;
            SystemRequirement = IDCARD;  // 刷卡
            CARDScanFlag = 1;
        }
        else if(key_num == KEY_SAVE)
        {
            key_num = KEY_NONE;
            SystemRequirement = ChangePassword; // 修改密码
        }
        if(SystemRequirement == NoRequirement)
        {
            ShowOrignState();          // 显示初始界面
        }
        else if(SystemRequirement == IDCARD)
        {
            OLED_Clear();
            if(CARDScanFlag)
            {
                time_count = 0;
                while(1)
                {
                    key_num = key_scan(1); // 扫描按键
                    OLED_ShowCH(0, 0, "  刷卡识别门禁");
                    OLED_ShowCH(0, 2, "SET识别 ADD添加");
                    OLED_ShowCH(0, 4, "    DEC删除");
                    
                    if(key_num == KEY_SAVE)
                    {
                        key_num = KEY_NONE;
                        SystemRequirement = NoRequirement; // 无需求
                        OLED_Clear();
                        break;
                    }
                    if (key_num == KEY_SET)
                    {
                        OLED_Clear();
                        OLED_ShowCH(0, 2, " RFID识别模式");
                        key_num = KEY_NONE;
                        while(1)
                        {
                            status = PcdRequest(REQ_ALL , TagType); 
                            if(!status) // 如果请求成功
                            {
                                status = PcdAnticoll(SelectedSnr); // 防冲突操作,获取唯一序列号(UID)
                                if(!status) // 如果防冲突操作成功
                                {
                                    status = PcdSelect(SelectedSnr); // 选择指定序列号的卡片
                                    if(!status) // 如果选择卡片成功
                                    {
                                        snr = 1; // 设置扇区号为 1
                                        status = PcdAuthState(KEYA, (snr*4+3), DefaultKey, SelectedSnr); 
                                        // 使用密钥 A 对指定扇区进行验证
                                        {
                                            if(!status) // 如果验证成功
                                            {
                                                status = PcdRead((snr*4+0), read_buf); // 从指定扇区的块0读取数据到缓冲区
                                                if(!status) // 如果读取成功
                                                {
                                                    WaitCardOff(); // 等待卡片离开感应区
                                                    OLED_ShowCH(0, 2, " RFID识别成功");
                                                    delay_ms(1500);
                                                    OLED_Clear();
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if(read_buf[0] == 1)
                        {
                            OpenDoorFlag = 1;
                            break;
                        }
                        if(read_buf[0] == 0)
                        {
                            OpenDoorFlag = 0;
                            break;
                        }                                
                    }
                    
                    if (key_num == KEY_ADD)
                    {
                        OLED_Clear();
                        key_num = KEY_NONE;
                        OLED_ShowCH(0, 2, " RFID录入模式");
                        write_buf[0] = 1;
                        while(1)
                        {
                            status = PcdRequest(REQ_ALL , TagType); // 请求卡片
                            if(!status)
                            {
                                status = PcdAnticoll(SelectedSnr); // 防冲突操作
                                if(!status)
                                {
                                    status = PcdSelect(SelectedSnr); // 选择卡片
                                    if(!status)
                                    {
                                        snr = 1; // 设置扇区号为 1
                                        status = PcdAuthState(KEYA, (snr*4+3), DefaultKey, SelectedSnr); // 使用密钥 A 对指定扇区进行验证
                                        if(!status)
                                        {
                                            status = PcdWrite((snr*4+0), write_buf); // 写入数据到指定扇区的块0
                                            if(!status)
                                            {
                                                WaitCardOff(); // 等待卡片
                                                OLED_ShowCH(0, 2, " RFID录入成功");
                                                delay_ms(1500);
                                                OLED_Clear();
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (key_num == KEY_DEC)
                    {
                        OLED_Clear();
                        key_num = KEY_NONE;
                        OLED_ShowCH(0, 2, " RFID删除模式");
                        write_buf[0] = 0;
                        while(1)
                        {
                            status = PcdRequest(REQ_ALL , TagType); // 请求卡片
                            if(!status)
                            {
                                status = PcdAnticoll(SelectedSnr); // 防冲突操作
                                if(!status)
                                {
                                    status = PcdSelect(SelectedSnr); // 选择卡片
                                    if(!status)
                                    {
                                        snr = 1; // 设置扇区号为 1
                                        status = PcdAuthState(KEYA, (snr*4+3), DefaultKey, SelectedSnr); // 使用密钥 A 对指定扇区进行验证
                                        if(!status)
                                        {
                                            status = PcdWrite((snr*4+0), write_buf); // 写入数据到指定扇区的块0
                                            if(!status)
                                            {
                                                WaitCardOff(); // 等待卡片
                                                OLED_ShowCH(0, 2, " RFID删除成功");
                                                delay_ms(1500);
                                                OLED_Clear();
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if(OpenDoorFlag == 0)
                {
                    OLED_ShowCH(0, 2, " 无 开 门 权 限");
                    OLED_ShowCH(0, 4, " 或 退 出 刷 卡");
                    OLED_ShowCH(0, 6, "    请重试");
                    BEEP = 0;
                    delay_ms(200);
                    BEEP = 1;
                    delay_ms(200);
                    BEEP = 0;
                    delay_ms(200);
                    BEEP = 1;
                    delay_ms(200);
                    SystemRequirement = NoRequirement;
                }
                else if(OpenDoorFlag == 1)
                {
                    OLED_ShowCH(0, 2, "    开门中");
                    OLED_ShowCH(0, 4, "    请稍候");
                }
                
                if(OpenDoorFlag)
                {
                    JDQ = 0;
                    OpenDoorFlag = 0;
                    OLED_ShowCH(0, 2, "           ");
                    OLED_ShowCH(0, 4, " 门已开,请进");
                    BEEP = 0;
                    delay_ms(200);
                    BEEP = 1;
                    delay_ms(200);
                    BEEP = 0;
                    delay_ms(200);
                    BEEP = 1;
                    delay_ms(200);
                    delay_ms(1000);
                    delay_ms(1000);
                    delay_ms(1000);
                    JDQ = 1;
                    TIM_Cmd(TIM2, DISABLE); // 关闭定时器2
                    OLED_Clear();
                    SystemRequirement = NoRequirement;
                }
            }
        }
        else if(SystemRequirement == UnlockWithFingerprint)
        {
            press_FR();                   // 按压指纹识别
            if(FingerFlag == FingerRight)
            {
                FingerFlag = WaitFinger;
                BEEPDD();
                SystemRequirement = NoRequirement;
                ShowFingerRightState();
                delay_ms(1500);
                delay_ms(1500);
                OLED_Clear();
            }
            else if(FingerFlag == FingerWrong)
            {
                FingerFlag = WaitFinger;
                SystemRequirement = NoRequirement;
                ShowFingerWrongState();
                delay_ms(1500);
                delay_ms(1500);
                OLED_Clear();
            }
        }
        else if(SystemRequirement == ChangePassword)
        {
            OLED_Clear();
            OLED_ShowCH(0, 0, " 修  改  密  码  ");
            OLED_ShowCH(0, 2, "  请输入旧密码");    
            ShowInputCode();
            CompareCodeAndGetResult();
            if(CodeCompareState == CodeRight)
            {
                BEEPDD();
                OLED_ShowCH(0, 0, " 修  改  密  码  ");
                OLED_ShowCH(0, 2, "  密码正确");
                delay_ms(1000);
                OLED_ShowCH(0, 2, "请输入新密码");
                ShowInputCode();
                OLED_Clear();
                SystemUpdateCode();
                
                time_count = 0;
                while(1)
                {
                    SystemRequirement = NoRequirement;
                    CodeCompareState = NoNeedToCompare;
                    if(time_count >= 300)
                    {
                        TIM_Cmd(TIM2, DISABLE); // 关闭定时器2
                        time_count = 0;
                        OLED_Clear();
                        break;
                    }
                }
            }
            else if(CodeCompareState == CodeWrong)
            {
                OLED_ShowCH(0, 0, " 修  改  密  码  ");
                OLED_ShowCH(0, 2, " 密码错误");
                OLED_ShowCH(0, 4, " 请重试");
                time_count = 0;
                while(1)
                {
                    SystemRequirement = NoRequirement;
                    CodeCompareState = NoNeedToCompare;
                    if(time_count >= 300)
                    {
                        TIM_Cmd(TIM2, DISABLE); // 关闭定时器2
                        time_count = 0;
                        OLED_Clear();
                        break;
                    }
                }
            }
        }
        else if(SystemRequirement == AddFingerprint)
        {
            Add_FR();                     // 添加指纹
            SystemRequirement = NoRequirement;
        }
        else if(SystemRequirement == DecFingerprint)
        {
            Del_FR();                     // 删除指纹
            SystemRequirement = NoRequirement;
        }
        else if(SystemRequirement == UnlockWithCode)
        {
            OLED_Clear();
            OLED_ShowCH(0, 0, " 电 子 密 码 锁");
            OLED_ShowCH(0, 2, " 请 输 入 密 码");    
            ShowInputCode();
            CompareCodeAndGetResult();
            if(CodeCompareState == CodeRight)
            {
                BEEPDD();
                OLED_ShowCH(0, 0, " 电 子 密 码 锁");
                OLED_ShowCH(0, 2, " 密码正确");
                OLED_ShowCH(0, 4, " 门已开,请进");
                time_count = 0;
                JDQ = 0;
                while(1)
                {
                    SystemRequirement = NoRequirement;
                    CodeCompareState = NoNeedToCompare;
                    if(time_count >= 300)
                    {
                        TIM_Cmd(TIM2, DISABLE); // 关闭定时器2
                        time_count = 0;
                        OLED_Clear();
                        break;
                    }
                }
            }
            else if(CodeCompareState == CodeWrong)
            {
                OLED_ShowCH(0, 0, " 电 子 密 码 锁");
                OLED_ShowCH(0, 2, " 密码错误");
                OLED_ShowCH(0, 4, " 请重试");
                time_count = 0;
                while(1)
                {
                    SystemRequirement = NoRequirement;
                    CodeCompareState = NoNeedToCompare;
                    if(time_count >= 300)
                    {
                        TIM_Cmd(TIM2, DISABLE); // 关闭定时器2
                        time_count = 0;
                        OLED_Clear();
                        break;
                    }
                }
            }
        }
    }
}

六、资料分享

点击即可查看当前资料分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值