“我们不做一锤子买卖,只做技术成长的长期伙伴!”
目录
一、视频展示
基于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;
}
}
}
}
}
}
六、资料分享
点击即可查看当前资料分享。