首页 > 分享 > 51单片机

51单片机

        写在前面:

        本节的主要内容是同矩阵键盘与LCD1602液晶屏联系,实现按键的数值显示,以及按键电子锁小项目。需要源码直接转至:三、代码分享;

目录

一、硬件部分

1.1矩阵按键        

1.2LCD1602液晶显示屏幕         

二、原理图

2.1矩阵按键模块

2.2单片机核心模块

三、 代码分享

  3.1矩阵按键的数值显示   

 3.2矩阵按键实现电子锁项目;

        总结

实验介绍:利用51单片机的矩阵按键模块以及LCD1602液晶屏幕显示模块,实现矩阵键盘的控制显示等;包括:电路分析、源码分享以及电子锁项目的讲解;通过此节学习熟悉51单片机的相关模块理解,加深对电路分析,扫描概念的理解,相关C语言程序的理解与学习;

实验设备:普中51-实验开发板

实验目录

1、矩阵按键的数值显示;

2、矩阵按键实现电子锁项目;

一、硬件部分

1.1矩阵按键        

       矩阵按键是单片机外部设备中所使用的排布类似于矩阵的键盘组。在前面我们讲解过普通的独立按键模块;矩阵键盘可以看作是独立按键的一种升级,因为独立按键中一个按键需要一个I/O进行输入输出,当按键的数量增多时,I/O的数量也随之需要增多;矩阵键盘通过将多数按键进行矩阵排列,从而实现利用较少的IO口控制较多的按键

        矩阵键盘的组成结构:为了减少I/O口的占用,通常将按键排成矩阵形式;在矩阵键盘中,每一条水平线与垂直线在交叉处通过一个按键进行连接,这样(4×4=16)的矩阵键盘只需要通过8个接口就可以实现控制;下图为矩阵键盘的实物图;

1.2LCD1602液晶显示屏幕         

        LCD1602液晶显示屏幕主要用于矩阵键盘的测试;矩阵键盘的输出显示将在LCD1602上面进行显示;对于LCD1602液晶显示模块感兴趣的朋友可参考我前面对1602的博客;

51单片机--LCD1602显示自定义字符、HD44780驱动(含源码、含驱动程序、含指令集讲解)!!!好文推荐!-CSDN博客

        矩阵按键与LCD1602液晶显示屏幕在开发板上的位置如下图所示:

二、原理图

2.1矩阵按键模块

        下图为普中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,进行第四列扫描;

2.2单片机核心模块

下图为单片机的核心模块电路图,用到的引脚是红色框选的部分,与矩阵按键模块相连;

三、 代码分享

  3.1矩阵按键的数值显示   

项目说明:按下一个按键后,在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;

}

实验现象: 

 3.2矩阵按键实现电子锁项目;

项目说明:初设一个四位数字的密码,进行矩阵键盘按键输入,按键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

所属分类:花卉
上一篇: 频率单位转换器:频率单位换算表
下一篇: 节水灌溉的节水措施有哪些?