51单片机期末考试设计题目
设计要求:
设计具有16个按键和1个数码管显示的密码锁,具体要求: 输入一位密码(为0~9,A~F之间的数字),密码输入正确显示“F”并将锁打开;否则显示“E”,继续保持锁定状态。
基本要求:
密码锁的基本功能如下:16个按键,分别代表数字0、1、2……9和英文字符A~F;密码在程序中事先设定为:“8”;系统上电时,数码管显示“-”,表示等待密码输入;密码输入正确时显示字符“F”约3s,并通过P3.0端口将锁打开;否则显示字符“E”约3s,继续保持锁定状态。
原理图设计如下:
程序设计如下:
#include "regx52.h" //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
#define GPIO_DIG P0 //数码管
#define GPIO_KEY P3 //按键
u8 KeyValue,mark; //KeyValue用来存放读取到的键值,mark用来存取按键按下标志位
u8 code smgduan[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//显示0~F的值
/*******************************************************************************
* 函 数 名 : Delay
* 函数功能 : 延时xms个1ms时间
***+****************************************************************************/
void Delay(u16 xms)
{
u8 i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
/*******************************************************************************
* 函 数 名 : KeyDown
* 函数功能 : 按键检测并返回键值
***+****************************************************************************/
void KeyDown(void)
{
char a=0;
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)//读取按键是否按下
{
Delay(10);//延时10ms进行消抖
if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
{
mark=1;
//测试列
GPIO_KEY=0X0F; //逐列
switch(GPIO_KEY)
{
case(0X07): KeyValue=0;break; //左1列
case(0X0b): KeyValue=1;break; // 2
case(0X0d): KeyValue=2;break; // 3
case(0X0e): KeyValue=3;break; // 4
}
//测试行
GPIO_KEY=0XF0; //逐行
switch(GPIO_KEY)
{
case(0X70): KeyValue=KeyValue;break; // 第一行
case(0Xb0): KeyValue=KeyValue+4;break; // 2
case(0Xd0): KeyValue=KeyValue+8;break; // 3
case(0Xe0): KeyValue=KeyValue+12;break; // 4
}
}
}
while((a<10)&&(GPIO_KEY!=0xf0)) //检测按键松手检测
{
Delay(1);
a++;
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 无按键按下显示默认值-,当按键按下显示键值,
如果正确显示F并亮led灯,错误显示E,各阶段延时1秒钟。
***+****************************************************************************/
void main()
{
while(1)
{
KeyDown(); //按键判断函数
P0=0xbf; //初始值 -
if(mark==1) //如果按键按下
{
if(KeyValue==8)
{
GPIO_DIG=smgduan[KeyValue];
Delay(1000);
GPIO_DIG=smgduan[15];
P2_1=0;
Delay(1000);
P2_1=1;
mark=0;
}
else
{
GPIO_DIG=smgduan[KeyValue];
Delay(1000);
GPIO_DIG=smgduan[14];
Delay(1000);
mark=0;
}
}
}
}
注意事项:
1.原理图的矩阵按键,引脚不用接错了,引脚接错那扫描结果就不一样,而且容易出现乱码的情况。
2.如果密码正确和密码错误需要显示的不是E,F,自己可以在段码表加在后面你想要的段码值,自己二进制转16进制计算咯,然后让数码管显示【你那个段码值】。
3.还有啥了,大概其实也没有什么写的应该比较简单易懂,而且可移植性很强,比如按键扫描函数,你以后需要用到矩阵按键,(噢,这个矩阵按键接线方法都和单片机开发板的一样)完全可以照搬,你只要知道怎么用就可以了。至于他的扫描方式,那注释也比较清楚,洒洒水了。
4.我这里有一整套的,程序+原理图+实验报告,需要可以私信,绝得可以,打赏一点也可以的。
转自:
https://blog.csdn.net/qq_64972872/article/details/128347296