前言
一、工具准备
工具一:51单片机
工具二:LCD1602液晶显示屏
工具三:Keil软件
二、开始操作
1.LCD1602的程序调试
2.矩阵键盘的程序调试
3.密码锁程序设计
总结
51单片机是一种8位的可编程控制元件,广泛应用于各种工业生产、家电中。51单片机的厂家有很多,如Inter(英特尔)、Atmel(艾特梅尔)等公司,本次实验所使用的是宏晶公司的STC89C52RC型号的单片机,此公司的其它型号单片机还有STC90C51、STC11系列、STC15系列、STC8系列等。
LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。更多详细介绍在此不多言,请移步百度百科:LCD1602详情
我使用的是 STC89C52型号的,其它类型的单片机都行,但是要注意其引脚的分布、I/O口类型,还有在烧录程序时注意更改单片机的型号。
购买单片机时,这个模块应该是赠送的,也可以单买。这里提一下LCD1602的控制指令,后面显示屏的初始化、写/读操作等需要用到。
LCD1602控制指令
常用的指令码有:
0x38:设置16×2显示,5×7点阵,8位数据接口
0x0C:设置开显示,不显示光标
0x06:写一个字符后地址指针加1
0x01:显示清0,数据指针清0
0x80:LCD第一行的起始地址
0x80+0x40:LCD第二行的起始地址
Keil是一款专业实用的c语言软件开发系统,提供编译器、编译器、安装包和调试跟踪等功能。我使用的是Keil5,文末有网盘链接,也可以去官网下载:Keil5软件
由于调试的代码过长,所以放入网盘里了,有需要的可参考。这里面的几个调试函数说明一下:
ShowChar(); |
显示一个字符 |
ShowString( ); |
显示字符串 |
ShowNum( ); |
显示十进制数字 |
ShowSignedNum( ); |
显示有符号十进制数字 |
ShowHexNum( ); |
显示十六进制数字 |
ShowBinNum( ); |
显示二进制数字 |
调试完后可以验证一下程序,调试中LED和数码管可能会乱闪,这是由于引脚冲突造成的。
我们先来了解一下矩阵键盘的接线原理。
为了减少I/O口的占用,通常将按键排列成矩阵形式,如51单片机的4X4的矩阵键盘,用8个引脚控制16个开关按键。这样连接后可采用逐行或逐列的“扫描”方式,就可以读出任何位置按键的状态。
例如,如果我们将引脚P1.3置为0(低电位),其他引脚置为1(高电位),当按下按键S1时,引脚P1.7就会变为0(低电位);反之亦然,如果P1.6引脚变为了0,那么我们就知道按键S5被按下了。又由于51的I/O口属于“弱提强拉”型,故这样的电位设置是可靠的。
了解矩阵键盘的工作原理后,使用编程来实现,代码如下:
#include
#include "Delay.h"
/*引脚配置*/
sbit FirLine = P1^3;
sbit ScoLine = P1^2;
sbit ThrLine = P1^1;
sbit ForLine = P1^0;
sbit FirRow = P1^7;
sbit ScoRow = P1^6;
sbit ThrRow = P1^5;
sbit ForRow = P1^4;
/**
* @brief 矩阵键盘按键码读取
* @param 无
* @retval KeyNum 按下按键的键码值
如果按下不松手,不会跳出此函数
*/
unsigned char MatrixKey()
{
unsigned char KeyNum = 0;
/*按列扫描矩阵键盘*/
P1 = 0xFF;
FirLine = 0;
if(FirRow == 0){Delay(20); while(FirRow == 0); Delay(20); KeyNum = 1;}
if(ScoRow == 0){Delay(20); while(ScoRow == 0); Delay(20); KeyNum = 5;}
if(ThrRow == 0){Delay(20); while(ThrRow == 0); Delay(20); KeyNum = 9;}
if(ForRow == 0){Delay(20); while(ForRow == 0); Delay(20); KeyNum = 13;}
P1 = 0xFF;
ScoLine = 0;
if(FirRow == 0){Delay(20); while(FirRow == 0); Delay(20); KeyNum = 2;}
if(ScoRow == 0){Delay(20); while(ScoRow == 0); Delay(20); KeyNum = 6;}
if(ThrRow == 0){Delay(20); while(ThrRow == 0); Delay(20); KeyNum = 10;}
if(ForRow == 0){Delay(20); while(ForRow == 0); Delay(20); KeyNum = 14;}
P1 = 0xFF;
ThrLine = 0;
if(FirRow == 0){Delay(20); while(FirRow == 0); Delay(20); KeyNum = 3;}
if(ScoRow == 0){Delay(20); while(ScoRow == 0); Delay(20); KeyNum = 7;}
if(ThrRow == 0){Delay(20); while(ThrRow == 0); Delay(20); KeyNum = 11;}
if(ForRow == 0){Delay(20); while(ForRow == 0); Delay(20); KeyNum = 15;}
P1 = 0xFF;
ForLine = 0;
if(FirRow == 0){Delay(20); while(FirRow == 0); Delay(20); KeyNum = 4;}
if(ScoRow == 0){Delay(20); while(ScoRow == 0); Delay(20); KeyNum = 8;}
if(ThrRow == 0){Delay(20); while(ThrRow == 0); Delay(20); KeyNum = 12;}
if(ForRow == 0){Delay(20); while(ForRow == 0); Delay(20); KeyNum = 16;}
return KeyNum;
}
其中的延时函数Delay()为:
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
完成LCD1602液晶显示屏和矩阵键盘的调试之后,就可以将这两个模块合在一起开发新的内容了,密码锁只是其中的一个小应用而已,你还可以使用这两个工具做更多好玩的内容,做一个简易的计算器?做一个实时日历放在实验室?还可以用来显示其他模块的数据,比如测距仪、测温仪等。
话不多说,言归正传,进入咱们的主题。
按键功能描述:
有效按键范围:S1~S12
S10~S9:对应数字1~9
S11:删除当前输入的数字,并向前移一位
S12:确认键
#include
#include
#include "LCD1602.h"
#include "MatrixKey.h"
#include "Delay.h"
unsigned char KeyNum = 0;
unsigned char password[] = {5,2,0,1,3,1,4}; //正确密码
void main()
{
unsigned int i = 1, j = 0, sigl = 0;
unsigned int In_password[6] = {0};
Outset:
init_lcd(); //LCD初始化
ShowString(1,1,"PassWord");
while(1)
{
KeyNum = MatrixKey();
while(KeyNum && i <= 6)
{
if(KeyNum > 10) goto Other_Operation;
else
{
In_password[i-1] = KeyNum % 10;
ShowNum(2,i,In_password[i-1],1);
}
i++;
KeyNum = 0;
}
Other_Operation:
/*每按下一次11键,删除最后一个数字*/
if(KeyNum == 11)
{
ShowNum(2,i-1,0);
In_password[i-2] = 0;
i--;
}
/*按下确认键12,并且输入满6个数字,判断输入密码正确性*/
else if(KeyNum == 12)
{
for(j = 0; j < 6; j++)
{
if(In_password[i] == password[i]) sigl = 0;
else
{
sigl = 1; break;
}
}
if(sigl == 1)
{
ShowString(2,1,"error!");
i = 1;goto Outset;
}
else ShowString(2,1,"congratualtion");
}
}
}
密码正确效果图:
单片机的学习是枯燥的,也是深动有趣的,愿每一位未来的嵌入工程师们都能步步攀登,学有所成!
对了,还有网盘链接:https://pan.baidu.com/s/1ogn2Otl_SUAU_XmLFo7d3Q?pwd=5m70
提取码:5m70