51单片机学习——矩阵按键

目录

gitee链接小程吃饭饭 (xiaocheng-has-a-meal) - Gitee.comhttps://gitee.com/xiaocheng-has-a-meal

1.图~突突突突突

矩阵键盘原理图

矩阵键盘的实物图

2.矩阵键盘

引入~啦啦啦啦啦

原理~沥沥沥沥沥

代码~嗷嗷嗷嗷嗷

【1】延时函数

[【2】 LCD1602](#【2】 LCD1602)

【3】检测按键函数Matrix

【4】主函数

3.是图像啦

4.你的阿锦啊


昨天没写博客,在摆烂,本来还想摆烂,最近心情可不好,好多东西缠在一起,捆住了该走的和不该走的。好怀念过去啊~~

1.图~突突突突突

矩阵键盘原理图

矩阵键盘的实物图

这是两个很好看的图, 一个是矩阵键盘原理图,一个是矩阵键盘,下面开始将原理

2.矩阵键盘

引入~啦啦啦啦啦

小程看了矩阵按键后非常疑惑,为什么键盘要这么搞,直接都弄成按独立键键盘不香吗?独立按键与单片机连接时,每个按键都需要单片机的一个I/O口,但是单片机的I/O口是有限的啊,如果每个按键都要一个口的话,假如我们需要多个按键来实现功能的话,51单片机就32个I/O口,怎么够用呢?

所以为了节省单片机的I/O口,我们引入矩阵键盘

原理~沥沥沥沥沥

下面我们来看矩阵键盘的工作原理,其实无论是矩阵键盘还是独立键盘,我们都是通过检测与键盘对应的I/O口是否为低电平。但是我们知道,独立按键是有一端是接地的,但是矩阵键盘两边都接在I/O口上,因此检测时需要人为通过单片机I/O口输出低电平。检测时,可以通过让一行为确定一列,检测一行按键。先送一行为低电平,然后迅速轮流扫描一次各行是否变为低电平,这样我们既确定了列线,又确定了行线,就确定了这个按键。当然,在我们搞这个的时候,也不能忘记按键消抖。

当然检测这个有多个方式,这里我们可以采取逐行或者逐列来进行检测。

代码~嗷嗷嗷嗷嗷

可以去我的gitee直接获得全套,纯开源

https://gitee.com/xiaocheng-has-a-meal/return-to-its-original-form

【1】延时函数

cpp 复制代码
//头文件
#ifndef ___H__
#define ___H__
void Delay( int x);


#endif
cpp 复制代码
#include<INTRINS.H>//延时1ms
void Delay( int x)	//11.0592MHz
{
	unsigned char data i, j;


	while(x)
		{
			_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
		x--;
		}
}

【2】 LCD1602

cpp 复制代码
#ifndef __LCD1602_H__
#define __LCD1602_H__

//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

#endif
cpp 复制代码
#include <REGX52.H>

//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0

//函数定义:
/**
  * @brief  LCD1602延时函数,12MHz调用可延时1ms
  * @param  无
  * @retval 无
  */
void LCD_Delay()//11.0592MHz的延时1ms的延时函数
{
	unsigned char data i, j;
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}

/**
  * @brief  LCD1602写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_DataPort=Command;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;
	LCD_RW=0;
	LCD_DataPort=Data;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602设置光标位置
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @retval 无
  */
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));
	}
}

/**
  * @brief  LCD1602初始化函数
  * @param  无
  * @retval 无
  */
void LCD_Init()
{
	LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
	LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
	LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
	LCD_WriteCommand(0x01);//光标复位,清屏
}

/**
  * @brief  在LCD1602指定位置上显示一个字符
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的字符
  * @retval 无
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Char);
}

/**
  * @brief  在LCD1602指定位置开始显示所给字符串
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  String 要显示的字符串
  * @retval 无
  */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
	{
		LCD_WriteData(String[i]);
	}
}

/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;
}

/**
  * @brief  在LCD1602指定位置开始显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~65535
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置开始以有符号十进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:-32768~32767
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
	unsigned char i;
	unsigned int Number1;
	LCD_SetCursor(Line,Column);
	if(Number>=0)
	{
		LCD_WriteData('+');
		Number1=Number;
	}
	else
	{
		LCD_WriteData('-');
		Number1=-Number;
	}
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置开始以十六进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~0xFFFF
  * @param  Length 要显示数字的长度,范围:1~4
  * @retval 无
  */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i,SingleNumber;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		SingleNumber=Number/LCD_Pow(16,i-1)%16;
		if(SingleNumber<10)
		{
			LCD_WriteData(SingleNumber+'0');
		}
		else
		{
			LCD_WriteData(SingleNumber-10+'A');
		}
	}
}

/**
  * @brief  在LCD1602指定位置开始以二进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~1111 1111 1111 1111
  * @param  Length 要显示数字的长度,范围:1~16
  * @retval 无
  */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
	}
}

【3】检测按键函数Matrix

cpp 复制代码
#ifndef __Matrix_H__
#define __Matrix_H__

unsigned char matrix();

#endif
cpp 复制代码
#include <REGX52.H>
#include <Delay.H>
unsigned char matrix()
{
	unsigned char Keynumber = 0;
	
	/*P1_7那行输入低电平检测*/
	P1 = 0xFF;
	P1_7 = 0;
	if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);Keynumber = 1;}
	if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);Keynumber = 2;}
	if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);Keynumber = 3;}
	if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);Keynumber = 4;}

	/*P1_6那行输入低电平检测*/
	P1 = 0xFF;
	P1_6 = 0;
	if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);Keynumber = 5;}
	if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);Keynumber = 6;}
	if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);Keynumber = 7;}
	if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);Keynumber = 8;}
	
	/*P1_5那行输入低电平检测*/
	P1 = 0xFF;
	P1_5 = 0;
	if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);Keynumber = 9;}
	if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);Keynumber = 10;}
	if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);Keynumber = 11;}
	if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);Keynumber = 12;}
	
	/*P1_4那行输入低电平检测*/
	P1 = 0xFF;
	P1_4 = 0;
	if(P1_3 == 0){Delay(20);while(P1_3 == 0);Delay(20);Keynumber = 13;}
	if(P1_2 == 0){Delay(20);while(P1_2 == 0);Delay(20);Keynumber = 14;}
	if(P1_1 == 0){Delay(20);while(P1_1 == 0);Delay(20);Keynumber = 15;}
	if(P1_0 == 0){Delay(20);while(P1_0 == 0);Delay(20);Keynumber = 16;}
	
	return Keynumber;



}

【4】主函数

cpp 复制代码
#include <REGX52.H>
#include "Delay.H"
#include "LCD1602.H"
#include "Matrix.H"
unsigned char KeyNumber = 0;

void main()
{
	LCD_Init();
	
  while(1)
  {
	  KeyNumber = Matrix();
  if(KeyNumber)
  {LCD_ShowNum(1,1,KeyNumber,2);}
	  
  }
}  

以上便是这个工程所有的代码

3.是图像啦

我按下了按键05,单片机显示图像如下

嘎嘎准,这里我就提供一种方法啦!!!

4.你的阿锦啊

面对苦难,人们往往会被打倒,但如果你坚持下去,苦难最终会给你带来回报。这种回报不一定是物质的,更多的是精神的。它会使你更加坚强,更加成熟。

相关推荐
7yewh9 分钟前
嵌入式硬件实战基础篇(三)-四层板PCB设计-步进电机驱动(TMC2208/TMC2209)
驱动开发·嵌入式硬件·mcu·物联网·硬件架构·硬件工程·pcb工艺
澄澈i24 分钟前
设计模式学习[9]---模板方法模式
c++·学习·设计模式·模板方法模式
Ice1661 小时前
算法学习笔记(十):位运算、数论等
笔记·学习
ZZZ_O^O1 小时前
【贪心算法入门第一题——860.柠檬水找零】
学习·算法·leetcode·贪心算法
我们的五年1 小时前
【Linux课程学习】:命令行参数,环境变量
linux·c语言·学习
辞丶1761 小时前
STM32基于HALL库的串口以及DMA(串口总篇)
stm32·单片机·嵌入式硬件
梅子酱~1 小时前
Vue 学习随笔系列十七 -- 表格样式修改
javascript·vue.js·学习
相醉为友2 小时前
003 STM32基础、架构以及资料介绍——常识
stm32·单片机·嵌入式硬件
HZU_Puzzle2 小时前
【6】STM32·FreeRTOS·列表和列表项
stm32·单片机·嵌入式硬件
我真的太难了啊2 小时前
学习QT第二天
开发语言·qt·学习