6-1和6-2矩阵键盘

江科大自动化单片机学习记录

  • 使用到的设备以及软件
  • 今天的学习内容
  • 弱上拉和强下拉
  • 代码
    • LCD1602.c
    • MatrixKey.c
    • 生成.h文件
  • 调用主函数main
  • 总结

记录学习单片机的过程
学习内容的视频链接:
江科大自化协:

51单片机入门教程-2020版,程序全程纯手打

使用到的设备以及软件

普中科技的嵌入式开发实验仪,keil uvision5,普中isp(用来程序下载),stc-isp(用来生成对应的需要的代码)
软件安装包、开发板资料、课件及程序源码百度网盘链接:https://pan.baidu.com/s/1vDTN2o8ffvczzNQGfyjHng 提取码:gdzf,链接里压缩包的解压密码:51 ,如果打不开请复制链接到浏览器再打开

今天的学习内容

今天主要学习到的是51单片机当中的矩阵键盘的使用
6-1和6-2矩阵键盘_第1张图片

弱上拉和强下拉

对于I/O端口,有些器件手册会说该端口可内置上拉/下拉电阻,一般情况下,这些内置的上拉/下拉电阻被称为**“弱上拉”或“弱下拉”**。而对于实际电路中,芯片端口外接的上拉/下拉电阻常称为“强上拉”或“强下拉”
如何直观上理解 什么是"强",什么是"弱"
**“强1"可以简单的理解为输出电平的高电平越是接近VCC,那么"强0”**可以理解为输出电平接近GND
上拉电阻可以提高电路的驱动能力,其核心就在于 并联降低阻抗
6-1和6-2矩阵键盘_第2张图片

代码

这里主要附上的是6-2矩阵键盘的内容
这里主要是主函数当中的一些操作,其他的操作则需要分开来看

LCD1602.c

首先第一部分是LCD602.c文件,该部分代码是视频当中老师给到的代码,主要是对灯光,也就是液晶屏的相关操作的函数进行定义

#include 

//引脚配置:
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()
{
	unsigned char i, j;

	i = 2;
	j = 239;
	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');
	}
}

MatrixKey.c

该部分代码主要是矩阵键盘的相关操作

include <REGX52.H>
#include "Delay.h"

unsigned char MatrixKey()//有返回值的函数
{
	unsigned char KeyNumber=0;
	
	P1=0xFF;// 全部持高电平
	P1_3=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
	
	P1=0xFF;// 全部持高电平
	P1_2=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
	
	P1=0xFF;// 全部持高电平
	P1_1=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
	
	P1=0xFF;// 全部持高电平
	P1_0=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
	
	return KeyNumber;
}

生成.h文件

对于上述的两个c文件再加上一个延迟函数的delay.c生成.h文件,可以方面后续主函数的相关操作,简化代码
类似于如下图片
6-1和6-2矩阵键盘_第3张图片

调用主函数main

创建主函数main.c,在最前面的头文件当中,我们需要注意到的是上面所提到的.h文件就要写在头文件的最前面了,注意要使用""将自己创建的文件括起来

#include 
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"

unsigned char KeyNum;
unsigned int Password,Count;

void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"Password:"); 
	while(1)
	{
		KeyNum=MatrixKey();
		if(KeyNum)//不进行判断就会立马刷新
		{
			if(KeyNum<=10)//按下S~S10输入密码
			{
					if(Count<4)//如果输入次数小于4
					{
					Password*=10;				//密码左移
					//0000 0000 0001
					//0010 0012 0120 0123
					Password+=KeyNum%10;//获取一位密码
					Count++;
					}
			}
			
			LCD_ShowNum(2,1,Password,4);//更新显示
		}
		if(KeyNum==11)//按下S11
		{
			if(Password==2345)//如果输入密码为正确密码
			{
				LCD_ShowString(1,14,"OK!");//显示OK
				Password=0;//密码和计次清零
				Count=0;
				LCD_ShowNum(2,1,Password,4);//更新显示
			}
			else
			{
				LCD_ShowString(1,14,"ERR");//显示OK
				Password=0;//密码和计次清零
				Count=0;
				LCD_ShowNum(2,1,Password,4);//更新显示
			}
		}
		if(KeyNum==12)//按下S12为取消键
		{
			Password=0;//密码和计次清零
			Count=0;
			LCD_ShowNum(2,1,Password,4);//更新显示
		}
	}
		
}

总结

本节主要学习了关于单片机如何进行矩阵键盘的应用

你可能感兴趣的:(矩阵,单片机,线性代数)