本设计仅供参考
基于STM32的矩阵电子密码锁的Proteus仿真 (源码+仿真+原理图+PCB)
原理图:Altium Designer
仿真图:protues 8.9
程序编译器:keil 5
编程语言:C语言
编号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); // 10ms
Beep_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;
else
disp_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;
}
阅读全文