【STM32项目开源】STM32单片机物联网门禁控制系统
目录
一、设计背景和意义
1.1设计背景:
1.2设计意义:
二、实物展示
三、硬件功能介绍
2.1 硬件清单:
2.2 功能介绍:
四、软件设计流程图
五、硬件PCB展示
六、软件主函序展示
七、单片机实物资料
资料获取 查看主页介绍:兆龙电子单片机设计
一、设计背景和意义
1.1设计背景:
在商业办公园区、住宅小区、工业园区及智慧楼宇的出入管理场景中,权限精准管控、安全预警与高效运维是核心需求。传统门禁系统存在明显局限:一方面,高端智能门禁设备(如品牌定制化安防门禁平台、多模态生物识别门禁系统)功能虽全但成本高昂,安装调试复杂,依赖专业技术人员操作与特定品牌售后支持,难以普及到中小型企业、老旧小区及基层办公场景,且设备兼容性差,更换或升级成本高,无法灵活满足不同人群(如员工、访客、运维人员)的权限管理需求;另一方面,普通简易门禁装置(如机械锁、单一 IC 卡门禁、密码锁)虽操作简单,但功能单一,仅能通过人工登记或固定凭证验证通行,缺乏身份精准识别、异常行为监测、远程授权及实时报警等功能,无法满足现代化安防场景下对出入安全、精准管理的需求。
现有关禁控制方案还存在功能割裂与集成度低的问题:部分高端门禁设备虽具备多模式认证与安全监测功能,但依赖复杂的软硬件架构与专业维护,后期使用成本高,难以覆盖预算有限的中小型场所或基层管理场景;而低成本门禁装置又在功能完整性与智能化上存在欠缺,无法实现出入数据与管理平台、移动端 APP 的联动,导致身份冒用、非法闯入、权限管理混乱等安全风险,无法为出入记录追溯及管理人员工作效率优化提供数据支撑。基于此,本设计以 STM32 单片机为核心,融合高精度识别与监测模块(如人脸识别模块、RFID 射频传感器、门磁状态传感器、防拆检测传感器)、LCD 显示模块、数据存储模块及电磁锁控制与报警模块,构建低成本、高集成度的物联网门禁控制系统,以解决传统门禁设备功能单一、智能化程度低、安全风险高及管理效率低的问题。
1.2设计意义:
本设计通过整合 STM32 单片机的高效数据处理能力与多模块协同工作机制,在出入安全管理领域具有多重实用价值,具体体现在以下三方面:
从使用体验与管理效率角度,该系统突破了传统门禁设备的局限:一是实现了多方式认证与多功能联动(如支持人脸、IC 卡、密码、远程授权认证,联动电磁锁控制模块、异常报警模块),无需管理人员现场值守或人工登记,减少人工操作繁琐性与失误率;二是配备 OLED 实时显示模块,直观呈现当前认证状态、出入时间、权限等级及运行模式,同时支持数据自动存储(可通过蓝牙或 WiFi 传输至管理平台 / 移动端 APP),方便管理人员长期追溯出入记录,为安防方案优化及日常管理流程规范提供完整数据支撑;三是新增异常预警与自动调控功能,当监测到某项参数超出安全范围(如非法闯入、设备被拆、门未关严),系统自动触发声光报警(同时向管理终端发送预警信息),并联动电磁锁锁闭、启动视频抓拍或切断非法操作通路,无需人工干预即可及时处理异常,大幅提升了门禁管理的便捷性与安全性。
从技术实践与成本控制角度,本设计以 STM32 单片机为核心,充分利用其低功耗、高性价比的优势,搭配低成本的高精度识别与监测模块及通用外围模块,在保证识别精度(人脸识别准确率可控制在 99.5% 以上,权限验证响应时间可控制在 0.5 秒以内)的前提下,有效降低了系统整体成本,相比同功能的高端智能门禁设备成本降低 40%-60%,更易普及到中小型企业、老旧小区、社区服务中心及基层办公等场景。同时,系统支持模块化扩展(如后续可新增语音交互模块、访客预约授权功能、电梯联动控制功能),为后续功能升级预留了空间,具备良好的灵活性与可扩展性。
从应用场景与行业价值角度,该系统可广泛适配多类出入管理场景:在商业办公园区中,可作为人员出入的智能管理终端,实时管控权限、监测安全状态,减轻管理人员值守压力;在高校电子信息、自动化相关专业教学中,可作为单片机与物联网设备结合的实践案例,帮助学生理解嵌入式系统在安防场景中的应用原理;在老旧小区或中小型商铺场景中,可为用户提供低成本的安全出入方案,减少安全事故风险与管理人员工作负担。此外,本设计探索了 STM32 单片机在低成本物联网门禁设备领域的应用方案,推动传统门禁装置从 “人工登记、固定认证” 向 “多方式识别、智能控制、自动预警” 升级,为低成本智能化门禁设备的开发提供了可参考的集成思路,具有较好的实践应用与行业推广价值。c
二、实物展示
下方为实物演示视频连接
点击下方链接跳转演示视频
https://www.bilibili.com/video/BV1XcayzGELQ/?spm_id_from=333.1387.upload.video_card.click&vd_source=2a672ca4e8794dca68cbe6d047b42ca5
下方为实物展示图片
三、硬件功能介绍
2.1 硬件清单:
- STM32F103C8T6
- OLED液晶显示
- 温湿度传感器
- MQ-2烟雾传感器
- 矩阵键盘
- 声光报警电路
- DS1302时钟模块
- 舵机
- RFID门禁模块
- 指纹模块
2.2 功能介绍:
(1)人机交互:在OLED显示时间信息,环境温湿度,烟雾浓度值,这两个传感器作用于发现室内环境异常自动打开门锁
(2)解锁功能:密码介绍,指纹介绍,IC卡解锁,APP解锁四种解锁方式
(3)具备物联网功能:连接WiFi实现远程控制查看实现远程解锁
(4)阈值报警:设定对应的报警参数,环境参数超出设定判定为室内异常,自动开启门锁
(5)密码管理:可实现对指纹密码IC卡的信息录入
四、软件设计流程图

五、硬件PCB展示


六、软件主函序展示
//头文件
#include "main.h"//所有头文件都放在里面方便调用管理//函数声明
void Key_Init(void);//按键函数声明
void display(void);
void DJ(unsigned int p_a );
u8 b_1s,eer_f,smart_config,openflag;
u16 sys_time,sys_time2;//系统计数
u8 mod=0;//显示模式
short menu1,set_f; //一级目录编号 设置数据位标记
u8 run_b;//运行标志,短信发送标志u16 open_time;//开门时间
u16 input_f;//输入计数
u16 pass[4];
u32 begin_code[EEPROM_volume] = {66,30,90,1000,10, //初始化数据0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
u32 set_code[EEPROM_volume];//设置参数
char str[32];//显示缓存
u16 station;
u16 key_num;//按键值,
u16 smoke; ////////////////////////关于rc522的使用寄存器定义 ////////////////////////////
u16 User_ID,integral;//用户编号,用户当前积分
u8 CT[2]; //卡类型
u8 SN[4]; //卡号
u32 RFID,RFID_Past;
u8 status;
u8 t;void DJ(unsigned int p_a ){ //舵机函数(需配合0.1ms延迟函数)dj_out = 1;
} void open(void)
{DJ(24);DJ(24);DJ(24);open_time = set_code[4];
}////////////////////////////////查卡////////////////////////////
//查内部有没有这个数据
u16 check_dat(u32 C_ID)
{u16 i;for(i=0;i<10;i++){if(C_ID==set_code[i+20]){break; }}return i;
}//查内部有没有空余
u16 check_ID(void)
{u16 i;for(i=0;i<10;i++){if(0==set_code[20+i]){break; }}return i;
}//////////////////////////////////////////查密码/////////////////////////查内部有没有这个数据
u16 PASS_dat(u32 C_ID)
{u16 i;for(i=0;i<10;i++){if(C_ID==set_code[i+10]){break; }}return i;
}//查内部有没有空余
u16 PASS_ID(void)
{u16 i;for(i=0;i<10;i++){if(0==set_code[10+i]){break; }}return i;
}
///////////////////////////////////////////////////////////////////////////////////显示函数/////////////////////////
void display(void)
{char i;switch(mod){case 0://待机界面OLED_ShowCC(0,0,"==智能门禁系统==");sprintf(str," %02d-%02d %02d:%02d:%02d ",mon,day,hour,min,sec);//显示当前时间OLED_ShowCC(0,2,(unsigned char *)str);sprintf(str,"RH:%02d%% 温度:%02d℃",DHT11_RH,DHT11_temp);//显示当前时间OLED_ShowCC(0,4,(unsigned char *)str); sprintf(str,"烟雾浓度:%03dppm ",smoke);//显示当前时间OLED_ShowCC(0,6,(unsigned char *)str); break;case 1://密码输入界面OLED_ShowCC(0,0,"===请输入密码===");OLED_ShowCC(0,2,"================");sprintf(str," %d %d %d %d ",pass[0],pass[1],pass[2],pass[3]);//显示当前时间if(input_f==0){ str[3] = str[6] = str[9] = str[12] = '_';}else if(input_f==1){ str[6] = str[9] = str[12] = '_';}else if(input_f==2){ str[3] = '*';str[9] = str[12] = '_';}else if(input_f==3){ str[3] = str[6] = '*';str[12] = '_';}OLED_ShowCC_S(0,4,(unsigned char *)str,4+(input_f-1)*3,1); OLED_ShowCC(0,6,"================");break;//管理员设置界面case 2:OLED_ShowCC(0,6,"4. 用户密码管理 ");//显示标题OLED_ShowCC(0,0,"1. 系统参数设置 ");//显示标题OLED_ShowCC(0,2,"2. 用户指纹管理 ");//显示标题OLED_ShowCC(0,4,"3. 用户IC卡管理 ");//显示标题 break;//系统参数设置case 3: sprintf(str,"温度阈值:%02d℃ ",set_code[1]);if(set_f==1) i = 4; else i = 0;str[16] = 0;OLED_ShowCC_S(0,0,(unsigned char *)str,10,i);sprintf(str,"湿度阈值:%02d%% ",set_code[2]);if(set_f==2) i = 3; else i = 0;str[16] = 0;OLED_ShowCC_S(0,2,(unsigned char *)str,10,i);sprintf(str,"烟雾阈值:%03dppm ",set_code[3]);if(set_f==3) i = 6; else i = 0;str[16] = 0;OLED_ShowCC_S(0,4,(unsigned char *)str,10,i);sprintf(str,"开门时间:%03d秒 ",set_code[4]);if(set_f==4) i = 5; else i = 0;str[16] = 0;OLED_ShowCC_S(0,6,(unsigned char *)str,10,i);break;//管理员设置界面case 4:OLED_ShowCC(0,0,"==用户指纹管理==");//显示标题OLED_ShowCC(0,2,"1. 增加指纹 ");//显示标题OLED_ShowCC(0,4,"2. 删除指纹库 ");//显示标题OLED_ShowCC(0,6,"3. 退出 ");//显示标题 break; //用户管理设置界面case 5:OLED_ShowCC(0,0,"==用户IC卡管理==");//显示标题OLED_ShowCC(0,2,"1. 增加IC卡 ");//显示标题OLED_ShowCC(0,4,"2. 删除IC卡库 ");//显示标题OLED_ShowCC(0,6,"3. 退出 ");//显示标题 break;case 6:OLED_ShowCC(0,0,"==用户密码管理==");//显示标题OLED_ShowCC(0,2,"1. 增加密码 ");//显示标题OLED_ShowCC(0,4,"2. 删除密码库 ");//显示标题OLED_ShowCC(0,6,"3. 退出 ");//显示标题 break;case 7://系统时间设置界面OLED_ShowCC(0,0,"==系统时间设置==");sprintf(str," 20%02d-%02d-%02d ",year,mon,day);//显示设置年月日if(set_f==1) i=4; else {if((set_f>=2)&(set_f<=3)) i=2; else i = 0;}OLED_ShowStr_S(0,2,(unsigned char *)str,8-i+(set_f-1)*3,i,2);//显示时分秒sprintf(str," %02d:%02d:%02d ",hour,min,sec);if((set_f>=4)&(set_f<=6)) i=2; else i = 0;OLED_ShowStr_S(0,4,(unsigned char *)str,5+(set_f-4)*3,i,2);OLED_ShowStr(0,6,"OK + - Return",2); break;case 11:OLED_ShowCC(0,0,"==请输入新密码==");OLED_ShowCC(0,2,"================");sprintf(str," %d %d %d %d ",pass[0],pass[1],pass[2],pass[3]);//显示当前时间if(input_f==0){ str[3] = str[6] = str[9] = str[12] = '_';}else if(input_f==1){ str[6] = str[9] = str[12] = '_';}else if(input_f==2){ str[12]= str[9] = '_';}else if(input_f==3){ str[12] = '_';}if(input_f==0) i= 4;else i= 4+(input_f-1)*3;OLED_ShowCC_S(0,4,(unsigned char *)str,i,1); OLED_ShowCC(0,6,"================");break;}if(openflag==1){openflag = 0;OLED_CLS(); OLED_ShowCC(0,2,"==远程解锁成功==");OLED_ShowCC(0,4,"====欢迎回家====");DelayMs(3000);}}void run(void)//逻辑程序
{if((DHT11_RH>set_code[2])||(DHT11_temp>set_code[1])||(smoke>set_code[3]))//判断阈值是不是超标{eer_f = 4;//蜂鸣器叫2声}if(smoke>set_code[3])//烟雾超过报警{DJ(24);DJ(24);//开门DJ(24);open_time = 60;//60秒内没有重复触发就吧门关上}
}//=============================================================================
//文件名称:main
//功能概要:主函数
//参数说明:无
//函数返回:int
//=============================================================================
// RCC_ClocksTypeDef get_rcc_clock;//定义一个结构体检查系统时钟int main(void)
{ int i;DelayInit();//系统延时函数初始化DelayMs(1000);USART3_Init(9600);//串口以初始化 波特率设置为9600as608_init();Key_Init();//按键引脚初始化ADC1_DMA_Config();TIM2_Int_Init(10000,3600);//输出话定时器 这边用到定时器2作为0.5秒钟中断发生源TIM_Cmd(TIM2, ENABLE);//开启定时器2 DS1302_init(0x23,0x02,0x18,0x14,0x30,0x30);//时钟模块初始化OLED_Init();//OLED屏幕初始化OLED_CLS();//清屏DHT11_Init();mod = 0;//开机显示开机界面InitRc522();//初始化RC522DJ(14);//初始状态DJ(14);//初始状态DJ(14);//初始状态Readflash(set_code,0,EEPROM_volume); //读取内部保存数据DelayMs(10);if(set_code[EEPROM_volume-1] != 66)//对比内部数据是不是以及被重新覆盖 是的话载入初始化数据{OLED_ShowStr(0,0,"===NO FLIASH===",2);begin_code[EEPROM_volume-1] = 66;Writeflash(0,begin_code,0,EEPROM_volume);//写入初始化数据DelayMs(500);Readflash(set_code,0,EEPROM_volume);//读取写写入后的数据sprintf(str,"Init System [%2d]",set_code[EEPROM_volume-1]);//显示验证数据OLED_ShowStr(0,4,(unsigned char *)str,2);DelayMs(100);OLED_CLS();//清屏}KEY34_O_1 = 0; //全开KEY34_O_2 = 0;KEY34_O_3 = 0;KEY34_O_4 = 0;smart_config = 1;OLED_ShowStr(0,0,"===Device Starting===",1);OLED_ShowStr(0,1,"Wait for link Interne",1);//等待网络连接OLED_ShowStr(0,2,"=====================",1); OLED_ShowStr(0,3,"KE2 Skip networking",1);//跳过配网OLED_ShowStr(0,4,"KE3 WIFI_SOFTAP_MODE",1);//热点配网模式OLED_ShowStr(0,5,"KE4 WIFI_AIRLINK_MODE",1);//一键配网模式 while(smart_config)//配网标志{if(KEY2 == 0) smart_config = 0;if(KEY3 == 0) {OLED_CLS();//清屏OLED_ShowStr(0,0,"===Device Starting===",1);OLED_ShowStr(0,1,"==WIFI smart_config==",1);OLED_ShowStr(0,2,"WIFI_SOFTAP_MODE",1);OLED_ShowStr(0,3,"SSID:XPG-GAgne- ",1);//热点名称OLED_ShowStr(0,4,"password:123456789",1);//连接的热点WiFi密码OLED_ShowStr(0,5,"Operation on app",1);}if(KEY4 == 0) {OLED_CLS();//清屏OLED_ShowStr(0,0,"===Device Starting===",1);OLED_ShowStr(0,1,"==WIFI smart_config==",1);OLED_ShowStr(0,2,"WIFI_AIRLINK_MODE",1);OLED_ShowStr(0,3,"Distribution network",1);OLED_ShowStr(0,4," by broadcasting",1);OLED_ShowStr(0,5,"Operation on app",1);}OLED_ShowStr(i*8,6,">",1);i++; if(i>=15){OLED_ShowStr(0,6," ",1);i = 0;}DelayMs(500);}OLED_CLS();//清屏 while (1){ if(mod == 0)//待机模式下{DS1302_Readtime(); //获取当前日期/时间DHT11_Read_Data();smoke = ADCConvertedValue[0]/10;press_FR();}display();//显示程序if(mod!=3)run();}
}//=============================================================================
//文件名称:Key_Init
//功能概要:GPIO初始化
//参数说明:无
//函数返回:无
//=============================================================================
void Key_Init(void) //按键引脚定义
{
//将按键接口设置为上拉电阻输入因为我们使用低电平信号触发GPIO_InitTypeDef gpio_initstruct;// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //按键引脚定义RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA , ENABLE);GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); gpio_initstruct.GPIO_Mode = GPIO_Mode_Out_PP; gpio_initstruct.GPIO_Pin = GPIO_Pin_6; gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &gpio_initstruct); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB , ENABLE);GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); gpio_initstruct.GPIO_Mode = GPIO_Mode_Out_PP; gpio_initstruct.GPIO_Pin = GPIO_Pin_12; gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio_initstruct); beep = 1;
}
七、单片机实物资料

