写在前面:
本节的主要内容是同矩阵键盘与LCD1602液晶屏联系,实现按键的数值显示,以及按键电子锁小项目。需要源码直接转至:三、代码分享;
目录
一、硬件部分
1.1矩阵按键
1.2LCD1602液晶显示屏幕
二、原理图
2.1矩阵按键模块
2.2单片机核心模块
三、 代码分享
3.1矩阵按键的数值显示
3.2矩阵按键实现电子锁项目;
总结
实验介绍:利用51单片机的矩阵按键模块以及LCD1602液晶屏幕显示模块,实现矩阵键盘的控制显示等;包括:电路分析、源码分享以及电子锁项目的讲解;通过此节学习熟悉51单片机的相关模块理解,加深对电路分析,扫描概念的理解,相关C语言程序的理解与学习;
实验设备:普中51-实验开发板
实验目录:
1、矩阵按键的数值显示;
2、矩阵按键实现电子锁项目;
矩阵按键是单片机外部设备中所使用的排布类似于矩阵的键盘组。在前面我们讲解过普通的独立按键模块;矩阵键盘可以看作是独立按键的一种升级,因为独立按键中一个按键需要一个I/O进行输入输出,当按键的数量增多时,I/O的数量也随之需要增多;矩阵键盘通过将多数按键进行矩阵排列,从而实现利用较少的IO口控制较多的按键;
矩阵键盘的组成结构:为了减少I/O口的占用,通常将按键排成矩阵形式;在矩阵键盘中,每一条水平线与垂直线在交叉处通过一个按键进行连接,这样(4×4=16)的矩阵键盘只需要通过8个接口就可以实现控制;下图为矩阵键盘的实物图;
LCD1602液晶显示屏幕主要用于矩阵键盘的测试;矩阵键盘的输出显示将在LCD1602上面进行显示;对于LCD1602液晶显示模块感兴趣的朋友可参考我前面对1602的博客;
51单片机--LCD1602显示自定义字符、HD44780驱动(含源码、含驱动程序、含指令集讲解)!!!好文推荐!-CSDN博客
矩阵按键与LCD1602液晶显示屏幕在开发板上的位置如下图所示:
下图为普中51实验板的矩阵按键模块的电路图,图中共有16个(4行、4列)的按键;通过8个(P10-P17)端口进行控制;例如:当S1按键按下时;P17与P13端口处于短路状态;基于矩阵按键模块自身特有的特点,我们引入扫描的概念;
扫描:
1、数码管的显示:在数码管的动态显示部分,我们讲述同时显示两位以及以上的数码管时,采用的方式是:显示第一位--->显示第二位--->显示第三位.....然后快速进行循环;达到肉眼无法分辨的速度,即可实现同时显示;
2、矩阵按键模块:读取第一行(列)--->读取第二行(列)--->读取第三行(列)......然后快速进行循环;矩阵按键的扫描一共有两种扫描方式,分别是行扫描以及列扫描;
可能上述对于矩阵键盘的扫描还解释的不够清楚;下面我将通过举例进一步说明:
采用逐行扫描:先令P17、P16、P15、P14引脚为0111,进行第一行(S1、S2、S3、S4)的扫描,对P13、P12、P11、P10引脚进行检测;若其中有0或低电平,则说明对应的按键按下;(如:检测到P13为低电平,则说明S1按键被按下);
再令P17、P16、P15、P14引脚为1011,进行第二行(S4、S5、S6、S7)的扫描,对P13、P12、P11、P10引脚进行检测;若其中有0或低电平,则说明对应的按键按下;
再令P17、P16、P15、P14引脚为1101,进行第三行扫描;
再令P17、P16、P15、P14引脚为1110,进行第四行扫描;
采用逐列扫描:先令P13、P12、P11、P10引脚为0111,进行第一列(S1、S5、S9、S13)的扫描,对P17、P16、P15、P14引脚进行检测;若其中有0或低电平,则说明对应的按键按下;(如:检测到P14为低电平,则说明S13按键被按下);
先令P13、P12、P11、P10引脚为1011,进行第二列(S2、S6、S10、S14)的扫描,对P17、P16、P15、P14引脚进行检测;若其中有0或低电平,则说明对应的按键按下;
再令P13、P12、P11、P10引脚为1101,进行第三列扫描;
再令P13、P12、P11、P10引脚为1110,进行第四列扫描;
下图为单片机的核心模块电路图,用到的引脚是红色框选的部分,与矩阵按键模块相连;
项目说明:按下一个按键后,在LCD1602上显示按键的数字;
代码分享:
main.c文件
#include "LCD1602.h"
unsigned keyword;
void main()
{
LCD_Init();
while(1)
{
keyword=MatriKey();
if(keyword)
LCD_ShowNumber(1,1,keyword,2);
}
}
LCD1602.h文件
#include "LCD1602.c"
void LCD_Init();
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void unsigned char MatriKey();
void LCD_ShowNumber(unsigned char Line,unsigned char Column,unsigned int number,unsigned char length);
LCD1602.c文件(驱动程序)
#include <REGX52.H>
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0
void LCD_Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay(1);
LCD_EN=0;
LCD_Delay(1);
}
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_EN=1;
LCD_Delay(1);
LCD_EN=0;
LCD_Delay(1);
}
void LCD_Init()
{
LCD_WriteCommand(0x38);
LCD_WriteCommand(0x0c);
LCD_WriteCommand(0x06);
LCD_WriteCommand(0x01);
}
void LCD_clear()
{
LCD_WriteCommand(0x01);
}
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40));
}
}
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!=' ';i++)
{
LCD_WriteData(String[i]);
}
}
int Pow(int x,int y)
{
unsigned char i;
int result = 1;
for(i = 0; i < y; i++)
{
result *= x;
}
return result;
}
void LCD_ShowNumber(unsigned char Line,unsigned char Column,unsigned int number,unsigned char length)
{
unsigned char i;
unsigned char temp;
LCD_SetCursor(Line,Column);
for(i =length ; i > 0 ; i--)
{
temp = number/Pow(10,i-1)%10 + '0';
LCD_WriteData(temp);
}
}
unsigned char MatriKey()
{
unsigned char KeyNumber=0;
P1=0XFF;
P1_7=0;
if(P1_3==0) {LCD_Delay(20);while(P1_3==0);LCD_Delay(20);KeyNumber=1;}
if(P1_2==0) {LCD_Delay(20);while(P1_2==0);LCD_Delay(20);KeyNumber=2;}
if(P1_1==0) {LCD_Delay(20);while(P1_1==0);LCD_Delay(20);KeyNumber=3;}
if(P1_0==0) {LCD_Delay(20);while(P1_0==0);LCD_Delay(20);KeyNumber=4;}
P1=0XFF;
P1_6=0;
if(P1_3==0) {LCD_Delay(20);while(P1_3==0);LCD_Delay(20);KeyNumber=5;}
if(P1_2==0) {LCD_Delay(20);while(P1_2==0);LCD_Delay(20);KeyNumber=6;}
if(P1_1==0) {LCD_Delay(20);while(P1_1==0);LCD_Delay(20);KeyNumber=7;}
if(P1_0==0) {LCD_Delay(20);while(P1_0==0);LCD_Delay(20);KeyNumber=8;}
P1=0XFF;
P1_5=0;
if(P1_3==0) {LCD_Delay(20);while(P1_3==0);LCD_Delay(20);KeyNumber=9;}
if(P1_2==0) {LCD_Delay(20);while(P1_2==0);LCD_Delay(20);KeyNumber=10;}
if(P1_1==0) {LCD_Delay(20);while(P1_1==0);LCD_Delay(20);KeyNumber=11;}
if(P1_0==0) {LCD_Delay(20);while(P1_0==0);LCD_Delay(20);KeyNumber=12;}
P1=0XFF;
P1_4=0;
if(P1_3==0) {LCD_Delay(20);while(P1_3==0);LCD_Delay(20);KeyNumber=13;}
if(P1_2==0) {LCD_Delay(20);while(P1_2==0);LCD_Delay(20);KeyNumber=14;}
if(P1_1==0) {LCD_Delay(20);while(P1_1==0);LCD_Delay(20);KeyNumber=15;}
if(P1_0==0) {LCD_Delay(20);while(P1_0==0);LCD_Delay(20);KeyNumber=16;}
return KeyNumber;
}
实验现象:
项目说明:初设一个四位数字的密码,进行矩阵键盘按键输入,按键S1-S9分别表示数字(1-9),S10表示数字0,S11表示确认键,按下后进行与设定密码对比;S12表示清零,重新输入;S13表示,清除一位,重新输入;
代码分享:
main.c文件
#include "LCD1602.h"
unsigned char keyword,count;定义变量,变量1:按键返回值,变量2:按键按下次数
unsigned int password;
void main()
{
LCD_Init();
LCD_ShowString(1,1,"mima");
LCD_ShowNumber(2,1,0,4);
while(1)程序循环
{
keyword=MatriKey();变量2进行复制,按下按键赋按键值,未按下按键赋0
if(keyword)
{
if(keyword<=10)判断按键的数值是否在1-9
{
if(count<4)
{
password*=10。。
password+= keyword%10;
count++;
}
}
LCD_ShowNumber(2,1,password,4);
if(keyword==11)
{
if(password==1022)
{
LCD_ShowString(1,1,"Ture ");
LCD_ShowNumber(2,1,password,4);
}
else
{
LCD_ShowString(1,1,"Error");
password=0;
count=0;
LCD_ShowNumber(2,1,password,4);
}
}
if(keyword==12)
{
password=0;
count=0;
LCD_ShowNumber(2,1,password,4);
}
if(keyword==13)
{
if(count>0)
{
password/=10;
count--;
}
LCD_ShowNumber(2,1,password,4);
}
}
}
}
LCD1602.h文件(与3.1节相同)
#include "LCD1602.c"
void LCD_Init();
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void unsigned char MatriKey();
void LCD_ShowNumber(unsigned char Line,unsigned char Column,unsigned int number,unsigned char length);
LCD1602.c文件(与3.1节相同)
#include <REGX52.H>
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0
void LCD_Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void LCD_WriteCommand(unsigned char Command)
{
LCD_RS=0;
LCD_RW=0;
LCD_DataPort=Command;
LCD_EN=1;
LCD_Delay(1);
LCD_EN=0;
LCD_Delay(1);
}
void LCD_WriteData(unsigned char Data)
{
LCD_RS=1;
LCD_RW=0;
LCD_DataPort=Data;
LCD_EN=1;
LCD_Delay(1);
LCD_EN=0;
LCD_Delay(1);
}
void LCD_Init()
{
LCD_WriteCommand(0x38);
LCD_WriteCommand(0x0c);
LCD_WriteCommand(0x06);
LCD_WriteCommand(0x01);
}
void LCD_clear()
{
LCD_WriteCommand(0x01);
}
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
if(Line==1)
{
LCD_WriteCommand(0x80|(Column-1));
}
else if(Line==2)
{
LCD_WriteCommand(0x80|(Column-1+0x40));
}
}
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
unsigned char i;
LCD_SetCursor(Line,Column);
for(i=0;String[i]!=' ';i++)
{
LCD_WriteData(String[i]);
}
}
int Pow(int x,int y)
{
unsigned char i;
int result = 1;
for(i = 0; i < y; i++)
{
result *= x;
}
return result;
}
void LCD_ShowNumber(unsigned char Line,unsigned char Column,unsigned int number,unsigned char length)
{
unsigned char i;
unsigned char temp;
LCD_SetCursor(Line,Column);
for(i =length ; i > 0 ; i--)
{
temp = number/Pow(10,i-1)%10 + '0';
LCD_WriteData(temp);
}
}
unsigned char MatriKey()
{
unsigned char KeyNumber=0;
P1=0XFF;
P1_7=0;
if(P1_3==0) {LCD_Delay(20);while(P1_3==0);LCD_Delay(20);KeyNumber=1;}
if(P1_2==0) {LCD_Delay(20);while(P1_2==0);LCD_Delay(20);KeyNumber=2;}
if(P1_1==0) {LCD_Delay(20);while(P1_1==0);LCD_Delay(20);KeyNumber=3;}
if(P1_0==0) {LCD_Delay(20);while(P1_0==0);LCD_Delay(20);KeyNumber=4;}
P1=0XFF;
P1_6=0;
if(P1_3==0) {LCD_Delay(20);while(P1_3==0);LCD_Delay(20);KeyNumber=5;}
if(P1_2==0) {LCD_Delay(20);while(P1_2==0);LCD_Delay(20);KeyNumber=6;}
if(P1_1==0) {LCD_Delay(20);while(P1_1==0);LCD_Delay(20);KeyNumber=7;}
if(P1_0==0) {LCD_Delay(20);while(P1_0==0);LCD_Delay(20);KeyNumber=8;}
P1=0XFF;
P1_5=0;
if(P1_3==0) {LCD_Delay(20);while(P1_3==0);LCD_Delay(20);KeyNumber=9;}
if(P1_2==0) {LCD_Delay(20);while(P1_2==0);LCD_Delay(20);KeyNumber=10;}
if(P1_1==0) {LCD_Delay(20);while(P1_1==0);LCD_Delay(20);KeyNumber=11;}
if(P1_0==0) {LCD_Delay(20);while(P1_0==0);LCD_Delay(20);KeyNumber=12;}
P1=0XFF;
P1_4=0;
if(P1_3==0) {LCD_Delay(20);while(P1_3==0);LCD_Delay(20);KeyNumber=13;}
if(P1_2==0) {LCD_Delay(20);while(P1_2==0);LCD_Delay(20);KeyNumber=14;}
if(P1_1==0) {LCD_Delay(20);while(P1_1==0);LCD_Delay(20);KeyNumber=15;}
if(P1_0==0) {LCD_Delay(20);while(P1_0==0);LCD_Delay(20);KeyNumber=16;}
return KeyNumber;
}
实验现象:
本节的内容主要是学习的是51单片机开发板的矩阵键盘的内容,主要的难点在于同LCD1602屏幕相结合,进行串联。大家在看完博客后,一定要动手自己进行联系!!!
创作不易,还请大家多多点赞,收藏支持~!!!
相关知识
【51单片机毕业设计
基于51单片机的智能浇花系统
基于51单片机控制的自动浇水系统设计
基于51单片机的自动浇花灌溉系统设计
基于51单片机的智能浇花系统设计
(毕业设计资料)基于51单片机控制的自动浇水系统设计
基于51单片机的智能浇花系统(可做毕设)
基于51单片机土壤湿度检测及自动浇花系统
基于51单片机的新型“花疗”智能花卉养护机设计
51单片机——自动浇花系统(含全部代码)
网址: 51单片机 https://m.huajiangbk.com/newsview378990.html
上一篇: 频率单位转换器:频率单位换算表 |
下一篇: 节水灌溉的节水措施有哪些? |