本設(shè)計(jì)僅供參考
基于STM32的矩陣電子密碼鎖的Proteus仿真 (源碼+仿真+原理圖+PCB)
原理圖:Altium Designer
仿真圖:protues 8.9
程序編譯器:keil 5
編程語(yǔ)言:C語(yǔ)言
編號(hào)C0034
主要功能:
- 液晶屏幕實(shí)時(shí)顯示矩陣鍵盤輸入的密碼;
- 4x4矩陣鍵盤可輸入6位密碼并支持循環(huán)覆蓋;
- 有密碼輸入正確或錯(cuò)誤的聲光提示;
- 帶重新輸入功能。
仿真圖(提供源文件):
原理圖(提供源文件):
PCB(僅供參考):
程序:
主函數(shù)
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; //輸入錯(cuò)誤
break;
}
else
{
flag = 0;
}
}
if(flag == 1) //輸入錯(cuò)誤
{
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);
}
}
//定時(shí)器3中斷服務(wù)函數(shù)
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);
}
鍵盤驅(qū)動(dòng)
#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全為零則沒(méi)有按鍵按下
}
else
{
HAL_Delay(5); //延時(shí)5ms去抖動(dòng)
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;
}
閱讀全文