设计目标
设计一个多功能电子密码箱
本设计是参考了2022年江西省风标杯的题目,但是没有温度模块DHT11
原题目:链接:https://pan.baidu.com/s/13h6S0q1vDSuY60bl3h-IZg 提取码:0112
部分功能展示如下:
初始状态
初始状态如图 1所示,LED不亮,蜂鸣器不响,步进电机角度为0°。
图 1 初始状态
输入密码
点击矩阵键盘的数字输入密码,过程如图 2所示,按下矩阵键盘上表明的数字,对应的数字就显示在LCD屏幕上。
图 2 输入密码
输入过程中按下取消按键,已输入密码清空,如图 3。
图 3 取消输入
密码正确
输入密码按下确认后,如果正确,显示“密码箱已打开”,步进电机顺时针转动180°,蜂鸣器响0.5s。如图 4所示。
图 4 密码正确
此时按下重启密码箱,步进电机转为0°,且LCD显示变为初始状态。剩余输入密码次数变为3。如图 5。
图 5 重启密码箱
密码错误
密码错误,剩余次数-1,且变为未输入状态,蜂鸣器响0.5s。如图 6
图 6 密码错误
当剩余次数为0时,蜂鸣器长响,LED变亮。如图 7图 8所示。
图 7 剩余次数为0密码箱锁死
图 8 剩余次数为0报警
修改密码
当按下修改密码按键后,LCD输入密码显示行变为“changing”,表示正在修改密码,修改的密码显示在输入行,按下确认,密码箱的密码就变为刚刚输入的数字。如图9。
图 22 修改密码
主要代码:
main.c
#include "stm32f10x.h"
#include "delay.h"
#include "sys.h"
#include "lcd.h"
#include "key.h"
#include "bsp_usart.h"
#include "password.h"
#include "display.h"
#include "step.h"
#include "beep.h"
#include "led.h"
int main(void)
{
LCD_Init();
USART_Config();
Matrix_ssKey_Pin_Init();
motor_init();
beep_init();
led_init();
display();
int key_val = 0;;
GPIO_SetBits(GPIOB,GPIO_Pin_1);
while(1){
key_val = Matrix_Key_Scan();
if (key_val != 255 && flag()!=0) {
handleKeyPress(key_val);
led_off();
}
}
}
password.c
#include "password.h"
// 声明密码和当前输入的密码
uint8_t password[] = {1, 2, 3, 4, 5, 6};
uint8_t enteredPassword[6];
uint8_t enteredPasswordIndex = 0;
// 标记是否正在修改密码
uint8_t isChangingPassword = 0;
// 剩余输入密码的次数
uint8_t remainingAttempts = 3;
// 检查输入的密码是否正确
uint8_t checkPassword() {
for (int i = 0; i < 6; i++) {
if (enteredPassword[i] != password[i]) {
return 0; // 密码错误
}
}
return 1; // 密码正确
}
// 显示数字到 LCD
void displayNumber(uint8_t digit, uint8_t number) {
uint8_t col = digit * 8; // 计算列位置
if(number==0){
LCD_DIS_Char(4,col,"0",MIDDLE);
}
else
// 调用 LCD 显示数字的函数
LCD_DIS_Number(4, col, number, MIDDLE);
}
// 显示剩余次数到 LCD
void displayRemainingAttempts() {
displayNumber(15, remainingAttempts);
}
// 清除密码输入框
void clearPasswordDisplay() {
LCD_DIS_Char(4,0,"------ ",MIDDLE);
}
//剩余次数标志位
int flag(){
if(remainingAttempts ==0){
return 0;
}
else
return 1;
}
//重置密码箱
void reset_passbox(){
remainingAttempts=3;
clearPasswordDisplay();
}
// 处理按键操作
void handleKeyPress(uint8_t key_val) {
if (isChangingPassword) {
// 处理修改密码的操作
switch (key_val) {
case 0: // 按下数字 0
case 1: // 按下数字 1
case 2: // 按下数字 2
case 3: // 按下数字 3
case 4: // 按下数字 4
case 5: // 按下数字 5
case 6: // 按下数字 6
case 7: // 按下数字 7
case 8: // 按下数字 8
case 9: // 按下数字 9
if (enteredPasswordIndex < 6) {
enteredPassword[enteredPasswordIndex++] = key_val;
// 显示输入的数字到 LCD
displayNumber(enteredPasswordIndex - 1, key_val);
}
break;
case 10: // 按下确定
if (enteredPasswordIndex == 6) {
// 将输入的密码作为新密码
for (int i = 0; i < 6; i++) {
password[i] = enteredPassword[i];
}
// 清除当前输入的密码
enteredPasswordIndex = 0;
isChangingPassword = 0; // 结束修改密码状态
clearPasswordDisplay();
}
break;
case 11: // 按下取消
// 清除当前输入的密码
enteredPasswordIndex = 0;
isChangingPassword = 0; // 结束修改密码状态
break;
default:
break;
}
} else {
// 处理其他操作(例如输入密码和执行解锁操作)
switch (key_val) {
case 0: //LCD_DIS_Char(4,enteredPasswordIndex-1,"0",MIDDLE);// 按下数字 0
case 1: // 按下数字 1
case 2: // 按下数字 2
case 3: // 按下数字 3
case 4: // 按下数字 4
case 5: // 按下数字 5
case 6: // 按下数字 6
case 7: // 按下数字 7
case 8: // 按下数字 8
case 9: // 按下数字 9
if (enteredPasswordIndex < 6) {
enteredPassword[enteredPasswordIndex++] = key_val;
// 显示输入的数字到 LCD
displayNumber(enteredPasswordIndex - 1, key_val);
}
break;
case 10: // 按下确定
if (enteredPasswordIndex == 6) {
if (checkPassword()) {
// 密码正确,执行解锁操作
// ...
led_off();
u8 word[6]={1,2,3,8,9,10};
LCD_DIS_WORD(4,0,word,LONG);
buzzer_beep_0_5s();
enteredPasswordIndex = 0;
motor_ffw45X(4);
} else {
// 密码错误,减少剩余次数
led_off();
remainingAttempts--;
LCD_DIS_Char(4,0,"------",MIDDLE);
buzzer_beep_0_5s();
if (remainingAttempts == 0) {
// 没有剩余次数,禁止继续输入密码
// ...
//清除2345行
LCD_CLEAR_COL(2);
LCD_CLEAR_COL(3);
LCD_CLEAR_COL(4);
LCD_CLEAR_COL(5);
u8 hanzi_mmxss[6]={1,2,3,13,14,15};
u8 hanzi_cwjb[6]={11,12,16,17};
LCD_DIS_WORD(2,32,hanzi_cwjb,LONG);
LCD_DIS_WORD(4,16,hanzi_mmxss,LONG);
//直接死循环放在里面
while(1){
buzzer_beep_0_5s();
led_on();//LED亮
}
}
// 显示剩余次数到 LCD
displayRemainingAttempts();
// 清除当前输入的密码
enteredPasswordIndex = 0;
}
}
break;
case 11: // 按下取消
// 清除当前输入的密码
enteredPasswordIndex = 0;
LCD_DIS_Char(4,0,"------",MIDDLE);
//clearPasswordDisplay(); // 清除密码输入框的显示
break;
case 12: // 按下重启
enteredPasswordIndex = 0;
reset_passbox();//重启密码盒
motor_rev45X(4);//反转
break;
case 13: // 按下修改密码
// 进入修改密码状态
enteredPasswordIndex = 0;
isChangingPassword = 1;
LCD_DIS_Char(4,0," changeing",MIDDLE);
break;
default:
break;
}
}
}
上述展示了密码判断和主函数代码,还有一些其他代码太长就不展示了。整体文件中还有开题报告、开题答辩PPT、功能讲解视频、答辩PPT和设计报告(32面)等。