摘 要
随着科学技术的迭代与发展,智能家居逐渐走入人们的视野。智能门锁是每个家庭守护生命财产安全的第一卫
士。与传统门锁相比,出门需要携带钥匙时会出现诸多不便捷,智能门锁可以完美解决这个问题。人体本身就是钥
匙,通过指纹对比结合计算机信息等多种技术进行门锁开启,输入正确的密码,通过手机解锁等多种方式结合。为
用户在购物结束不方便使用钥匙,晨跑没有口袋钥匙无处收纳,晚归机械解锁噪声大等多场景下提供了完美的解决
方案。同时,在有访客的情况下,可以使用远程手机解锁,并可以实时监控访客情况,为孩子不小心把自己反锁在
室内,小朋友放学提前回家,老人外出未归之类的问题提供支持。智能无疑是给家庭温馨提供了良好的保障,很好
地建立起了出入家门信息沟通的安全纽带。目前的智能门锁由一块机械插芯电子主板进行控制,指纹采集模块,蓝
牙模块,无线射频模块,人脸采集模块,传统锁芯等组成。这些模块由智能芯片控制,赋予了门锁智能性。当有不
法分子进行偷窃行为时,智能门锁是他需要面对的第一道防线也是最后一道。
该系统将以STM32单片机为控制核心,其包括了指纹识别模块、外围蜂鸣器、4x4的矩阵按键、射频模块、蓝牙
模块和 oled显示屏等进行设计。设计了三种解锁方式,第一种是在我们忘记了密码的情况下,用提前设置的密码进
行解锁。第二种是 使用设定好的IC卡,我们可以直接用 IC卡刷卡来解锁,同时我们可以将 IC卡的信息存入单片
机。本设计的门禁系统在刷卡的时候,会响起一声铃声,如果有权限,门锁就会被打开,指示灯会亮起来,过后门
锁会自动关闭,指示灯也会随之消失。在程序中加入了射频识别卡的权限判定,在碰到已经录入的卡时,会出现卡
号,开门,接着延迟关机,违法卡不能显示卡号,无法开门。本智能门锁系统设计较为简单,同时性能优良,运行
稳定,是一种在实际生活中比较实用的门禁系统,具有市场推广价值。
关键词:智能芯片 多功能解锁 指纹 射频
第1章 绪 论
伴随着人们生活水平的不断提高和随之进步的科学技术,在满足日常生活需求的同时人们逐渐加大了对生命财
产安全的保护投入。智能门锁市场开始兴起。传统锁单一的解锁方式和机械锁芯容易破解等缺点尤为明显,入室盗
窃等案件仍然屡见不鲜。
智能保安系统是一种新兴的现代保安管理技术,它将自动辨识技术与现代保安技术有机地融合在一起。在经济
发展的今天,大楼的主要管理区,出入口,贵重物品库房,设备控制中心,电梯口等关键部位的出入口,都要进行
相应的安保工作,因此必须研制相应的智能化监控设备,以确认进出人员的身份,控制出入口。这在目前来说是主
流趋势
而传统的门锁已钥匙解锁为主,人们出门都需要佩戴多把钥匙以此应对多场景,除了钥匙本身重量带来的不便
携性之外,忘记带钥匙和钥匙丢失也会带来极大的安全隐患。智能密码锁的出现解决了这些问题,因其所具有的简
约外观,低功耗,价格低,容易操作等优势迅速受到广大用户青睐。自上世纪三十年代以来,我国对门禁系统的研
究一直处于起步阶段,并已在某些特定的地方得到广泛的应用。不过,那时候的锁具大多都是与机械锁具配套使用
的,而且体积大、造价高、可靠性差等缺陷,短时间内很难推广开来。20世纪80年代以后,随着信息技术、集成电
路和半导体技术的飞速发展,我国的电子门禁系统的设计技术也得到了飞速的发展。目前,在欧美发达国家,门禁
系统的技术已经相当成熟,品种也比较齐全,在安全场所中已经得到了广泛的运用,但在这一方面,我们却是稍显
落后。国外智能门锁技术已经基本成熟,市场规模在不断地扩大,人脸识别,虹膜解锁等新技术相继诞生。在1971年,国外已经结束了智能门锁的发展阶段,转而进入发展期,而目前,国外智能门锁行业因为5G技术而进入了发展
成熟期。根据STATISTA公布的数据显示,2019年国外智能门锁市场规模相较于2016年同比增长了24%。越来越多的家
庭单间住房,和越来越多的消费者对智能家庭的自动化和安全服务感兴趣,使得美国成为迄今最大的智能门锁市
场。在西欧,由于温度的控制更加重要,而智能锁往往不会被整合进智能家庭服务中。在韩国, SK、韩国电信或
者 LGU-Plus的多个家庭设备中,一般都有一个共用的入口,每个商业级别的电子锁系统都是这样。
在技术上,中国有不少公司,都在模仿外国先进的门禁设备,他们的主要方法有两个,一是从国外采购指纹模
块、读写器、门控器等门禁设备,然后在软件和软件上进行二次开发。这个控制装置的功能非常好,可以在很多需
要高度保密的地方使用,不过它的造价非常昂贵。第二个办法是,购买核心晶片以外的所有零件,全部采用进口高
品质的进口。该方法更具弹性,能够按用户需要,在任何时候都可以添加相应的权限,并且成本相对低廉。在体系
的体系上,目前我国大部分的门控设备都是采用了以控制器为中心的,而大部分的门控机都是国外公司开发的。因
此设计一款造价便宜,功耗低,运行稳定的智能门锁是很有必要的
第2章 智能门锁项目背景分析
(1)智能家居历史市场分析
智能家居自2016年作为新兴的高科技家居类别,逐渐被主流消费群体所追捧,智能家居将人们的生活通过科学
技术联系起来,使人们的生活更加科技,有趣。就像一项新技术诞生一样,它定义了一个全新的生活方式。与传统
相比,智能家居不仅仅具有传统设备所具有的基础的功能,在此基础上,通过通信技术,互联网设备,嵌入式自动
化和便捷的手机端APP等对这些智能设备进行统一远程控制,实现了高效,便捷,舒适,极具安全性的室内居住环
境,也实现了不用动手就可以进行信息交互的功能。
智能家居的起源可以追述到1984年美国的一家科创公司首次将家居设施智能化、信息化、一体化的概念运用于
建筑设备,这在当时是创新的极具颠覆性的想法,也很快在全球智能家居市场掀起了一波浪潮。自此,逐渐有厂商
将多个家居通过嵌入式智能设备进行一体化。提出了一体化的智能家居的概念,由此总线控制逐步盛行 。随着科技
的不断发展,欧洲的部分发达国家在技术上已经赶超美国,开始出现无线的远程控制以及开始追求在功能完善的前
提下,进一步缩小体积,追求安全性,精确性,和低功耗环保型等。
从2001年到2003年,这是一个快速发展时期,目前国内的智能门锁累计企业数量不足30家,行业总规模不足亿
元,企业规模普遍较小,且大部分企业从产业链的上游电子部分开始,甚至个别企业从产业链的上游电子部分开
始,甚至个别企业的模组也是自主生产。2004-2008是我国智能化门禁发展的一个时期,随着公司数目的增长,行业
的组织结构逐渐成型,公司的规模逐渐扩大,逐渐产生了一些生产产能落后的企业。2008-2014是行业技术和产品积
累阶段,公司的规模不断扩大,产值超过10亿元,成为了行业的领军人物,有些公司甚至开始涉足大型的项目。比
如奥运会和世博会,但是,总体的市场规模还是很小的。
自2011年起,市场出现了高速的爬坡,智能家居产业出现了一个新的转折点,从徘徊期步入了增长期。近五年
来,在智能家庭领域,创新技术得到了快速发展,技术规范与产业规范也在不断融合。
从2015年开始,智能门锁行业就进入了高速发展期,行业规模、企业规模、明星企业数量都在快速增长,行业
总产值更是达到了千亿元,尤其是在2017年,智能门锁被越来越多的消费者所接受。
在这方面,家用自动化的发展尤其显著,传统的家用自动化系统都是以总分式的方式布置,由一台具有一定运
算能力的小型中央处理器为主导,其他的由它来完成家用自动化。公司的主要产品有:智能灯光、智能安全、智能
家居等。其中,智能门锁的使用比例接近30%。到现在为止,全国有1300多个生产厂家,2800多个品牌。在业内,排
名在前二十的企业,占据了六成的市场份额,技术、生产等方面,都有相当的积累,而别的公司,平均一个品牌的
生产能力,也不过万台左右,左右是贴牌,大多数都是组装型。
(2)当前智能门锁项目需求分析
目前,市场上的安防类智能家居主要包括了多种类的智能门锁,智能远程监控设备,红外防盗报警器等。就我
国智能设备供应市场的总体占比来看,入户门防盗安全系统和家庭远程监控安防设备是占据市场份额最大的设备类
别。从家庭用品的使用量来看,在市场上,以19.34%的频率,排在了最畅销的商品之列,只比智能电器少了2.66个
百分点。说明了智能门禁系统在智能化家庭中具有更高的应用价值和更大的用户群体。
作为一款刚刚起步的智能型家庭设备,2020年,已有两百万套的智能门锁和210.1000套的智能门禁被安装,配
备率高达64.6%;智能化安全保障体系的设备数量已达220,000个,配备比例为68.2%,其中,智能安全防盗设备的使
用量显著大于一般家庭。
7
随着网络、远程通信、大数据、数据库等技术的迅速发展,为安全监控技术的发展奠定了坚实的技术基础。它
不但在家用市场上表现出了勃勃生机的态势,而且随着新科技的发展,它能够提供更多的功能,比如指纹解锁、面
部识别、手机 APP解锁、 NFC等,再到内置了能够增强计算能力和解锁速度和精度的微型摄像头,还配备了一个小
型摄像头,可以对可疑人员进行拍照,并将其上传到户主的手机 APP中,让住户通过 APP进行远程监视,或者是用
语音进行远程通讯,既能有效地监视和威慑,又能进一步增强智能电器的安全性、远程连接、智能化、准确度。与
传统的门锁相比,智能门锁在安全、方便等方面有了很大的提高。
十年来,中国公安部门处理的治安案件呈逐年下降趋势,但入室盗窃、抢劫等违法犯罪案件依然时有发生,不
安全因素依然存在,尤其是近年来针对单身女子的犯罪案件频频发生,在整体消费能力提高的十年里,人们更愿意
把更多的精力放在个人和财产的保护上。这是为了保护自己,也是为了保护自己的亲人。这也是智能家居安全的装
置。
每年的需求量都在增长。目前,相较于欧美地区和环太平洋地区,智能门锁在我国的普及率仍然较低,中国的
渗透率不及日韩的10%,由此可见,中国智能门锁市场需求量和市场空间巨大,还有很长的路要走。
(3)智能门锁国内外研究现状
国外智能门锁技术起步早,技术成熟,发展稳定,渗透率很高。而国内的智能门锁在90年代才起步,早期主要
是磁卡感应型的电子锁,大量被酒店引进安装,方便酒店进行管理。21世纪开始,带有指纹的智能指纹锁开始进入
内地市场,打破了单一刷卡解锁的市场,逐渐向家庭用户转换迈进;2011年后,随着 两个市场的发展,越来越多的
安全手段如人脸识别、虹膜识别、手指静脉识别、 手机终端APP开锁等都得到了广泛的应用。经过几年的发展,智
能锁企业的数目逐步增多,传统的锁企、家电企业、智能锁企业纷纷进入市场,使得智能锁产业的发展速度加快。
当前市面上有多种类型的智能门锁,开发到现在已逐渐发展为功能性的类别。
1.智能锁:与普通的机械式锁不同,它在用户识别、安全性和管理性方面具有较高的智能化程度。智能化门锁
是一种用于控制门锁的控制元件。与以前的“打开后扫描”模式完全不同,它的扫描很容易,只需要将手指从顶部
向下一扫,而不需要将手指放入扫描仪中,这样就可以将指纹的残留量降到最低,从而保证了指纹的完整性。
2.指纹锁:是一种以人的指尖为特征的智能锁。指纹识别与控制、机械式连杆是目前指纹锁的重要部件。由于生物
特征的唯-一性和不可重复性,目前已是最可靠的方法。根据国家相关法规,除了手印之外,应当配有应急机械锁。
3.密码锁:一种由一系列的号码或标记组成的钥匙。一般来说,代码仅仅是一个组合,并非一个真实的组合。有些
密码锁只使用一个转台来转动多个碟片或凸轮,或者是直接带动锁体的内部。
4.感应式门锁:是一种新型的安全装置,它采用红外线感应器。通常可分为射频、感应式、高质量的门锁。欧美等
发达国家,感应锁发展到一定阶段,已成为人们生活质量和生活质量的重要标志。
5.遥控锁:遥控锁是当前最好的防盗设备。高科技盗贼及专业开锁公司职员对现今广泛应用的机械锁早已经破解。
如今,远程控制已经被广泛用于家居、宾馆、出租屋、仓库等场所,极大的便利了人们的日常生活。
第3章 设计思路及主要工作
(1)设计意义
1)防盗窃
目前主流的智能门锁由一块机械插芯电子主板进行控制,指纹采集模块,蓝牙模块,无线射频模块,人脸采集
模块,传统锁芯等组成。这些模块由智能芯片控制,赋予了门锁智能性。当有不法分子进行偷窃行为时,智能门锁
是他需要面对的第一道防线也是最后一道。当非授权用户解锁时,门锁会自动采集解锁人照片并实时远程共享至户
主的APP端,并伴随警报声对犯罪分子进行恐吓。当外部受到不法分子暴力破坏时,智能门锁自动将锁芯全部弹出处
于全部落锁并且无法解除,从而保障财产安全。
2)用户便携性
与传统门锁相比,出门需要携带钥匙时会出现诸多不便捷,智能门锁可以完美解决这个问题。人体本身就是钥
匙,通过指纹对比结合计算机信息等多种技术进行门锁开启,输入正确的密码,通过手机解锁等多种方式结合。为
用户在购物结束不方便使用钥匙,晨跑没有口袋钥匙无处收纳,晚归机械解锁噪声大等多场景下提供了完美的解决
方案。同时,在有访客的情况下,可以使用远程手机解锁,并可以实时监控访客情况,为孩子不小心把自己反锁在
室内,小朋友放学提前回家,老人外出未归之类的问题提供支持。智能无疑是给家庭温馨提供了良好的保障,很好
地建立起了出入家门信息沟通的安全纽带。
(2)设计目的
1)综合管理端
智能门锁其目的都是为了让人们的生活变得更加便利。对于智能锁来说,拥有着远程访问、语音控制以及场景
功能是目前的主流功能。如借助智能助手,AppleHomeKit和小米家庭等终端控制工具,用户可以设置类似场景模
式,来调暗灯光、调节室温并锁门等一系列操作。这就给智能门锁赋予了一项综合管理的功能。设计出一款具有
WiFi功能,可以通过无线局域网对室内智能家居进行总体控制。例如在手机端设置好夜晚的场景模式,灯的开关控
制,音响的控制,家庭温度控制等,除了解锁功能外,实现其作为总控制端实现用户远程对室内设备的综合管理与
监控。
2)安全性多功能进入
在安全技术防范的领域内,智能门锁逐渐替代传统机修门锁。无论是传统的机械钥匙解锁还是密码解锁,其解
锁方式都很单一。机械式密码锁密码量少,安全性差。伴随着大规模的集成电路技术的发展,特别是单片机的大量
使用,将智能芯片植入智能门锁,使其在具备基础密码解锁的功能外增加多种进入的方式以及远程监控和管理。
(3)设计目标及主要工作
目前市场上一般的电子锁由三个部件构成:输入元件、电路和机械锁体。这种方案的物理结构比较复杂,传统
的操作模式也会对使用者造成不便;而采用 MCU的智能控制系统,它的可操作性强,输入输出接口多,控制精度
高,不仅可以完成基本的解锁操作,还可以增加自动落锁、报警提示、手机端无线解锁等功能,但它的缺点在于原
理非常复杂,制作工艺和那度较高,如果出现问题维修起来也比较麻烦。目前常用的密码锁设计方法有中大规模 IC
和单片机两种。在电路控制方面,将电路划分为:编码电路,控制电路,复位电路,解码电路,防盗报警电路,门
铃电路。
本设计将用STM32F103C8T6芯片作为主要控制芯片,控制包括指纹模块AS608(串口控制),7针OLED显示屏幕
(IIC),HC-05蓝牙模块,RFID RC522射频模块等对带驱动模块的步进电机进行控制,AS608芯片做指纹识别功能,
RC522做IC卡读写功能,有源蜂鸣器做报警提示,LM2596和AMS1117芯片为系统供电,串口屏做人机交互界面;在软件方
面,使用C语言进行开发,采用模块化设计。该系统能够在开机后使用指纹解锁、输入当前密码、修改密码、登录、删
除 IC卡。在读卡机的读卡区中,读卡机会自动读出卡片的序号,由单片机根据卡片的序号来判定。如果卡片是一张
有效的卡片,则会进行打开,并将正确的信息显示在 LCD上;如果是不合法的卡片,就不能进行操作,只有在 LCD
的屏幕上显示卡号。同时,用户可以按下按钮,将登录、删除两种方式转换为登录、删除或登录。该系统具有高可
靠性、高保密性、方便、快捷等优点,能够有效、方便、安全地对关键部位的进出和存取进行控制。
第四章 硬件的选择与搭建
(1)主控芯片选择
1)主控芯片介绍
该系统的关键是采用了微处理器,实现了对各个模块的控制和处理。与数字电路相比,利用单片机的优点是:
利用 LCD技术,将 CPU、随机存储器 RAM、 ROM、多输入/中断系统、定时器/计数器等功能集合起来(也可以包含
显示驱动电路,脉冲宽度调制电路,模拟多路转换器, A/D转换器等电路)。其体积小,质量轻,应用范围广泛,
如智能仪表,实时工业控制,通讯设备,导航系统,家电等。为达到对目标的控制需求,单片机的指令系统具有很
强的支路转换能力、 I/O端口的逻辑运算和比特运算能力,特别适合于特殊的控制功能。在芯片的外围,有很多三
总线和并行、串行输入/输出插头,可以轻松地组成多种大小的电脑应用程序。该系统具有丰富的端口功能,运算速
度快,编程简单,控制精确,并采用 RAM和 ROM (ROM),通过外部液晶显示口令和操作提示,并采用矩阵键盘来输
入口令,并采用AT24C04芯片来储存密码。如下图(图一)所示为主控芯片STM32f103原理图
图一 主控芯片原理图
ST:意法半导体,是一个公司的名字。M:Microelectronics的缩写,表示微控制器,要注意微控制器和微处理器的
区别。32:32bit的意思,表示这是一个32bit的微控制器Cortex-M3采用ARMv7-M架构
STM32F103是增强 MCU 32位MCU中性能最强的,它具有良好的控制能力和通信能力,是低压/低压领域的理想选
择。本设计所选用的单片机为STM32F103C8T6,这款单片机比51单片机有更多的功能,不仅运算速度更快,而且还附
带了两个 AD,可以让我们在设计时省去了额外的 ADC。STM32具有很强的通讯和控制能力.这是51所不能相比的。由
于51单片机仅有一个串口,32 MCU有5个串口,因此对于某些需要用串口进行通讯的模块来说,并不需要像CD4052这
样的双串接口来实现,下图(图二)为单片机实物图。
(图二单片机实物图)
STM32有着很强大的通信功能和控制功能,而51单片机只有1个串口进行通信,而32单片机具有5个串口进行通
信,所以对一些要求用串口进行通信的模块而且就不需要通过CD4052等双串口模块来转换,STM32单片机因为本身可
以进行多种不同的时钟模数来进行工作,所以在功耗要求比较严格的产品中占有一席之地。
2)STM32单片机引脚介绍
如下图(图三)所示为单片机引脚介绍
FT:表示的是耐压值为5v
串口:就是串口通信功能,比如蓝牙,GSM ,GPS,PM2.5,甲醛 等
IIC:通信的一种方式,比如BMP180,SHT20,
SPI:通信的一种方式,比如RC522射频卡,语音识别LD3320
ADC:模数转换,比如烟雾,酒精
TIM:定时器
DAC:数模转换
SWD:程序下载口
如下图(图三)所示为单片机引脚介绍
(图三)单片机引脚介绍
(2)指纹模块选择
该方案所使用的AS608指纹模组包含了光学电路与指纹识别两大功能,并以 USB与 UART两种方式进行通讯。如
下图(图四)所示为指纹模块原理图,(图五)为指纹模块实物图。该模块通过对指纹的特征分析,可以从指纹的
特征中得到具有代表性的指纹。指纹的存储、比对和检索均由指纹的特性进行处理。在识别过程中,指纹的识别过
程包括两个步骤:指纹比对和检索。在进行指纹比对时,首先要对使用者的指纹进行二次提取,再与指纹存储的两
次比对,再进行比对,最终得出是否匹配的结果。
(图五)指纹模块实物图(图四)指纹模块原理图
(3)OLED显示屏选择
(图六)0.96英寸OLED显示屏原理图
本设计采用的0.96英寸OLED显示屏,控制芯片为SSD1306,其特点在于性价比高,显示效果好,可以通过字库取
模来编辑文字显示。在智能家居领域广泛应用于智能门锁上。在医疗机械,运动智能穿戴设备,工业仪器发射机等
领域产品都有广泛的应用。右图为OLED显示屏的原理图。在本设计,显示屏默认为英文显示,通过使用PCtolCD进行
取模设计,从而对显示屏的显示进行汉化。当我们接通电源以后,显示屏会显示进入初始界面,显示目前的锁定情
况为已锁定,通过指纹模块解锁时,会显示正在匹配指纹并且显示匹配结果。当检测失败则显示检测错误。当使用
矩阵按键进行密码解锁时,在输入密码的界面会显示输入的密码,但是会被屏蔽为“”显示,以此保护使用者的信
息安全。当解锁密码输入错误时,则会显示解锁失败。用户可以通过电子显示屏清晰地了解当前状态。如上图(图
六)所示为OLED显示屏原理图,
(4)4x4矩阵按键选择
4x4型键控 MCU是一种非矩阵形式的单芯片外部器件。它可以在应用中实现更多的函数,但是相对的程序比较繁琐。
4X4的键盘键被分成4套列线、4套行线路,将行线连接的 MCU I/O端口用作输出,列线连接的 I/O端口用作输入。在
普通的嵌入式系统中,使用最多的不是密码的键盘,而是对键盘进行了加密。无码的键盘有单独的和矩阵的两种类
型。在此基础上,采用了基于键值的键值进行多路传输的方法。
一般来说,键盘是分为行和列进行采集的,比如44的键盘,只要行4个键,列4个键,就能完成矩阵键盘的整体控
制。
在本设计中,最基础的解锁方式为使用矩阵按键进行密码解锁。当接入电源后,密码锁处于锁定状态。此时除
了9位数字键以为,还添加了4位功能按键,可以控制菜单按钮的上下移动,确认选项和进行一键锁定功能。即图中
所显示的LOCK,DEL,DIS,OK四个按键。当处于解锁界面是,可以通过设置六位解锁密码进行解锁。如果输入错误,共
有三次解锁机会。当我们按下对应数字按键,在显示屏上便会出现相应的数字,当密码输入正确便可进入控制界面。
(5)蓝牙模块选择
JDY-31是基于 Bluetooth3.0 SPP设计的,可以通过WINDOWS、Linux、android数据传输,2.4GHZ,调制方式为
GFSK,最大发射功率8c,最远发射距离达到了30米,支持用户通过AT指令修改设备名称、波特率等指令,方便快
捷,操作方便。如下图(图十)所示为蓝牙模块原理图。此功能可与具有Bluetooth功能的计算机和移动电话进行通
讯,并能通过Android的蓝牙进行传输。该方案采用了 Android APP,利用AT命令对蓝牙模块的频率进行调整,实现
了与MCU相同的 USB接口,从而实现了与 MCU相连的功能。通过USB接口,可以通过USB接口和 PC接口,通过USB接
口,通过蓝牙传输信息,调整波特速率,然后将波特率作为当前的无线网络设备的波特率。下图(图十一)为蓝牙
模块实物图
(图十一)蓝牙模块实物图
(图十)蓝牙模块原理图
(6)蜂鸣器模块选择
声音的频谱范围约在几十到几千赫兹,若能利用程序来控制单片机某个口线的“高”电平或低电平,则在该口
线上就能产生一定频率的矩形波,接上喇叭就能发出一定频率的声音. 蜂鸣器是一种一体化结构的电子讯响器,采
用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电
子产品中作发声器件。
此设计是stm32单片机,单片机上电后引脚为高组态,所以我们不可以使用8550,因为8550 是低电平导通,
8050 是高电平导通,当我们想让蜂鸣器进行报警的时候,我们给三极管一个高电平 ,就实现了蜂鸣器报警。三极
管本身具有的作用是放大电流(放大200倍)加1k电阻是为了进行限流。参数为:电压5V,灵敏度:min 75 dB这个蜂
鸣器的工作电压可以在5V电源下工作,且P3口不需要上拉电阻。IO口输出后接一个1K电阻,到NPN三极管(S8050)
的基极,PNP三极管的发射极接一个5V电源。三极管的集电极接蜂鸣器的正极,蜂鸣器负 极接地,R=(5-0.6-3)
/2mA=0.7K欧姆,则取1K欧姆。下左图(图十二)为蜂鸣器模块原理图。
在本设计中,蜂鸣器模块作为密码输入失败后提示输入失败以及解锁成功时作为通知使用。当我们通过三种解
锁方式进行解锁时,当解锁信息匹配如按键输入密码错误时,蜂鸣器会出警报声来提示用户解锁失败。
(7)带驱动模块的步进电机选择
步进电动机是一种开环驱动马达,它把脉冲信号转换成直线或角度的位移,是当今数控编程中最常用的驱动部
件。如下图(图十四)所示为步进电机实物图。步进电动机的平均精确度在百分之三到百分之五之间。步进马达的
扭矩随着速度的增加而降低,在低速度时能保持稳定运行。步进电动机要加上一个驱动装置,在没有脉冲的情况下,步进马达是不动的,然而给他加上一个合适的脉冲,它就会旋转,也就是所谓的步角。旋转速率与脉搏的频率
是直接相关的。步进马达的特点是快速起动和快速停止。通过调整脉冲序列,可(图十五)步进电机原理图(图十
四)步进电机实物图以很容易地调整旋转的角度。步进电机不能
通过工频 AC或 DC供电,需采用特殊的步进电机驱动器,该驱动器包括:脉冲产生、电力驱动、防护等。该驱
动器与步进电机是一个直接连接的,它可以被看作是一个步进电机的电源界面。上图(图十五)为步进电机原理
图。它可以快速地提高和降低电压,使得电流波形更靠近长方形。在断开过程中,电路会使线圈上的反电位降低,
从而加速电路中的电流的衰变。它的功率和效率都很高。用步进电动机的速度和脉冲信号的频率来调节电动机的速
度。本设计采用了步进电动机作为智能门锁解锁的控制器。
8)射频模块选择
MFRC522是应用于13.56MHz非接触式通信中高集成度的读写卡芯片,针对“三表”应用推出的一款低电压、低成
本、体积小的非接触式读写卡芯片,是智能仪表和便携式手持设备研发的较好选择。MFRC522利用了先进的调制和解
调概念,集成了在13.56MHZ下所有类型的被动非接触式通信方式和协议。支持14443A兼容应答器信号。数字部分处
理1S014443A帧和错误检测。此外,还支持快速CRYPTO1加密算法,用语验证MIFARE系列产品。MFRC522支持MIFARE系列更高速的非接触式通信,双向数据传输速率高达424kbit/s。作为13.56MHz高集成度读写卡系列芯片族的新成员,
MFRC522与MFRC500和MFRC530有不少相似之处,同时也具备许多特点和差异。它与主机间通信采用SPI模式,有利于
减少连线,缩小PCB板体积,总而减少成本。
1)射频模块参数介绍
下表(表一)为射频模块参数表
该模块适用于各种基于iso,iec标准并且要求低成本,小尺寸,高性能以及单电源的非接触式通信场合。例如
三表、板上单元、公共交通终端、便携式手持设备、非接触式公用电话等。
工作电流 13-26mA/直流3.3V
空闲电流 10-13mA/直流3.3V
峰值电流MAX 30mA
工作频率 13.65MHz
支持卡的类型 mifare1 S50, mifare1 S70, mifar
UltraLight, mifare Pro, mifare Desfire
工作温度 正负20摄氏度
模块接口SPI参数
数据传输速率:大10Mbit/s
(图十六)射频模块实物图
MF RC522的命令操作有发送接收数据、认证和复位芯片等,不同的操作对应了不同的4位二进制命令代码。通过
向commandreg寄存器的低4位写入命令代码来执行相应的操作。执行一个命令所需的参数和/或数据通过FIFO缓冲区
来交换。上图(图十七)为射频模块简化框图
(图十八)射频模块原理图
将射频识别技术同IC卡技术相互结合,从而产生了非接触式的射频卡。该种卡片的出现在电子信息类研究是突
破式的进步。它成功破解了不用接触和有源无源的问题。卡片本身是不带有供电装置的,他通过卡片接近感受器时
在特定的范围内电磁场所产生的电磁波进行读取信息,完成操作。上图(图十八)为射频模块原理图。
2)模块特性功能介绍
其特性有以下几种
1.高集成度的调制解调电路
2.TX管脚对天线有着驱动能力
3.支持 MIFARE® Classic 加密;
4.支持的主机接口:
5.-10Mbit/s 的SPI 接口
6.灵活的中断模式;
7.可编程定时器。
8.内部振荡器,连接27.12MHz 的晶体;
9.工作温度范围-30~+85℃;
10.5mm×5mm×0.85mm 的超小体积。
11.内置有温度传感器,当芯片温度过高时实行自动断电
3)卡片读取原理
该模块读卡原理如下图(图十九)所示
(图十九)卡片读取原理图
(9)电源供电选择
本设计采用直流5V供电,在本设计中各模块电压都在5V以内,所以选择5V电压足够满足供电需求,同时也预留
了可扩展升压模块,从而支持更高电压的元器件。其各模块原理图如图(图二十)所示。
(图二十)供电部分原理图
(10)电路设计搭建
本设计基于STM32单片机进行设计,单片机负责数据处理,矩阵按键负责进行数据输入,OLED显示屏负责将当前运行状态及信息进行显示。电源提供5v电压为单片机进行供电,步进电机的转动模拟出门锁的开与关。蜂鸣器用来
提示解锁状态失败。
最核心的单片机负责数据处理,本设计使用的STM32F103C8T6为贴片式单片机,其本身具有四十个引脚。单片机
输出3.3V电压,其内部具有降压模块,将5V电压降到3.3V进行输出。供电系统采用的是5V的电压,供电输入接口采
用的是USB-C接口,当我们接通电源,整个系统直接启动不要开关进行控制。显示器采用了0.96英寸OLED显示屏,其
优点在于亮度高,显示稳定,彩色显示。在其右边接入一个一个电阻作为限位器,从而控制其电压保证显示稳定。
数据采集部分使用了4x4矩阵按键,其优点在与可以减少单片机使用的I/O口数量,通过判断按键高低电平从而判断
被按下的按键具体位置。通过行列竖列同时为低电平时,单片机可以判断被按下的按键,从而执行该按键设定的命
令。采集数据端,有指纹模块和射频模块。当我们将引进录入的识别卡靠近接受器时,单片机判断输入信号与存储
的信号是否一致从而进行解锁操作。射频模块供电电压为3.3V,采用SPI通信方式最为简单。最后将蜂鸣器接入,当
我们密码错误时,蜂鸣器报警提示密码错误。整体电路设计PCB图如下图(图二十二)所示。
(图二十二)电路设计PCB图
第5章 软件的设计与实现
(1)软件的设计
当我们完成了硬件框架的搭建并且确定了我们所需要的所有元器件,我们需要对软件进行设计。一般的,在为
单片机设计软件是,一般从确定软件任务,画出软件流程图,选择语言,编制源程序,汇编,仿真调试等步骤进
行。如果在编写过程中发现有错误,则需要修改程序,重新回到汇编,直至成功写入ROM,最终结束。软件在本设计
中起到至关重要的作用。当我们完成了硬件的链接,软件则是将个硬件的功能统一融合,从而实现多功能同步工作
的目的。硬件结构相同的情况下,不同的软件则会为设计带来不同的丰富的功能。
2)软件设计流程图
当我们为系统接通电源后,系统将会进行初始化,OLED显示屏也会显示初始化进度,接着进入初始界面,然后
通过多功能解锁的方案实现解锁,修改密码,录入指纹,指纹比较,密码比较,时钟显示,一键锁定,NFC刷卡识
别,手机蓝牙解锁,手机APP端控制,密码错误报警等操作。下图(图二十四)为运行界面实拍图
(图二十四)运行界面实拍图
当密码输入正确以后,我们会进入用户设置界面,在这里我们可以录入新的指纹,录入新的卡片,录入新的密码。
(3)录入新密码流程图
进入设置界面,通过DOWN调整至3.修改密码,输入新密码后点击确认即可修改成功。下图(图二十五)所示为当
我们需要修改密码是具体流程的流程图。
(图二十五)密码修改流程图
第6章 调 试
首先,检查一下在示意图中使用的元器件是否正确,再对照 PCB图样进行二次,确认有没有接线错误等。电路
的接线有没有问题,看看电路与元件的插头正负是否一致。当全部检查结束以后,就可以着手焊接了。首先,把板
子放在制板机里,在制板机的过程中,我要先对电路板上的元器件进行检查,确保元器件的工作状态,再把它们焊
到板子上。为了使元器件接点完全合拢,需要进行大量的实践,避免漏焊和虚焊。绝对不能在焊接完成后进行带电
测试。需要先通过肉眼观察是否存在相邻电线短路的可能性。然后用万用表检测是否有短路,不要在焊接过程中仓
促地切断过多的插头。这样可以避免在焊接过程中产生的问题,避免浪费。在解决了所有的问题之后,就可以进行
功率测试了。在上电试验时,要与软件一起进行调试,在确认硬件连接无误的情况下对软件进行调试,直至能够稳
定运行。下图(图二十七)为实物展示图。
(1)焊接
在焊接时,也出现了许多的问题,造成焊接质量不高焊锡用量掌握不好,导致出现焊接球中心虚焊,内部焊锡
过少导致无法连接也会出现冷焊,焊接之前电烙铁预热时间不充分导致焊锡没有充分融化。节点之间存在松香导致
短路,在焊点处,连接点中间有松香夹杂,导致接触不良出现短路。焊锡过量导致相互连桥的短路
(2)电路板调试
小系统的电路不工作,首先应该确认电源电压是否正常。用电压表测量接地引脚跟电源引脚之间的电压,看是
否符合电源电压,常用的是5V左右。接下来就是检测复位引脚的电压是否正常,EA引脚的电压要正常为5V左右。
如果补焊电源后RC522无法识别还是不能工作,有可能是STM32输出3.3V引脚和RC522的3.3V没有连接好,通过使
用万用表测试一下通断情况重新连接一下,然后rc522电源指示灯已经正常亮起。通过稍微修改RC522时序已经可以
进行刷卡识别,然后测试按键是否可以正常使用。
(图二十七)设计实物展示图
(3)读卡调试
(图二十八)录入卡片解锁实拍图
基于MF RC522的读写器主要由MF RC522、微处理器、天线以及相应的外围连接电路组成(如图1所示)。读写器
要通过天线来发射能量,形成电磁场,通过电磁场来对电子标签进行识别,天线所形成的电磁场范围就是射频识别
系统的可读写区域。因此,要提高读写器的读写距离,所设计的天线必须能在尽可能大的范围内产生所需的电磁场
。当我们使用录入的卡片靠近读卡区,即可解锁。下图为解锁实拍图。
第七章 结论与展望
经过近半个月的努力,在胡教授和同学的帮助下,查阅资料等,最终才完成了本设计,通过这次毕业设计,我
认识到了动手能力的重要性,以及信息检索能力的重要性。本设计是基于STM32单片机开发一款具有多功能进入的智
能门锁。设计之初,比较茫然,只知道硬件软件结合,但是从从零开始还是一筹莫展。在硬件部分我通过查阅资料
列出元器件清单,在实现功能的条件下选择性价比高的各个模块,也考虑了电路设计的复杂性。因此,尽量减少硬
件电路,节约电路板的空间,以实现对硬件电路的最佳设计。
该软件采用 C语言,以模块化的方式进行编程,具有很好的可读性。经联合调试,证明了该系统的有效性,除
了最基本的密码输入解锁以外,还能使用用指纹解锁,能用刷卡方式进行身份识别。在本设计中一开始加入了蓝牙
模块,但是由于苹果设备的局限性已经蓝牙模块本身的限制,最终没有开发出通过手机解锁的APP,较为遗憾。如果
后期条件允许,我将继续完善其功能。
通过本设计,也让我对智能门锁有了新的认识,也让我充分连接了解锁原理和相较于传统门锁科技为我们生活所带
来的便利的重要性。智能门锁在多场合下极具运用价值。
本次设计是对我大学四年的总结,也是为我未来投入社会,投身工作的铺垫。整个过程中我所获得宝贵经验,
必将使我日后的宝贵财富。
附录三:源代码
#include “main.h”
#include <string.h>
SysTemPat sys;
#define MAXERRTIMES 5
#define usart2_baund 57600//串口2波特率,根据指纹模块波特率更改
//要写入到STM32 FLASH的字符串数组
const u8 TEXT_Buffer[]={0x17,0x23,0x6f,0x60,0,0};
#define TEXT_LENTH sizeof(TEXT_Buffer) //数组长度
#define SIZE TEXT_LENTH/4+((TEXT_LENTH%4)?1:0)
#define FLASH_SAVE_ADDR 0X0802C124 //设置FLASH 保存地址(必须为偶数,且所在扇区,要大于本代码所占用到的
扇区.
//否则,写操作的时候,可能会导致擦除整个扇区,从而引起部分程序丢失.引起死机.
SysPara AS608Para;//指纹模块AS608参数
u16 ValidN;//模块内有效指纹个数
u8** kbd_tbl;
void Display_Data(void);//显示时间
void Add_FR(void); //录指纹
void Del_FR(void); //删除指纹
int press_FR(void);//刷指纹
void ShowErrMessage(u8 ensure);//显示确认码错误信息
int password(void);//密码锁
void SetPassworld(void);//修改密码
void starting(void);//开机界面信息
u8 MFRC522_lock(void);//刷卡解锁
u8 Add_Rfid(void); //录入
void Set_Time(void);
void Massige(void);
void SysPartInit(void ); //系统参数初始化
//u8 Pwd[7]=" “; //解锁密码1
//u8 Pwd2[7]=” “; //解锁密码2
//u8 cardid[6]={0,0,0,0,0,0}; //卡号1
int Error; //密码验证信息
40
u8 DisFlag = 1;
//数字的ASCII码
uc8 numberascii[]={‘0’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’,‘A’,‘B’,‘C’,‘D’,‘E’,‘F’};
//显示缓冲区
u8 dispnumber5buf[6];
u8 dispnumber3buf[4];
u8 dispnumber2buf[3];
//MFRC522数据区
u8 mfrc552pidbuf[18];
u8 card_pydebuf[2];
u8 card_numberbuf[5];
u8 card_key0Abuf[6]={0xff,0xff,0xff,0xff,0xff,0xff};
u8 card_writebuf[16]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
u8 card_readbuf[18];
//SM05-S数据区
u8 sm05cmdbuf[15]={14,128,0,22,5,0,0,0,4,1,157,16,0,0,21};
//extern声明变量已在外部的C文件里定义,可以在主文件中使用
extern u8 sm05receivebuf[16]; //在中断C文件里定义
extern u8 sm05_OK; //在中断C文件里定义
//u8 * week[7]={“Mon”,“Tue”,“Wed”,“Thu”,“Fri”,“Sat”,“Sun”};
u8 * week[7]={“Sun”,“Mon”,“Tue”,“Wed”,“Thu”,“Fri”,“Sat”};
u8 * setup[7]={“1、录入指纹”,“2、删除指纹”,“3、修改密码”,“4、修改时间”,“5、录入卡片”,“6、查看信息”};
void DisUnLock(void )
{
OLED_Clear();
Show_Str(20,10,128,24,“解锁中…”,24,0);
OLED_Refresh_Gram();//更新显示
Walkmotor_ON();
Show_Str(20,10,128,24,“已解锁!”,24,0);
OLED_Refresh_Gram();//更新显示
delay_ms(1500);
}
void DisLock(void )
{
OLED_Clear();
Show_Str(30,20,128,16,“锁定中!”,16,0);
OLED_Refresh_Gram();//更新显示
Walkmotor_OFF();
Show_Str(30,20,128,16,“已锁定!”,16,0);
OLED_Show_Font(56,48,0);//锁
OLED_Refresh_Gram();//更新显示
delay_ms(1000);
}
int main(void)
{
u16 set=0;
u8 err=0;
41
int key_num;
int time1;
int time2; //锁屏时间
char arrow=0; //箭头位子
//SysHSI_Init();
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化为9600
printf(“串口功能正常\r\n”);
Button4_4_Init(); //初始化与按键连接的硬件接口
OLED_Init(); //显示初始化
Walkmotor_Init(); //步进电机初始化
BEEP_Init(); //蜂鸣器初始化
usart2_init(usart2_baund); //初始化指纹模块
PS_StaGPIO_Init();
OLED_Clear();
starting();//开机信息 logo
err = RTC_Init(); //RTC初始化
if(err)
{
OLED_Clear();
Show_Str(12,13,128,20,“RTC CRY ERR!”,12,0);
OLED_Refresh_Gram();//更新显示
delay_ms(3000);
}
SysPartInit(); //系统参数初始化
while(1)
{
//锁屏界面
MAIN:
OLED_Clear();
OLED_Show_Font(56,48,0);//显示锁图标
while(1)
{
time1++;Display_Data();//时间显示:每1000ms更新一次显示数据
if(DisFlag == 1)
{
DisFlag = 0;
OLED_Fill(0,24,16,63,0);
OLED_Refresh_Gram();//更新显示
}
if((time1%100)1)
{
//MFRC522解锁
time1=0;
MFRC522_Initializtion();
Error=MFRC522_lock();
42
if(Error0)
{
goto MENU;
}
else
{
OLED_Show_Font(56,48,0);//锁
}
//手机蓝牙解锁密码1
Error=usart1_cherk((char*)sys.passwd1);
if(Error0){
OLED_Clear_NOupdate();
Show_Str(12,13,128,20,“蓝牙密码1:正确”,12,0);
OLED_Refresh_Gram();//更新显示
delay_ms(800);
DisUnLock();
goto MENU;
}
else
{
// OLED_Clear_NOupdate();
// Show_Str(12,13,128,12,“蓝牙密码:错误!”,12,0);
// OLED_Refresh_Gram();//更新显示
// delay_ms(800);
// OLED_Show_Font(56,48,0);//锁
}
//手机蓝牙解锁密码2
Error=usart1_cherk((char*)sys.passwd2);
if(Error0){
sys.errCnt = 0;
OLED_Clear_NOupdate();
Show_Str(12,13,128,12,“蓝牙密码2:正确”,12,0);
OLED_Refresh_Gram();//更新显示
delay_ms(800);
DisUnLock();
goto MENU;
}
else
{
//OLED_Show_Font(56,48,0);//锁
}
}
//指纹解锁
if(PS_Sta) //检测PS_Sta状态,如果有手指按下
{
while(PS_Sta){
Error=press_FR();//刷指纹
43
if(Error0)
{
//DisUnLock();
goto MENU; //跳到解锁界面
}
else
{
OLED_Show_Font(56,48,0);//锁
}
}
}
//密码锁
key_num=Button4_4_Scan(); //按键扫描
if(key_num!=-1)
{
Error=password();//密码解锁函数
if(Error0)
{
goto MENU; //跳到解锁界面
}
else
{
OLED_Show_Font(56,48,0);//锁
}
}
delay_ms(1);
}
/主界面******/
MENU:
OLED_Clear();
MENUNOCLR:
OLED_Fill(0,0,20,48,0);
//主页菜单显示
if(arrow<3){
Show_Str(5,arrow16,128,16,“->”,16,0);//显示箭头
set=0;}
else {
Show_Str(5,(arrow-3)16,128,16,“->”,16,0);
set=3;}
Show_Str(25,0,128,16,setup[set],16,0);
Show_Str(25,16,128,16,setup[set+1],16,0);
Show_Str(25,32,128,16,setup[set+2],16,0);
Show_Str(0,52,128,12,“上 下 确定”,12,0);
OLED_Refresh_Gram();//更新显示
time2=0;
while(1)
{
44
//超时锁屏
time2++;
if(time2>10000 | key_num4){
OLED_Clear();
DisLock();
if(time2>10000)beep_on_mode2();
time2 =0;
// delay_ms(1000);
OLED_Clear();
goto MAIN;
}
//手机蓝牙锁定
if(memcmp(USART_RX_BUF,“LOCK”,4)0) {
// USART_RX_STA=0;
// memset(USART_RX_BUF,0,USART_REC_LEN);
DisLock();
goto MAIN;
}
//功能选项选择
key_num=Button4_4_Scan();
if(key_num)
{
if(key_num13){
if(arrow>0)arrow–;
goto MENUNOCLR;
}
if(key_num15){
if(arrow<5)arrow++;
goto MENUNOCLR;
}
if(key_num16){
switch(arrow)
{
case 0:Add_FR(); break;//录指
case 1:Del_FR(); break;//删指纹
case 2:SetPassworld();break;//修改密码
case 3:Set_Time(); break; //设置时间
case 4:Add_Rfid(); break; //录入卡片
case 5:Massige(); break; //显示信息
//
}
goto MENU;
}
}delay_ms(1);
}
}//while
}
45
u8 DisErrCnt(void)
{
int time=0;
u8 buf[64];
if(sys.errTime>0)//错误次数计数
{
OLED_Clear();
while(1)
{
if(time++ == 1000)
{
time = 0;
if(sys.errTime0)
{
OLED_Clear();
break;
}
Show_Str(0,16,128,16,“密码错误次数过多”,16,0);
sprintf(buf,“请%02d秒后重试”, sys.errTime);
Show_Str(20,32,128,16,buf,16,0);
OLED_Refresh_Gram();//更新显示
}
delay_ms(1);
if(4 == Button4_4_Scan())//返回
{
OLED_Clear();
return 1;
}
}
}
}
//获取键盘数值
u16 GET_NUM(void)
{
u8 key_num=0;
u16 num=0;
OLED_ShowNum(78,32,num,3,12);
OLED_Refresh_Gram();//更新显示
while(1)
{
key_num=Button4_4_Scan();
if(key_num != -1)
{
// if(key_num13)return 0xFFFF;//‘返回’键
// if(key_num14)return 0xFF00;//
// if(key_num>0&&key_num<10&&num<99)//‘1-9’键(限制输入3位数)
// num =num10+key_num;
46
// if(key_num15)num =num/10;//‘Del’键
// if(key_num10&&num<99)num =num10;//‘0’键
// if(key_num16)return num; //‘Enter’键
switch(key_num)
{
case 1:
case 2:
case 3:
if(key_num>0&&key_num<10&&num<99)//‘1-9’键(限制输入3位数)
num =num10+key_num;
break;
case 4://返回
return 0xFFFF;
return -1;
break;
case 5:
case 6:
case 7:
if(key_num>0&&key_num<10&&num<99)//‘1-9’键(限制输入3位数)
num =num10+key_num-1;
break;
case 8:num =num/10;//‘del’键
break;
case 9:
case 10:
case 11:
if(key_num>0&&key_num<10&&num<99)//‘1-9’键(限制输入3位数)
num =num10+key_num-2;
break;
case 12: break;//DIS
case 13:
case 15:
return 0xFF00;
break;
case 14:num =num10;
break;
case 16:return num;
break;
}
OLED_ShowNum(78,32,num,3,12);
OLED_Refresh_Gram();//更新显示
}
}
}
//密码锁
int password(void)
{
47
int key_num=0,i=0,satus=0;
u16 num=0,num2=0,time3=0,time;
u8 pwd[11]=" “;
u8 hidepwd[11]=” “;
u8 buf[64];
OLED_Clear();//清屏
if(DisErrCnt())return -1;//错误次数超限
OLED_Clear();//清屏
Show_Str(5,0,128,16,“密码:”,16,0);
Show_Str(10,16,128,12,” 1 2 3 Bck",12,0);
Show_Str(10,28,128,12," 4 5 6 Del",12,0);
Show_Str(10,40,128,12," 7 8 9 Dis",12,0);
Show_Str(10,52,128,12,“Clr 0 Clr OK”,12,0);
OLED_Refresh_Gram();//更新显示
// Show_Str(102,36,128,12,“显示”,12,0);
// Show_Str(0,52,128,12,“删除 清空 返回 确认”,12,0);
while(1)
{
key_num=Button4_4_Scan();
if(key_num != -1)
{
DisFlag = 1;
time3=0;
if(key_num != -1)
{
DisFlag = 1;
time3=0;
switch(key_num)
{
case 1:
case 2:
case 3:
pwd[i]=key_num+0x30; //1-3
hidepwd[i]=‘‘;
i++;
break;
case 4://返回
OLED_Clear();
delay_ms(500);
return -1;
break;
case 5:
case 6:
case 7:
pwd[i]=key_num+0x30-1; //4-6
hidepwd[i]=’’;
i++;
48
break;
case 8:
if( i > 0){
pwd[–i]=’ ‘; //‘del’键
hidepwd[i]=’ ‘;
}
break;
case 9:
case 10:
case 11:
pwd[i]=key_num+0x30-2; //4-6
hidepwd[i]=’‘;
i++;
break;
case 12:satus=!satus; break;//DIS
case 13:
case 15:
while(i–){
pwd[i]=’ ‘; //‘清空’键
hidepwd[i]=’ ‘;
}
i=0;
break;
case 14:
pwd[i]=0x30; //4-6
hidepwd[i]=’';
i++;
break;
case 16:
goto UNLOCK;
break;
}
}
if(DisFlag == 1)
{
if(satus0)OLED_ShowString(53,0,hidepwd,12);
else OLED_ShowString(53,0,pwd,12);
OLED_Refresh_Gram();//更新显示
}
time3++;
if(time3%10000){
OLED_Clear();//清屏
return -1;
}
}
}
UNLOCK:
49
for(i=0; i<10; i++){ //验证虚伪密码
if(pwd[i]sys.passwd1[num])num++;
else num=0;
if(num6)
break;
}
for(i=0; i<10; i++){ //验证密码
if(pwd[i]sys.passwd2[num2])num2++;
else num2=0;
if(num26)
break;
}
if(num6 | num26){
DisUnLock();
OLED_Clear();//清屏
sys.errCnt = 0;
return 0;
}
else {
sys.errCnt++;//错误次数计数
if(sys.errCnt>MAXERRTIMES)
sys.errTime = 30; //30秒不能再解锁
OLED_Clear();//清屏
Show_Str(45,48,128,16,“密码错误!”,16,0);
OLED_Refresh_Gram();//更新显示
beep_on_mode1();
delay_ms(1500);
OLED_Clear();//清屏
return -1;
}
}
//显示确认码错误信息
void ShowErrMessage(u8 ensure)
{
Show_Str(0,48,128,12,(u8*)EnsureMessage(ensure),12,0);
OLED_Refresh_Gram();//更新显示
delay_ms(1000);
OLED_ShowString(0,48," ",12);
OLED_Refresh_Gram();//更新显示
}
//录指纹
void Add_FR(void)
{
u8 i,ensure ,processnum=0;
int key_num;
u16 ID;
50
OLED_Clear();//清屏
while(1)
{
key_num=Button4_4_Scan();
if(key_num16){
OLED_Clear();//清屏
return ;
}
switch (processnum)
{
case 0:
//OLED_Clear();//清屏
i++;
Show_Str(0,0,128,16,”=== 录入指纹 =",16,0);
Show_Str(0,24,128,12,"请按指纹! ",12,0);
Show_Str(104,52,128,12,“返回”,12,0);
OLED_Refresh_Gram();//更新显示
ensure=PS_GetImage();
if(ensure0x00)
{
BEEP=1;
ensure=PS_GenChar(CharBuffer1);//生成特征
BEEP=0;
if(ensure0x00)
{
Show_Str(0,24,128,12,"指纹正常! ",12,0);
OLED_Refresh_Gram();//更新显示
i=0;
processnum=1;//跳到第二步
}else ShowErrMessage(ensure);
}else ShowErrMessage(ensure);
//OLED_Clear();//清屏
break;
case 1:
i++;
Show_Str(0,24,128,12,“请再按一次指纹”,12,0);
OLED_Refresh_Gram();//更新显示
ensure=PS_GetImage();
if(ensure0x00)
{
BEEP=1;
ensure=PS_GenChar(CharBuffer2);//生成特征
BEEP=0;
if(ensure0x00)
{
Show_Str(0,24,128,12,“指纹正常!”,12,0);
OLED_Refresh_Gram();//更新显示
51
i=0;
processnum=2;//跳到第三步
}else ShowErrMessage(ensure);
}else ShowErrMessage(ensure);
//OLED_Clear();//清屏
break;
case 2:
Show_Str(0,24,128,12,"对比两次指纹 ",12,0);
OLED_Refresh_Gram();//更新显示
ensure=PS_Match();
if(ensure0x00)
{
Show_Str(0,24,128,12,“两次指纹一样 “,12,0);
OLED_Refresh_Gram();//更新显示
processnum=3;//跳到第四步
}
else
{
Show_Str(0,24,128,12,“对比失败 请重录 “,12,0);
OLED_Refresh_Gram();//更新显示
ShowErrMessage(ensure);
i=0;
OLED_Clear();//清屏
processnum=0;//跳回第一步
}
delay_ms(1200);
//OLED_Clear();//清屏
break;
case 3:
Show_Str(0,24,128,12,“生成指纹模板… “,12,0);
OLED_Refresh_Gram();//更新显示
ensure=PS_RegModel();
if(ensure0x00)
{
//
Show_Str(0,24,128,12,“生成指纹模板成功!”,12,0);
OLED_Refresh_Gram();//更新显示
processnum=4;//跳到第五步
}else {processnum=0;ShowErrMessage(ensure);}
delay_ms(1200);
break;
case 4:
//OLED_Clear();//清屏
Show_Str(0,24,128,12,"请输入储存ID: “,12,0);
Show_Str(122,52,128,12,” ",12,0);
Show_Str(0,52,128,12,“删除 清空 确认”,12,0);
OLED_Refresh_Gram();//更新显示
52
do
ID=GET_NUM();
while(!(ID<AS608Para.PS_max));//输入ID必须小于模块容量最大的数值
ensure=PS_StoreChar(CharBuffer2,ID);//储存模板
if(ensure0x00)
{
OLED_Clear_NOupdate();//清屏
Show_Str(0,30,128,16,“录指纹成功!”,16,0);
PS_ValidTempleteNum(&ValidN);//读库指纹个数
Show_Str(66,52,128,12,“剩余”,12,0);
OLED_ShowNum(90,52,AS608Para.PS_max-ValidN,3,12);
OLED_Refresh_Gram();//更新显示
delay_ms(1500);
OLED_Clear();
return ;
}else {processnum=0;ShowErrMessage(ensure);}
OLED_Clear();//清屏
break;
}
delay_ms(400);
if(i10)//超过5次没有按手指则退出
{
OLED_Clear();
break;
}
}
}
//刷指纹
int press_FR(void)
{
SearchResult seach;
u8 ensure;
char str[256];
if(DisErrCnt())return -1;//错误次数超限
ensure=PS_GetImage();
OLED_Clear_NOupdate();
Show_Str(0,0,128,16,“正在检测指纹”,16,0);
OLED_Refresh_Gram();//更新显示
if(ensure0x00)//获取图像成功
{
ensure=PS_GenChar(CharBuffer1);
if(ensure0x00) //生成特征成功
{
ensure=PS_HighSpeedSearch(CharBuffer1,0,AS608Para.PS_max,&seach);
if(ensure0x00)//搜索成功
{
OLED_Clear_NOupdate();
53
Show_Str(20,10,128,24,“解锁中…”,24,0);
OLED_Refresh_Gram();//更新显示
Walkmotor_ON();
Show_Str(20,10,128,24,“已解锁!”,24,0);
OLED_Refresh_Gram();//更新显示
OLED_Show_Font(112,18,1);//开锁
//str=mymalloc(SRAMIN,2000);
sprintf(str,“ID:%d 匹配分”,seach.pageID);
Show_Str(0,52,128,12,(u8*)str,12,0);
sprintf(str,”:%d”,seach.mathscore);
Show_Str(96,52,128,12,(u8*)str,12,0);
//myfree(SRAMIN,str);
OLED_Refresh_Gram();//更新显示
delay_ms(1800);
OLED_Clear();
return 0;
}
else {
sys.errCnt++;//错误次数计数
if(sys.errCnt>MAXERRTIMES)
sys.errTime = 30; //30秒不能再解锁
ShowErrMessage(ensure);
OLED_Refresh_Gram();//更新显示
beep_on_mode1();
OLED_Clear();
return -1;
}
}
else
ShowErrMessage(ensure);
OLED_Refresh_Gram();//更新显示
delay_ms(2000);
OLED_Clear();
}
return -1;
}
//删除指纹
void Del_FR(void)
{
u8 ensure;
u16 num;
OLED_Clear();
Show_Str(0,0,128,16,”=== 删除指纹 =",16,0);
Show_Str(0,16,128,12,“输入指纹ID:”,12,0);
Show_Str(0,52,128,12,“返回 清空 确认删除”,12,0);
OLED_Refresh_Gram();//更新显示
delay_ms(50);
54
// AS608_load_keyboard(0,170,(u8**)kbd_delFR);
num=GET_NUM();//获取返回的数值
if(num0xFFFF)
goto MENU ; //返回主页面
else if(num0xFF00)
ensure=PS_Empty();//清空指纹库
else
ensure=PS_DeletChar(num,1);//删除单个指纹
if(ensure0)
{
OLED_Clear();
Show_Str(0,20,128,12,“删除指纹成功!”,12,0);
Show_Str(80,48,128,12,“剩余”,12,0);
OLED_Refresh_Gram();//更新显示
}
else
ShowErrMessage(ensure);
OLED_Refresh_Gram();//更新显示
PS_ValidTempleteNum(&ValidN);//读库指纹个数
OLED_ShowNum(110,48,AS608Para.PS_max-ValidN,3,12);
delay_ms(1200);
MENU:
OLED_Clear();
}
//修改密码
void SetPassworld(void)
{
int pwd_ch=0;
int key_num=0,i=0,satus=0;
u16 time4=0;
u8 pwd[6]=” “;
u8 hidepwd[6]=” “;
u8 buf[10];
OLED_Clear();//清屏
Show_Str(10,16,128,12,” 1 2 3 Bck”,12,0);
Show_Str(10,28,128,12,” 4 5 6 Del",12,0);
Show_Str(10,40,128,12," 7 8 9 Dis",12,0);
Show_Str(10,52,128,12,“Clr 0 Chg OK”,12,0);
Show_Str(5,0,128,16,“新密码”,16,0);
sprintf((char*)buf,“%d:”,pwd_ch+1);
Show_Str(5,48,128,16,buf,16,0);
OLED_Refresh_Gram();//更新显示
while(1)
{
key_num=Button4_4_Scan();
if(key_num != -1)
55
{
DisFlag = 1;
time4=0;
switch(key_num)
{
case 1:
case 2:
case 3:
pwd[i]=key_num+0x30; //1-3
hidepwd[i]=‘‘;
i++;
break;
case 4://返回
OLED_Clear();
delay_ms(500);
return ;
break;
case 5:
case 6:
case 7:
pwd[i]=key_num+0x30-1; //4-6
hidepwd[i]=’’;
i++;
break;
case 8:
if( i > 0){
pwd[–i]=’ ‘; //‘del’键
hidepwd[i]=’ ‘;
}
break;
case 9:
case 10:
case 11:
pwd[i]=key_num+0x30-2; //4-6
hidepwd[i]=’';
i++;
break;
case 12:satus=!satus; break;//DIS
case 13:
sprintf((char)buf,“%d:”,pwd_ch+1);
Show_Str(5,48,128,16,buf,16,0);
pwd_ch = !pwd_ch;
case 15:
while(i–){
pwd[i]=’ ‘; //‘清空’键
hidepwd[i]=’ ‘;
}
56
i=0;
break;
case 14:
pwd[i]=0x30; //4-6
hidepwd[i]=’';
i++;
break;
case 16:
goto MODIF;
break;
}
}
if(DisFlag == 1)
if(satus0)
{
OLED_ShowString(70,0,hidepwd,12);
OLED_Refresh_Gram();//更新显示
}
else
{
OLED_ShowString(70,0,pwd,12);
OLED_Refresh_Gram();//更新显示
}
time4++;
if(time4%10000){
OLED_Clear();//清屏
DisFlag = 1;
return ;
}
}
MODIF:
if(pwd_ch==0)
{
memcpy(sys.passwd1,pwd,7);
STMFLASH_Write(SYS_SAVEADDR,(u16)&sys,sizeof(sys));//保存到内部FLASH
//STMFLASH_Read(SYS_SAVEADDR,(u16*)&sys,sizeof(sys)); //读取
printf(“pwd=%s”,sys.passwd1);
}
else
{
memcpy(sys.passwd2,pwd,7);
STMFLASH_Write(SYS_SAVEADDR,(u16*)&sys,sizeof(sys));//保存密码到内部FLASH
// STMFLASH_Write(0X08090004,(u32*)pwd,2);//保存密码到内部eeprom
//STMFLASH_Read(SYS_SAVEADDR,(u16*)&sys,sizeof(sys)); //读取密码2
printf(“pwd2=%s”,sys.passwd1);
}
OLED_Clear();//清屏
57
Show_Str(0,48,128,16,“密码修改成功 !”,16,0);
OLED_Refresh_Gram();//更新显示
delay_ms(1000);
}
//设置时间
void Set_Time(void)
{
// RTC_TimeTypeDef RTC_TimeStruct;
// RTC_DateTypeDef calendar;
u16 year;
u8 mon,dat,wek,hour,min,sec;
u16 time5=0;
u8 tbuf[40];
int key_num;
int st=0;
// RTC_GetTime(RTC_Format_BIN,&RTC_TimeStruct);
// RTC_GetDate(RTC_Format_BIN, &calendar);
year=calendar.w_year;
mon=calendar.w_month;
dat=calendar.w_date;
wek=calendar.week;
hour=calendar.hour;
min=calendar.min;
sec=calendar.sec;
OLED_Clear();
Show_Str(98,38,128,12,“<–”,12,0);
Show_Str(0,52,128,12,“减 加 切换 确定”,12,0);
OLED_Refresh_Gram();//更新显示
while(1)
{
time5++;
key_num=Button4_4_Scan();
if(key_num12 | time53000){
OLED_Clear();//清屏
return ;
}
if(key_num13){
switch(st)
{
case 0:if(hour>0)hour–;break;
case 1:if(min>0)min–;break;
case 2:if(sec>0)sec–;break;
case 3:if(wek>0)wek–;break;
case 4:if(year>0)year–;break;
case 5:if(mon>0)mon–;break;
case 6:if(dat>0)dat–;break;
58
}
}
if(key_num14){
switch(st)
{
case 0:if(hour<23)hour++;break;
case 1:if(min<59)min++;break;
case 2:if(sec<59)sec++;break;
case 3:if(wek<7)wek++;break;
case 4:if(year<2099)year++;break;
case 5:if(mon<12)mon++;break;
case 6:if(dat<31)dat++;break;
}
}
if(key_num15){
if(st<7)st++;
if(st7)st=0;
}
if(key_num16){
break;
}
if(time5%2500)
{
switch(st) //闪烁
{
case 0:OLED_ShowString(0,0," “,24);break;
case 1:OLED_ShowString(36,0,” “,24);break;
case 2:OLED_ShowString(72,0,” “,24);break;
case 3:OLED_ShowString(110,12,” “,12);break;
case 4:OLED_ShowString(68,26,” “,12);break;
case 5:OLED_ShowString(98,26,” “,12);break;
case 6:OLED_ShowString(116,26,” “,12);break;
}
OLED_Refresh_Gram();//更新显示
}
if(time5%5000)
{
time5=0;
sprintf((char*)tbuf,“%02d:%02d:%02d”,hour,min,sec);
OLED_ShowString(0,0,tbuf,24);
//RTC_GetDate(RTC_Format_BIN, &calendar);
sprintf((char*)tbuf,“%04d-%02d-%02d”,year,mon,dat);
OLED_ShowString(68,26,tbuf,12);
sprintf((char*)tbuf,“%s”,week[wek]);
OLED_ShowString(110,12,tbuf,12);
OLED_Refresh_Gram();//更新显示
}delay_ms(1);
59
}
// RTC_Set_Time(hour,min,sec,RTC_H12_AM); //设置时间
// RTC_Set_Date(year,mon,dat,wek); //设置日期
RTC_Set(year,mon,dat,hour, min,sec);
OLED_Clear();
Show_Str(20,48,128,16,“设置成功!”,16,0);
OLED_Refresh_Gram();//更新显示
delay_ms(1000);
}
//录入新卡
u8 Add_Rfid(void)
{
u8 ID;
u16 time6=0;
u8 i,key_num,status=1,card_size;
OLED_Clear();
Show_Str(0,0,128,16,"= 录入卡片 =",16,0);
Show_Str(0,20,128,12,“请放入新卡片:”,12,0);
Show_Str(0,52,128,12,“返回”,12,0);
OLED_Refresh_Gram();//更新显示
MFRC522_Initializtion(); //初始化MFRC522
while(1)
{
AntennaOn();
status=MFRC522_Request(0x52, card_pydebuf); //寻卡
if(status0) //如果读到卡
{
printf(“rc522 ok\r\n”);
Show_Str(0,38,128,12,“读卡成功!”,12,0);
OLED_Refresh_Gram();//更新显示
status=MFRC522_Anticoll(card_numberbuf); //防撞处理
card_size=MFRC522_SelectTag(card_numberbuf); //选卡
status=MFRC522_Auth(0x60, 4, card_key0Abuf, card_numberbuf); //验卡
status=MFRC522_Write(4, card_writebuf); //写卡(写卡要小心,特别是各区的块3)
status=MFRC522_Read(4, card_readbuf); //读卡
//printf(“卡的类型:%#x %#x”,card_pydebuf[0],card_pydebuf[1]);
//卡序列号显,最后一字节为卡的校验码
printf(“卡的序列号:”);
for(i=0;i<5;i++)
{
printf(”%#x “,card_numberbuf[i]);
}
printf(”\r\n");
//卡容量显示,单位为Kbits
//printf(“卡的容量:%dKbits\n”,card_size);
AntennaOff();
OLED_Clear_NOupdate();
60
Show_Str(0,12,128,12,“请输入储存ID(0-9): “,12,0);
Show_Str(122,52,128,12,” “,12,0);
Show_Str(0,52,128,12,“删除 清空 确认”,12,0);
OLED_Refresh_Gram();//更新显示
do
ID=GET_NUM();
while(!(ID<10));//输入ID必须小于最大容量
printf(“正在录入卡片:%d\r\n”,ID);
OLED_Clear_NOupdate();
Show_Str(0,38,128,12,“正在录入.”,12,0);
OLED_Refresh_Gram();//更新显示
// memcpy(sys.cardid[ID],card_numberbuf,5);
for(i=0;i<5;i++)
{
sys.cardid[ID][i] = card_numberbuf[i];
}
STMFLASH_Write(SYS_SAVEADDR,(u16*)&sys,sizeof(sys));//保存到内部FLASH
// STMFLASH_Write(0X080f0004,(u32*)card_numberbuf,2);
// STMFLASH_Read(0X080f0004,(u32*)cardid,1); //读取卡号1
for(i=0;i<10;i++)
printf(“cardid={%X,%X,%X,%X}\r\n”,sys.cardid[i][0],sys.cardid[i][1],sys.cardid[i][2],sys.cardid
[i][3]);
Show_Str(0,38,128,12,“录入成功!”,12,0);
OLED_Refresh_Gram();//更新显示
delay_ms(1000);
OLED_Clear();
return 0;
}
key_num=Button4_4_Scan();
time6++;
if(time6%50000 | key_num13)
{
OLED_Clear();
return 1;
}
}
}
//rfid卡锁
u8 MFRC522_lock(void)
{
u8 i,j,status=1,card_size;
u8 count;
u8 prtfbuf[64];
AntennaOn();
status=MFRC522_Request(0x52, card_pydebuf); //寻卡
if(status==0) //如果读到卡
{
61
if(DisErrCnt())return -1;//错误次数超限
printf(“rc522 ok\r\n”);
status=MFRC522_Anticoll(card_numberbuf); //防撞处理
card_size=MFRC522_SelectTag(card_numberbuf); //选卡
status=MFRC522_Auth(0x60, 4, card_key0Abuf, card_numberbuf); //验卡
status=MFRC522_Write(4, card_writebuf); //写卡(写卡要小心,特别是各区的块3)
status=MFRC522_Read(4, card_readbuf); //读卡
//MFRC522_Halt(); //使卡进入休眠状态
//卡类型显示
//printf(“卡的类型:%#x %#x”,card_pydebuf[0],card_pydebuf[1]);
//卡序列号显,最后一字节为卡的校验码
count=0;
for(j=0;j<10;j++){
printf(”\r\n卡%d 的序列号:”,j);
for(i=0;i<5;i++)
{
printf("%x=%x ",card_numberbuf[i],sys.cardid[j][i]);
if(card_numberbuf[i]sys.cardid[j][i])count++;
}
printf(“\r\n”);
if(count>=4)
{
sys.errCnt = 0;
OLED_Clear_NOupdate();
sprintf(prtfbuf,“RFID:%d匹配成功”,j);
Show_Str(12,13,128,20,prtfbuf,12,0);
OLED_Refresh_Gram();//更新显示
delay_ms(500);
DisUnLock();
return 0;
}else count=0;
}
{
sys.errCnt++;//错误次数计数
if(sys.errCnt>MAXERRTIMES)
sys.errTime = 30; //30秒不能再解锁
OLED_Clear();
Show_Str(12,13,128,20,“卡片错误”,12,0);
OLED_Refresh_Gram();//更新显示
beep_on_mode1();
OLED_Clear();
OLED_Show_Font(56,48,0);//锁
DisFlag = 1;
}
printf(“\n”);
//卡容量显示,单位为Kbits
//printf(“卡的容量:%dKbits\n”,card_size);
62
//读一个块的数据显示
// printf(“卡数据:\n”);
// for(i=0;i<2;i++) //分两行显示
// {
// for(j=0;j<9;j++) //每行显示8个
// {
// printf(“%#x “,card_readbuf[j+i9]);
// }
// printf(“\n”);
// }
}
AntennaOff();
return 1;
}
//显示信息
void Massige(void)
{
OLED_Clear();
Show_Str(0,0,128,12,“智能门锁系统”,12,0);
// Show_Str(0,13,128,12,"123 ",12,0);
// Show_Str(0,26,128,12,“123 “,12,0);
// Show_Str(0,39,128,12,”:123”,12,0);
Show_Str(0,52,128,12,"2022-5-2 ",12,0);
OLED_Refresh_Gram();//更新显示
delay_ms(3000);
}
//显示时间
void Display_Data(void)
{
static u8 t=1;
u8 tbuf[40];
if(t!=calendar.sec)
{
t=calendar.sec;
sprintf((char)tbuf,”%02d:%02d:%02d”,calendar.hour,calendar.min,calendar.sec);
OLED_ShowString(0,0,tbuf,24);
//printf(tbuf);
sprintf((char*)tbuf,“%04d-%02d-%02d”,calendar.w_year,calendar.w_month,calendar.w_date);
OLED_ShowString(68,26,tbuf,12);
//printf(tbuf);
sprintf((char*)tbuf,“%s”,week[calendar.week]);
//printf(tbuf);
OLED_ShowString(110,12,tbuf,12);
DisFlag = 1;//更新显示
}
}
//开机信息
63
void starting(void)
{
u8 cnt = 0;
u8 ensure;
char str[64];
u8 key;
// OLED_Show_Image(0); //image
// OLED_Refresh_Gram();//更新显示
Show_Str(16,12,128,16,“智能门锁系统”,16,0);
OLED_Refresh_Gram();//更新显示
delay_ms(3000);
/开机信息提示**/
OLED_Clear();
Show_Str(0,0,128,12,“fingerprint system!”,12,0);
Show_Str(0,12,128,12,“connect to as608”,12,0);
OLED_Refresh_Gram();//更新显示
while(PS_HandShake(&AS608Addr))//与AS608模块握手
{
cnt++;if(cnt>10)break;
delay_ms(400);
Show_Str(0,24,128,12,"connect failed! ",12,0);
OLED_Refresh_Gram();//更新显示
delay_ms(800);
Show_Str(0,24,128,12,"connect to as608 ",12,0);
printf(“connect to as608…\r\n”);
OLED_Refresh_Gram();//更新显示
}
if(cnt>10)Show_Str(0,24,128,12,“connect failed!”,12,0);
OLED_Refresh_Gram();//更新显示
sprintf(str,“baud:%d addr:%x”,usart2_baund,AS608Addr);
Show_Str(0,36,128,12,(u8*)str,12,0);
OLED_Refresh_Gram();//更新显示
ensure=PS_ValidTempleteNum(&ValidN);//读库指纹个数
if(ensure!=0x00)
printf(“ERR:010\r\n”);
//ShowErrMessage(ensure);//显示确认码错误信息
ensure=PS_ReadSysPara(&AS608Para); //读参数
// if(ensure0x00)
// {
sprintf(str,“capacity:%d Lv: %d”,AS608Para.PS_max-ValidN,AS608Para.PS_level);
Show_Str(0,48,128,12,(u8*)str,12,0);
OLED_Refresh_Gram();//更新显示
// }
// else
// ShowErrMessage(ensure); //显示确认码错误信息
delay_ms(1000);
//
OLED_Clear();
}
void SysPartInit(void ) //系统参数初始化
{
STMFLASH_Read(SYS_SAVEADDR,(u16*)&sys,sizeof(sys)); //读取
if(sys.HZCFlag != 980706)
{
memset(&sys,0,sizeof(sys));
sys.HZCFlag = 980706;
strcpy((char *)sys.passwd1, “123456”);//密码
strcpy((char )sys.passwd2, “980706”);//密码
STMFLASH_Write(SYS_SAVEADDR,(u16)&sys,sizeof(sys));//保存到内部FLASH
printf(“初始化配置成功\r\n”);
}else
{
printf(“欢迎使用智能门锁\r\n”);
}
}