数字密码锁的详解之梳理F4总结系列逻辑篇(三)
目录
前言:程序包下载
一、简要的过程
二、涉及的知识点
三、main.c函数
四、矩阵键盘的详解
五、串口屏的详解
前言:程序包下载
下载方式一:CSDN下载:https://download.csdn.net/download/qq_38351824/12128803
下载方式二:微信公众号:① 关注Tech云 ② 回复 数字密码锁 文章最后有下载链接
一、简要的过程
--->输入开机密码(输入三次错误后,需要输入管理员密码)
--->输入正确后进入主程序
--->通过独立按键进入修改密码的模式
--->输入管理员密码(输入三次错误后,冻结60s才能接着输入)
--->输入正确后进入开始修改密码
--->填写修改的密码
--->检测密码是否修正成功
--->断电重启后,再次输入密码
--->密码修改成功
二、涉及的知识点
1、C语言
结构体、数组、指针、条件语句、循环语句
2、STM32F429
IO读写、SPI、IIC、USART
三、main.c函数
/********************************************************************************* @file main.c* @author Sumjess* @version V1.0* @date 2019-05-xx* @brief MDK5.27******************************************************************************* @attention** 实验平台 :STM32 F429 * CSDN Blog :https://blog.csdn.net/qq_38351824* 微信公众号 :Tech云********************************************************************************/#include "sum_common.h"
#include "bsp_4X4key.h"
#include "OLED_Show.h"
#include "bsp_HIM.h"
#include "bsp_i2c_ee.h"#include "OLED.h"#define pass_num 6
#define EEP_Firstpage 0x00void input_passw(void);
void input_change(void);
struct{int standard_pass[pass_num] ; //用户密码int manage_pass[pass_num]; //管理员密码int input_pass[pass_num]; //用户键入密码
}password={{0,1,2,3,4,5},{1,2,3,4,5,6},{0}};int Key_val=0;struct{int count; //输入密码位数int show; //用*显示密码位数int pairing; //输入密码和正确密码的匹配数量int pairing2;//输入密码和正确密码的匹配数量} input_test = { 0, 0 , 0 , 0}; //密码位数把控及显示、密码比对结构体struct{int verification; //密码验证完毕int succeed; //密码正确int Admin; //管理员密码int ERROR_count; //错误次数} Flag = { 0, 1 , 0, 0}; //标志位结构体 struct{int verification; //密码验证完毕int succeed; //密码正确int change; //密码修改准备开始int ERROR_count; //错误次数int test; //测试是否密码修改成功} Flag_change = { 0, 1 , 0, 0, 0}; //修改密码标志位结构体 struct{int one; //密码验证完毕int two; //密码正确int three; //管理员密码int four; //错误次数} Flag_Del = { 0, 0 , 0, 0}; //标志位结构体int main(void)
{ SysTick_Init(); //时钟初始化 LED_GPIO_Config(); //板载LED初始化 LED_PURPLE; //紫灯亮---开始初始化,请不要进行操作I2C_EE_Init();Debug_USART_Config(); //串口初始化USART1Key_GPIO_Config();OLED_Init();Key4X4_GPIO_Config(); //矩阵键盘4X4初始化LED_YELLOW; //黄灯亮---初始化结束,初始化成功,可以开始操作 input_passw(); //输入开机密码while(1) { input_change(); //修改开机密码}
}///修改开机密码//
void input_change(void)
{if(Key_Scan(GPIOA,GPIO_Pin_0)) //修改密码的按键是否按下{while(Flag_change.succeed) //密码是否修改成功{SHOW_Password_change(); //显示修改密码Key_val=KEY_Scan(); //键值获取if(Key_val!=NO_press) //确保有按键按下{ if(Key_val<=9) //确保是0-9的数字{ if(input_test.count<pass_num) //确保输入数字不超过pass_num(6)位{ *(password.input_pass+input_test.count) = Key_val; //移位存储数据,指针指向数组的首地址(password.input_pass[0])然后通过自加变量input_test.count进行移位。++input_test.count; //input_test.count自加input_test.show=input_test.count; //用*显示密码位数for(;input_test.show>0;input_test.show--) //用*显示密码位数OLED_ShowChar(32+input_test.show*8,5,'*'); //用*显示密码位数}}//if(Key_val==10) //确保是A,相当于确认键,开始比对密码{for(int b=0;b<pass_num;b++) //遍历比对{ if(*(password.input_pass+b) == *(password.manage_pass+b)) //是否比对成功input_test.pairing++; //如果成功,匹配数量加一} Flag_change.verification = 1; //比对完毕,开始测试密码是否符合要求} }if(Flag_change.verification) //开始测试密码是否符合要求{ Flag_change.verification=0; //清空标志位if(input_test.pairing==pass_num) //如果六位密码都对{ LED_GREEN; //绿灯通过Flag_change.change=1; //密码成功开始修改密码标志位SHOW_Password_OK(); //显示密码通过Delay_ms(500); //延时500msOLED_Clear(); //清屏}else{LED_RED; //红灯警报input_test.count=0; //清空输入密码位数input_test.pairing=0; //清空配对数量for(int c=0;c<pass_num;c++) //遍历输入数据数组清零{ *(password.input_pass+c)=0; //清空用户输入的错误密码SHOW_Password_error(); //显示输入密码错误Delay_ms(500); //延时500ms}OLED_Clear(); //清屏} }if(Flag_change.change) //密码修改完毕,开始检测{Flag_change.change=0; //清空标志位input_test.count=0; //清空输入密码位数LED_WHITE; //白灯亮while(1){SHOW_Password_new(); //显示请输入新密码Key_val=KEY_Scan(); //键值获取if(Key_val!=NO_press) //确保有按键按下if(Key_val<=9) //确保是0-9的数字{if(input_test.count<pass_num) //确保输入数字不超过pass_num(6)位{ *(password.standard_pass+input_test.count) = Key_val; //移位存储数据,指针指向数组的首地址(password.standard_pass[0])然后通过自加变量input_test.count进行移位。++input_test.count; //input_test.count自加input_test.show=input_test.count; //显示密码OLED_ShowNum(32+input_test.show*8,6,Key_val,1,16); //显示密码}}//if(Key_val==10) //确保是A,相当于确认键,开始比对密码{//将I2c_Buf_Write中顺序递增的数据写入EERPOM中 I2C_EE_BufferWrite( password.standard_pass, EEP_Firstpage, 6);OLED_Clear(); //清屏Flag_change.test=1; //打开测试程序的标志位SHOW_pass_succ(); //显示密码修改成功Delay_ms(500); //延时500msOLED_Clear(); //清屏Flag_change.succeed=0;//清空密码修改成功标志位 break;} }}}if(Flag_change.test) //密码修改测试{input_test.count=0; //清空输入位数 Flag.ERROR_count=0; //清空输错次数for(int b=0;b<pass_num;b++) //遍历清空数组*(password.input_pass+b) = 0;while(1){ SHOW_Password_user(); //请输入用户密码Key_val=KEY_Scan(); //键值获取if(Key_val!=NO_press) //确保有按键按下{ if(Key_val<=9) //确保是0-9的数字{ if(input_test.count<pass_num) //确保输入数字不超过pass_num(6)位{ *(password.input_pass+input_test.count) = Key_val; //移位存储数据,指针指向数组的首地址(password.input_pass[0])然后通过自加变量input_test.count进行移位。++input_test.count; //input_test.count自加input_test.show=input_test.count; //用*显示密码位数for(;input_test.show>0;input_test.show--) //用*显示密码位数OLED_ShowChar(32+input_test.show*8,5,'*'); //用*显示密码位数}}//if(Key_val==10) //确保是A,相当于确认键,开始比对密码{//将EEPROM读出数据顺序保持到I2c_Buf_Read中I2C_EE_BufferRead(password.standard_pass, EEP_Firstpage, 6); ;for(int b=0;b<pass_num;b++) //遍历比对{ if(*(password.input_pass+b) == *(password.standard_pass+b)) //是否比对成功input_test.pairing++; //如果成功,匹配数量加一 } Flag.verification = 1; //比对完毕,开始测试密码是否符合要求} }if(Flag.verification) //开始测试密码是否符合要求{ Flag.verification=0;//清空标志位 if(input_test.pairing==pass_num) //如果六位密码都对{ Flag.succeed=0; //打开密码成功标志位SHOW_Password_OK(); //显示密码通过Delay_ms(500); //延时500msLED_GREEN; //绿灯通过}else{LED_RED; //红灯警报++Flag.ERROR_count; //错误次数累加input_test.count=0; //清空输入密码位数input_test.pairing=0; //清空配对数量for(int c=0;c<pass_num;c++) //遍历{ *(password.input_pass+c)=0; //清空用户输入的错误密码SHOW_Password_error(); //显示输入密码错误Delay_ms(500); //延时500ms } OLED_Clear(); //清屏if(Flag.ERROR_count>=3) //检测密码输错次数{ Flag.ERROR_count=0; //清空密码输错次数SHOW_clock_one(); //显示锁住一分钟Delay_ms(500); //延时500msOLED_Clear(); //清屏for(int time=0;time<60;time++) //倒计时一分钟{SHOW_clock_one(); //显示锁住一分钟Delay_ms(1000);OLED_ShowNum(32,6,60-time,2,16);//实时显示倒计时 }}}}} }}
}///输入开机密码//
void input_passw(void)
{while(Flag.succeed) //密码是否正确{ SHOW_Password_prompt();//显示请输入密码Key_val=KEY_Scan(); //键值获取if(Flag.Admin) //是否进入管理员模式{ if(Key_val!=NO_press)//确保有按键按下{ //if(Key_val<=9) //确保是0-9的数字 { if(input_test.count<pass_num) //确保输入数字不超过pass_num(6)位{ *(password.input_pass+input_test.count) = Key_val; //移位存储数据,指针指向数组的首地址(password.input_pass[0])然后通过自加变量input_test.count进行移位。++input_test.count; //input_test.count自加input_test.show=input_test.count; //用*显示密码位数for(;input_test.show>0;input_test.show--) //用*显示密码位数OLED_ShowChar(32+input_test.show*8,5,'*'); //用*显示密码位数}}//if(Key_val==10) //确保是A,相当于确认键,开始比对密码{//将EEPROM读出数据顺序保持到I2c_Buf_Read中I2C_EE_BufferRead(password.standard_pass, EEP_Firstpage, 6); for(int b=0;b<pass_num;b++) //遍历比对{ if(*(password.input_pass+b) == *(password.manage_pass+b)) //是否比对成功input_test.pairing++; //如果成功,匹配数量加一} Flag.verification = 1; //比对完毕,开始测试密码是否符合要求} }if(Flag.verification) //开始测试密码是否符合要求{ Flag.verification=0; //清空标志位if(input_test.pairing==pass_num) //如果六位密码都对{ LED_GREEN; //绿灯通过Flag.succeed=0; //打开密码成功标志位Flag.Admin=0; //清空管理员模式标志位SHOW_Password_OK(); //显示密码通过Delay_ms(500); //延时500msFlag_Del.one=1;}else{LED_RED; //红灯警报input_test.count=0; //清空输入密码位数input_test.pairing=0; //清空配对数量for(int c=0;c<pass_num;c++) //遍历{ *(password.input_pass+c)=0; //清空用户输入的错误密码SHOW_Password_error(); //显示输入密码错误Delay_ms(500); //延时500ms}OLED_Clear(); //清屏} }}else //是否进入用户模式{ if(Key_val!=NO_press)//确保有按键按下{ //if(Key_val<=9) //确保是0-9的数字{ if(input_test.count<pass_num) //确保输入数字不超过pass_num(6)位{ *(password.input_pass+input_test.count) = Key_val; //移位存储数据,指针指向数组的首地址(password.input_pass[0])然后通过自加变量input_test.count进行移位。++input_test.count; //input_test.count自加input_test.show=input_test.count; //用*显示密码位数for(;input_test.show>0;input_test.show--) //用*显示密码位数OLED_ShowChar(32+input_test.show*8,5,'*'); //用*显示密码位数}}//if(Key_val==10) //确保是A,相当于确认键,开始比对密码{//将EEPROM读出数据顺序保持到I2c_Buf_Read中I2C_EE_BufferRead(password.standard_pass, EEP_Firstpage, 6); for(int b=0;b<pass_num;b++) //遍历比对{ if(*(password.input_pass+b) == *(password.standard_pass+b)) //是否比对成功input_test.pairing++; //如果成功,匹配数量加一if(*(password.input_pass+b) == *(password.manage_pass+b)) //是否比对成功input_test.pairing2++; //如果成功,匹配数量加一 } Flag.verification = 1; //比对完毕,开始测试密码是否符合要求} }if(Flag.verification) //开始测试密码是否符合要求{ Flag.verification=0; //清空标志位if((input_test.pairing==pass_num)||(input_test.pairing2==pass_num)) { //如果六位密码都对Flag.succeed=0; //打开密码成功标志位SHOW_Password_OK(); //显示密码通过Delay_ms(500); //延时500msLED_GREEN; //绿灯通过Flag_Del.one=1; //清空标志位和缓存数组数据}else{LED_RED; //红灯警报++Flag.ERROR_count; //错误次数累加input_test.count=0; //清空输入密码位数input_test.pairing=0; //清空配对数量for(int c=0;c<pass_num;c++) //遍历{ *(password.input_pass+c)=0; //清空用户输入的错误密码SHOW_Password_error(); //显示输入密码错误Delay_ms(500); //延时500ms } OLED_Clear(); //清屏if(Flag.ERROR_count>=3) //检测密码输错次数{ Flag.ERROR_count=0; //清空密码输错次数SHOW_Password_state(); //显示进入管理员模式Delay_ms(500); //延时500msOLED_Clear(); //清屏Flag.Admin=1; //进入管理员模式}}}}}if(Flag_Del.one==1) //清空标志位和缓存数组数据{OLED_Clear(); //清屏Flag_Del.one=0; //只清除一次input_test.count=0; //清空输入密码位数for(int b=0;b<pass_num;b++) //遍历清零*(password.input_pass+b) = 0; //遍历清零}
}
四、矩阵键盘的详解
五、串口屏的详解
数字密码锁的详解之梳理F4总结系列逻辑篇(三)相关推荐
- 陶晶驰stm32_陶晶驰HMI3.5寸串口屏的详解之梳理F4总结系列准备篇(二)
基于stm32的串口屏教程.用过的人都说好,哈哈哈,减少了我们很多不太必要的麻烦步骤. 程序资料包CSDN下载地址:https://download.csdn.net/download/qq_3835 ...
- x.509数字证书编码详解
转自:http://blog.sina.com.cn/s/blog_49b531af0102eahs.html x.509数字证书编码详解 一. X.509数字证书的编码 X.509证书的结构是用AS ...
- python正则表达式提取数字比较好_python正则表达式从字符串中提取数字的思路详解...
python从字符串中提取数字 使用正则表达式,用法如下: ## 总结 ## ^ 匹配字符串的开始. ## $ 匹配字符串的结尾. ## \b 匹配一个单词的边界. ## \d 匹配任意数字. ## ...
- Python Tkinter——数字拼图游戏详解版
Python Tkinter 实践系列--数字拼图游戏详解版 import random #Python中的random是一个标准库用于生成随机数.随机整数.还有随机从数据集取数据. import t ...
- C语言中的字符串转数字函数常见问题详解
目录 C语言中的字符串转数字函数常见问题详解 字符串转整形 atoi函数 字符串转长整形 strtol函数, C语言中的字符串转数字函数常见问题详解 字符串转整形 atoi函数 函数原型: int a ...
- php 获取手机特征码,【新人学习】按键精灵获取数字特征码实例详解
按键精灵获取数字特征码实例详解 运行环境:分辨率:1440x900 色深:32位 操作系统:Windows XP 按键精灵版本:7.00.3730 @兄弟工程师01未评2009/3/19//做这东西主 ...
- linux文件属性644到755,linux系统文件夹数字权限设置详解644、755、777
linux系统文件夹数字权限设置详解644.755.777 ,左至右,第一位数字代表文件所有者的权限,第二位数字代表同组用户的权限,第三位数字代表其他用户的权限. 而具体的权限是由数字来表示的,读取的 ...
- (4)top详解 (每周一个linux命令系列)
(4)top详解 (每周一个linux命令系列) linux命令 top详解 引言:今天的命令是用来看cpu信息的top top 我们先看man top top - display Linux pro ...
- 详解Linux运维工程师打怪升级篇
详解 Linux 运维工程师打怪升级篇 积累经验篇 做运维也快4年多了,就像游戏打怪升级,升级后知识体系和运维体系也相对变化挺大,学习了很多新的知识点. 运维工程师 是从一个呆逼进化为苦逼再成长为牛逼 ...
最新文章
- Vue中使用form表单提交刷新问题
- 通过先序和中序数组生成后续数组
- minicap_工具使用
- Hibernate视频学习笔记(3)常用映射标签及属性
- robomaster裁判系统服务器,2018裁判系统调试组网完全攻略
- Google Earth 和MS Virtual Earth:虚拟地球简介
- linux中断响应时间太慢_Linux中的进程调度有哪些核心概念?
- 团队文化中的害群之马
- svm神经网络葡萄酒matlab,SVM神经网络的数据分类预测-葡萄酒种类识别
- python生成简单二维码_使用Python生成个性二维码
- 【文献阅读未遂】Understanding data storage and ingestion for large-scale deep recommendation model training
- Android 9 Audio系统笔记:AudioFlinger音频流处理流程
- Untiy AVpro
- 怎样用电脑收发短信?
- 【XSY2508】【BZOJ4424】Fairy(二分图)
- STM32——三原色
- Synology NAS多媒体(Photo Station管理照片)
- Java课程设计记录——虚拟校园系统
- Jprofile连接远程机器
- ubuntu 18.04 安装 ROS
热门文章
- C++ fstream 创建文件
- Trinity简介(1)--用于无参考基因组的转录组de novo组装
- 假如自家APP被苹果下架了 你会怎么处理?
- java身高排队问题_抓狂的java之小朋友排队
- 苹果新规,微信面临下架?一文看懂苹果与腾讯“相亲相爱相杀”
- WSL(Ubuntu20.04)与其图形界面安装配置
- 牛客寒假基础集训营 | Day1 D题—hanayo和米饭
- java和vue募捐网水滴筹项目捐款爱心系统筹款系统
- oracle云怎么购买,使用免费的Oracle云服务-创建云主机
- SAP中采购订单交货己完成相关逻辑和控制原理分析