用数码管和矩阵按键实现密码锁功能,我的理解是实现输入数据并判断数据是否和密码一致,并且更改密码。矩阵按键是4×4的,图在下面。先说功能,初始密码值4321。第一部分:当数码管未进行闪烁的时候,按下S11是进行数据和密码的比较,当正确时数码管显示1111,错误显示2222。按下S12进行数据移位(口误了,应该是数据选择而不是数据移位,但意思大家一定要理解,因为下面的我都口误了),这时数码管闪烁,你按下S1到S10可以进行设定,当按四次S12的时候或者按下S13可以不闪烁了,这时按下S11才能进行数据比较(意思是只有不闪烁才能进行数据比较)。这是数据和密码的比较。第二部分:当数码管不进行闪烁的时候才能进行密码的更改,按下S14显示密码值。按下S15时进行密码值的选择,也就是闪烁,按下S1到S10可以进行数码值的改变,按四次S15或者按一次S16可以将数码管闪烁消除,再按一次S14可以退出密码设置,问题在于你如果按了S11到S13会改变数据数值吗?同理在数据和密码比较的时候你要是按了S14到S16会对密码造成影响吗?这是标志位的设定问题大家思考一下。自己写一遍是最好的,会发现很多问题考虑。
我们还按照从小到大,从浅入深的方法解决这个问题。
步骤一、考虑一下你的数据如何从矩阵按键输送给数码管,这里面大家可以想一下如何解决这个问题,我用了函数封装以及调用。(这里有一个很有意思的东西,大家好好考虑一下,超有意思)
步骤二、考虑如何实现输入数据,数据的输入方式是从右向左依次输入,举个例子就是输入4321,显示就是4321,,这是规则。
步骤三、实现数据输入后,再进行输入数据和密码的比较,当正确的时候显示1111,错误显示2222。
这是这个程序的骨架,以后的程序都是在上面的添加。
步骤四、当按下S12的时候(也就是输入数据11,我程序中用的都是数据),进行移位操作,数码管会进行闪烁。这是可以更改数据,当你按四次S12或者按下S13的时候数码管不会闪烁了,这时再按一下S11,就是数据和密码的比较,这也是规则。当你在数码管闪烁的时候按S11是不会进行比较的(规则)。这时程序已经开始丰满了。
步骤五、进行改变密码操作,这个操作和改变数据操作很相似,但由于太相似了,所以会有所冲突,这时就需要条件才能保证程序的正常运行。具体操作手法就是用数据和密码的移位的标志位来限制数据和密码的比较(按下S11)和更改密码的按键(S14),这样避免了在你按错键又看不到现象的情况下,程序自己在两者之间不断运行。
总结:没必要太过纠结于别人程序怎么写,先看现象理解那个程序的功能,想好思路,自己写一遍(由浅入深一步步来,不要一步成,写程序大忌)。出了问题自己找解决办法,没法解决参考别人的也可以。记住一定要保证基层骨架的完美,才可进行复杂功能的添加。大家只需要找到自己需要的一部分就行了。
程序我觉得最重要的部分:矩阵函数的封装,移位时数码管的闪烁,如何将大于9的数不显示在数码管上,进行密码改变时的标志位设定,数据和密码的比较与密码改变的互锁关系,定时器开关的设定(TR0=1或0)
电路原理图如下:
单片机源程序如下:
#include "digdisplay.h" //矩阵按键输入10(键表面为S11,程序中默认都是数值)为密码确认,矩阵按键输入11为移位操作按钮,输入12为移位后闪烁的确认键,按下之后便会不闪烁;
#include "key.h" //矩阵按键输入13将进行密码的设定,输入14为密码的移位,输入15为结束闪烁
u8 digdate[4]={0,0,0,0}; //存放输入数值
u8 digcode[4]={1,2,3,4}; //存放密码值
u8 knum=0,flag0,flag1=1,knum1=0; //knum代表数据的移动位置,flag0代表移位闪烁标志位,flag1代表更改密码操作的标志位,knum1是进行密码移位的操作数
u8 time; //定时器中断时间计时,
void keyprogress() //检测密码的输入并进行判断
{
u8 keynum;
keynum=KeyDown(); //if的判断语句里应该不要加含有return的语句,我把KeyDown()放到if()里面程序错误了。
if(keynum!=0xff) //检测按键是否按下,如果矩阵按键程序返回值不是0xff,说明是在输入密码值
{
if(keynum==13&&knum==0&&knum1==0) //13代表着是否密码需要更改,默认不需要更改,不在闪烁的时候进行更改,程序一步步走
{
flag1=!flag1; //改变输入数据和密码的标志位变化
}
if(flag1)
{
if(keynum==11) //代表开始移位,定时器中断开始
{
knum++; //代表4个数码管的某一位改变
if(knum==5) //代表移位四次了,
{
knum=0; //变为初始状态,为确认做准备
}
if(knum!=0) //有按键按下
{
if(TR0!=1) //如果定时器没开启
{
TR0=1; //开启定时器
}
}
else //按键按了五次回到knum=0时,
{
if(TR0!=0) //如果定时器开启
{
TR0=0; //关闭定时器
}
}
}
if(knum==0) //代表没有进行移位时可以进行密码输入操作
{
if(keynum<=9)
{
digdate[3]=digdate[2];
digdate[2]=digdate[1];
digdate[1]=digdate[0];
digdate[0]=keynum;
}
}
else if(knum==1) //代表第零位数码管需要改变数值
{
if(keynum<=9) //防止按下移位按钮的时候显示b
{
digdate[0]=keynum; //结合显示函数写
}
else if(keynum==12)
{
knum=0;
if(TR0!=0)
{
TR0=0;
}
}
}
else if(knum==2)
{
if(keynum<=9)
{
digdate[1]=keynum; //结合显示函数写
}
else if(keynum==12)
{
knum=0;
if(TR0!=0)
{
TR0=0;
}
}
}
else if(knum==3)
{
if(keynum<=9)
{
digdate[2]=keynum; //结合显示函数写
}
else if(keynum==12)
{
knum=0;
if(TR0!=0)
{
TR0=0;
}
}
}
else if(knum==4)
{
if(keynum<=9)
{
digdate[3]=keynum; //结合显示函数写
}
else if(keynum==12)
{
knum=0;
if(TR0!=0)
{
TR0=0;
}
}
}
if(keynum==10&&knum==0&&knum1==0) //当矩阵按键值为10,且没有移位的时候才能判断
{
if(digdate[3]==digcode[3]&&digdate[2]==digcode[2]&&digdate[1]==digcode[1]&&digdate[0]==digcode[0])
{
digdate[3]=1;
digdate[2]=1;
digdate[1]=1;
digdate[0]=1;
}
else
{
digdate[3]=2;
digdate[2]=2;
digdate[1]=2;
digdate[0]=2;
}
}
}
else //如果密码进行更改
{
if(keynum==14) //密码开始移位的按键
{
knum1++;
if(knum1==5)
{
knum1=0;
}
if(knum1!=0)
{
if(TR0!=1)
{
TR0=1;
}
上一篇:16位adc AD7705单片机例程(串口打印采集数据)
下一篇:单片机串口控制步进电机的源程序
推荐阅读最新更新时间:2024-11-17 09:23
设计资源 培训 开发板 精华推荐
- ADR395B 5V 输出微功率、低噪声精密电压基准的典型应用
- 爱墓式268号-宽输入稳压输出5V3A,基于MP28167
- 使用 California Eastern Laboratories 的 THCV219 的参考设计
- LTC2428 的典型应用 - 4 通道/8 通道 20 位功率无延迟 Delta-Sigma ADC
- AD5341 并行接口、单电压输出、12 位 DAC 的典型应用
- USB HUB2.0 SL2.2S
- LT3663IMS8E、1.2V 降压转换器的典型应用
- 使用 Silicon Labs 的 EZR32WG330F256R63G 的参考设计
- 使用 Analog Devices 的 AD7710 的参考设计
- LM324声音探听器