本设计仅供参考
基于STM32的矩阵电子密码锁的Proteus仿真 (源码+仿真+原理图+PCB)
原理图:Altium Designer
仿真图:protues 8.9
程序编译器:keil 5
编程语言:C语言
编号C0034
【腾讯文档】C0034 网盘链接
资料下载链接
主要功能:
- 液晶屏幕实时显示矩阵键盘输入的密码;
- 4x4矩阵键盘可输入6位密码并支持循环覆盖;
- 有密码输入正确或错误的声光提示;
- 带重新输入功能。
仿真图(提供源文件):
原理图(提供源文件):
PCB(仅供参考):
程序:
主函数
int main(void)
{uint8_t Key_Value = 27;uint8_t i = 0;/* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* Configure the system clock */SystemClock_Config();TIM3_Init(2400-1, 72-1); // 10msBeep_Init();Key_Init();LCD_Init();LCD_write_string(0, 0, "Input Password:");while(1){ Key_Value = Key_Scan();if(Key_Value < 10){disp_num[i] = Key_Value;i++;if(i > 5)i = 0;Key_Value = 27;} if(Key_Value == 16){ for(i = 0; i < 6; i++){if(disp_num[i] != password[i]){flag = 1; //输入错误break;}else{flag = 0;}}if(flag == 1) //输入错误{LCD_write_string(6, 1, Disp_NO);LED_Blink (3, 200); BEEP_Blink(3, 200); LCD_write_string(6, 1, Disp_NONE);}else //输入正确{LCD_write_string(6, 1, Disp_YES);LED_Blink (1, 500); BEEP_Blink(1, 500); LCD_write_string(6, 1, Disp_NONE);}memset(disp_num, 27, 6);Key_Value = 27;i = 0; }if(Key_Value == 13){memset(disp_num, 27, 6);Key_Value = 27;i = 0; }for(uint8_t j = 0; j < 6; j++){if(disp_num[j] > 9)disp_num_tmp[j] = 0;elsedisp_num_tmp[j] = disp_num[j];}sprintf(toDisplay, DISP_FORMAT, disp_num_tmp[0], disp_num_tmp[1], disp_num_tmp[2], disp_num_tmp[3], disp_num_tmp[4], disp_num_tmp[5]);HAL_Delay(20); }
}//定时器3中断服务函数
uint8_t led_temp = 0;
void TIM3_IRQHandler(void)
{ led_temp++;if(led_temp > 10){led_temp = 0;LED1_TOG();LCD_write_string(0, 1, toDisplay);}HAL_TIM_IRQHandler(&TIM3_Handler);
}
键盘驱动
#include "key4x4.h"void Key_Init(void)
{GPIO_InitTypeDef GPIO_Initure; X_GPIO_CLK();Y_GPIO_CLK();/*****************************4行输出*********************************************/GPIO_Initure.Pin = X1_GPIO_PIN|X2_GPIO_PIN|X3_GPIO_PIN|X4_GPIO_PIN; GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_Initure.Pull = GPIO_NOPULL; GPIO_Initure.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(X_GPIO_PORT, &GPIO_Initure);/**************************************4列输入*************************************/GPIO_Initure.Pin = Y1_GPIO_PIN; GPIO_Initure.Mode = GPIO_MODE_INPUT; GPIO_Initure.Pull = GPIO_NOPULL; GPIO_Initure.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(Y_GPIO_PORT, &GPIO_Initure);GPIO_Initure.Pin = Y2_GPIO_PIN; HAL_GPIO_Init(Y_GPIO_PORT, &GPIO_Initure);GPIO_Initure.Pin = Y3_GPIO_PIN; HAL_GPIO_Init(Y_GPIO_PORT, &GPIO_Initure);GPIO_Initure.Pin = Y4_GPIO_PIN; HAL_GPIO_Init(Y_GPIO_PORT, &GPIO_Initure);
}uint8_t Key_Scan(void)
{uint8_t KeyVal = 27;uint8_t Y1 = 0, Y2 = 0, Y3 = 0, Y4 = 0;X1_OUT(1); //先让X1输出高X2_OUT(1); //先让X2输出高X3_OUT(1); //先让X3输出高X4_OUT(1); //先让X4输出高if( (Y1_IN() | Y2_IN() | Y3_IN() | Y4_IN()) == 0 ){ return 27; //如果X1到X4全为零则没有按键按下 } else{ HAL_Delay(5); //延时5ms去抖动if( (Y1_IN() | Y2_IN() | Y3_IN() | Y4_IN()) == 0 )return 27;}/*1********************************************************/ X1_OUT(1); X2_OUT(0); X3_OUT(0); X4_OUT(0);Y1 = Y1_IN(); Y2 = Y2_IN(); Y3 = Y3_IN(); Y4 = Y4_IN();if(Y1==1&&Y2==0&&Y3==0&&Y4==0)KeyVal=1;if(Y1==0&&Y2==1&&Y3==0&&Y4==0)KeyVal=5;if(Y1==0&&Y2==0&&Y3==1&&Y4==0)KeyVal=9;if(Y1==0&&Y2==0&&Y3==0&&Y4==1)KeyVal=13; //等待按键释放while( (Y1_IN() | Y2_IN() | Y3_IN() | Y4_IN()) > 0 );/*2********************************************************/ X1_OUT(0); X2_OUT(1); X3_OUT(0); X4_OUT(0);Y1 = Y1_IN(); Y2 = Y2_IN(); Y3 = Y3_IN(); Y4 = Y4_IN();if(Y1==1&&Y2==0&&Y3==0&&Y4==0)KeyVal=2;if(Y1==0&&Y2==1&&Y3==0&&Y4==0)KeyVal=6;if(Y1==0&&Y2==0&&Y3==1&&Y4==0)KeyVal=0;if(Y1==0&&Y2==0&&Y3==0&&Y4==1)KeyVal=14; //等待按键释放while( (Y1_IN() | Y2_IN() | Y3_IN() | Y4_IN()) > 0 );/*3********************************************************/ X1_OUT(0); X2_OUT(0); X3_OUT(1); X4_OUT(0);Y1 = Y1_IN(); Y2 = Y2_IN(); Y3 = Y3_IN(); Y4 = Y4_IN();if(Y1==1&&Y2==0&&Y3==0&&Y4==0)KeyVal=3;if(Y1==0&&Y2==1&&Y3==0&&Y4==0)KeyVal=7;if(Y1==0&&Y2==0&&Y3==1&&Y4==0)KeyVal=11;if(Y1==0&&Y2==0&&Y3==0&&Y4==1)KeyVal=15; //等待按键释放while( (Y1_IN() | Y2_IN() | Y3_IN() | Y4_IN()) > 0 );/*4********************************************************/ X1_OUT(0); X2_OUT(0); X3_OUT(0); X4_OUT(1);Y1 = Y1_IN(); Y2 = Y2_IN(); Y3 = Y3_IN(); Y4 = Y4_IN();if(Y1==1&&Y2==0&&Y3==0&&Y4==0)KeyVal=4;if(Y1==0&&Y2==1&&Y3==0&&Y4==0)KeyVal=8;if(Y1==0&&Y2==0&&Y3==1&&Y4==0)KeyVal=12;if(Y1==0&&Y2==0&&Y3==0&&Y4==1)KeyVal=16; //等待按键释放while( ( Y1_IN() | Y2_IN() | Y3_IN() | Y4_IN() ) > 0 );return KeyVal;
}