使用单片机实现电子密码锁(状态机应用)
上篇文章作者给大家介绍了状态机在编程上的应用,感兴趣的朋友可以点击我的头像进行查看,接下来作者给大家介绍如何利用单片机实现电子密码锁,并且分享使用单片机实现一个简单的计数器项目源码。
文章涉及到的电路图和程序源码大家如果需要,可以私信给作者。
电路图见下图,功能可以分为三个部分:第一部分为输入部分,为一个4*4的矩阵键盘,键号从左到右,从上到下为0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F;第二部分为显示部分,使用四位数码管来显示输入的密码;第三部分为驱动部分,本电路使用LED来替代,实际项目中应该是用一个IO口去打开一个马达。
功能介绍:按键输入的数字逐位显示在数码管上,数码管初始状态位比如你输入,那么数码管就显示,如果继续输入76,那么数码管就显示,当输入正确密码后,即认为输入了正确的密码,单片机识别这个状态后,就去打开LED(马达)。
显示效果图如下:
输入正确密码后显示效果图,LED被点亮了。
核心代码如下:
//矩阵按键实现每5ms扫描一次扫描
voidKey_Sanf(void)
{
intKeyStataus=0x00;//当前键值
staticcharpreKeyStataus=0x00;//上一个状态键值
KEY_Port=0x0F;//低四位IO设置为1高四位IO设置为0
if((KEY_Port0x01)==0x00)
{
KeyStataus=0x01;
}
elseif((KEY_Port0x02)==0x00)
{
KeyStataus=0x02;
}
elseif((KEY_Port0x04)==0x00)
{
KeyStataus=0x03;
}
elseif((KEY_Port0x08)==0x00)
{
KeyStataus=0x04;
}
else
{
KeyStataus=0X00;
}
KEY_Port=0xF0;//低四位IO设置为1高四位IO设置为0
if((KEY_Port0x10)==0x00)
{
KeyStataus+=0x00;
}
elseif((KEY_Port0x20)==0x00)
{
KeyStataus+=0x04;
}
elseif((KEY_Port0x40)==0x00)
{
KeyStataus+=0x08;
}
elseif((KEY_Port0x80)==0x00)
{
KeyStataus+=0x0C;
}
else
{
KeyStataus=0X00;
}
if(preKeyStataus!=KeyStataus)
{
SysDataVar.u8KeyNumber=KeyStataus;
preKeyStataus=KeyStataus;
}
}
//SysDataVar.u8KeyNumber矩阵按键被按下的数字
//按键处理函数状态机应用
voidKey_Deal(void)
{
//staticKey_State=0x00;//状态机,初始状态为0x00
if(SysDataVar.u8KeyNumber!=0)//代表按键按下
{
/////////数码管数字滚动,新按下数字替代旧数字///////////
SysDataVar.u8nSegNumber[3]=SysDataVar.u8nSegNumber[2];
SysDataVar.u8nSegNumber[2]=SysDataVar.u8nSegNumber[1];
SysDataVar.u8nSegNumber[1]=SysDataVar.u8nSegNumber[0];
SysDataVar.u8nSegNumber[0]=SysDataVar.u8KeyNumber-1;
////////状态机实现///////
switch(SysDataVar.u8nSegNumber[0])//根据按键值,来改变状态
{
case1://按下数字1
{
SysDataVar.Key_State=0x01;
}break;
case2://按下数字2
{
if(SysDataVar.Key_State==0x01)
{
SysDataVar.Key_State=0x02;
}
else
{
SysDataVar.Key_State=0x00;
}
}break;
case3://按下数字3
{
if(SysDataVar.Key_State==0x02)
{
SysDataVar.Key_State=0x03;
}
else
{
SysDataVar.Key_State=0x00;
}
}break;
case4://按下数字4
{
if(SysDataVar.Key_State==0x03)
{
SysDataVar.Key_State=0x04;
}
else
{
SysDataVar.Key_State=0x00;
}
}break;
default:
{
SysDataVar.Key_State=0x00;
}
}
if(SysDataVar.Key_State==0x04)
{
LED_KEY=1;//打开LED
SysDataVar.Key_State=0x00;
}
else
{
LED_KEY=0;//关闭LED
}
SysDataVar.u8KeyNumber=0;
}
}
大家如果不明白数码管显示的原理,可以查看作者文章:《单片机控制数码管显示不同数字》,同时欢迎