在网站上做宣传,风溪商城是那个网站建设的,简单班级网站模板,电商app开发文章目录 引言电路图开发板IO连接矩阵键盘的工作原理行列扫描逐行/逐列扫描 LCD1602代码库代码演示——暴力扫描代码演示——数码管(行列式)代码演示——线翻转法代码演示——LCD1602密码锁 引言
矩阵按键是一种通过行列交叉连接的按键阵列#xff0c;可以有效地减少单片机I/… 文章目录 引言电路图开发板IO连接矩阵键盘的工作原理行列扫描逐行/逐列扫描 LCD1602代码库代码演示——暴力扫描代码演示——数码管(行列式)代码演示——线翻转法代码演示——LCD1602密码锁 引言
矩阵按键是一种通过行列交叉连接的按键阵列可以有效地减少单片机I/O口的使用。常见的4x4矩阵键盘只需要8个I/O口即可读取16个按键的状态。采用逐行或逐列的“扫描”就可以读出任何位置按键的状态。
电路图 开发板IO连接 根据图片可以看出矩阵按键的连接在P1端口下面是它的原理图。 注意牵扯到数码管相连接的实物图这里不做展示可查看之前章节的数码管讲解数码管讲解演示 矩阵键盘的工作原理
矩阵键盘通过行列扫描的方式来检测按键的状态。假设我们有一个4x4的矩阵键盘它由4条行线和4条列线组成总共可以检测16个按键。每个按键位于行线和列线的交叉点上。
行列扫描
行列扫描的基本步骤如下
初始化将所有行线设置为高电平所有列线设置为低电平。扫描行逐行将行线设置为低电平检测列线的状态。如果某一列线变为低电平说明该行的某个按键被按下。扫描列则反之确定列将检测到的列线设置为高电平逐列扫描确定具体的按键位置。
逐行/逐列扫描
逐行/逐列扫描的本质与行列扫描类似但适用于矩阵键盘接到了任意的I/O口。具体步骤如下
逐行扫描将某一行设置为低电平其余行和列设置为高电平读取列线数据。逐列扫描将某一列设置为低电平其余行和列设置为高电平读取行线数据。
LCD1602代码库
注意LCD1602不过多讲解后续会提供专门的章节。因为矩阵按键代码牵扯到LCD1602根据源码可以看如何使用即可也可以使用上一章的内容使用数码管进行显示
LCD1602.h
#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);#endifLCD1602.c
#include REGX52.H//引脚配置
sbit LCD_RSP2^6;
sbit LCD_RWP2^5;
sbit LCD_ENP2^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_RS0;LCD_RW0;LCD_DataPortCommand;LCD_EN1;LCD_Delay();LCD_EN0;LCD_Delay();
}/*** brief LCD1602写数据* param Data 要写入的数据* retval 无*/
void LCD_WriteData(unsigned char Data)
{LCD_RS1;LCD_RW0;LCD_DataPortData;LCD_EN1;LCD_Delay();LCD_EN0;LCD_Delay();
}/*** brief LCD1602设置光标位置* param Line 行位置范围1~2* param Column 列位置范围1~16* retval 无*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{if(Line1){LCD_WriteCommand(0x80|(Column-1));}else if(Line2){LCD_WriteCommand(0x80|(Column-10x40));}
}/*** 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(i0;String[i]!\0;i){LCD_WriteData(String[i]);}
}/*** brief 返回值X的Y次方*/
int LCD_Pow(int X,int Y)
{unsigned char i;int Result1;for(i0;iY;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(iLength;i0;i--){LCD_WriteData(Number/LCD_Pow(10,i-1)%100);}
}/*** 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(Number0){LCD_WriteData();Number1Number;}else{LCD_WriteData(-);Number1-Number;}for(iLength;i0;i--){LCD_WriteData(Number1/LCD_Pow(10,i-1)%100);}
}/*** 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(iLength;i0;i--){SingleNumberNumber/LCD_Pow(16,i-1)%16;if(SingleNumber10){LCD_WriteData(SingleNumber0);}else{LCD_WriteData(SingleNumber-10A);}}
}/*** 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(iLength;i0;i--){LCD_WriteData(Number/LCD_Pow(2,i-1)%20);}
}代码演示——暴力扫描
这个程序初始化LCD显示屏并不断扫描4x4矩阵键盘。当按键被按下时相应的键号会显示在LCD1602上。延迟函数确保按键消抖以避免多次检测到单次按键。
扫描4x4矩阵键盘。它依次将每一列设置为低电平并检查每一行是否有低电平信号表示按键被按下。返回相应的键号。
#include REGX52.H
#include LCD1602.hvoid DelayXms(unsigned int xms) //12.000MHz
{unsigned char data i, j;while(xms){i 2;j 239;do{while (--j);} while (--i);xms--;}
}unsigned char MatrixKey()
{unsigned char keyNumber 0;P1 0xff;P1_3 0;//第一列低电平if(P1_7 0){DelayXms(1);while(P1_7 0);DelayXms(1);keyNumber 1;}if(P1_6 0){DelayXms(1);while(P1_6 0);DelayXms(1);keyNumber 5;}if(P1_5 0){DelayXms(1);while(P1_5 0);DelayXms(1);keyNumber 9;}if(P1_4 0){DelayXms(1);while(P1_4 0);DelayXms(1);keyNumber 13;}P1 0xff;P1_2 0;//第二列低电平if(P1_7 0){DelayXms(1);while(P1_7 0);DelayXms(1);keyNumber 2;}if(P1_6 0){DelayXms(1);while(P1_6 0);DelayXms(1);keyNumber 6;}if(P1_5 0){DelayXms(1);while(P1_5 0);DelayXms(1);keyNumber 10;}if(P1_4 0){DelayXms(1);while(P1_4 0);DelayXms(1);keyNumber 14;}P1 0xff;P1_1 0;//第三列低电平if(P1_7 0){DelayXms(1);while(P1_7 0);DelayXms(1);keyNumber 3;}if(P1_6 0){DelayXms(1);while(P1_6 0);DelayXms(1);keyNumber 7;}if(P1_5 0){DelayXms(1);while(P1_5 0);DelayXms(1);keyNumber 11;}if(P1_4 0){DelayXms(1);while(P1_4 0);DelayXms(1);keyNumber 15;}P1 0xff;P1_0 0;//第四列低电平if(P1_7 0){DelayXms(1);while(P1_7 0);DelayXms(1);keyNumber 4;}if(P1_6 0){DelayXms(1);while(P1_6 0);DelayXms(1);keyNumber 8;}if(P1_5 0){DelayXms(1);while(P1_5 0);DelayXms(1);keyNumber 12;}if(P1_4 0){DelayXms(1);while(P1_4 0);DelayXms(1);keyNumber 16;}return keyNumber;
} void main()
{LCD_Init();LCD_ShowString(1,1,helloword);while(1){unsigned char temp MatrixKey();if(temp){LCD_ShowNum(2,1,temp,2);}}
}代码演示——数码管(行列式)
程序初始化数码管并不断扫描4x4矩阵键盘。当按键被按下时相应的键号会显示在数码管上。延迟函数确保按键消抖以避免多次检测到单次按键。9之后的数字显示的是字母A~E数码管如何连接可参考此博客数码管讲解演示
#include REGX52.H//共阴极数码管显示 0~F 的段码数据
unsigned char gsmg_code[17]{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void DelayXms(unsigned int xms) //12.000MHz
{unsigned char data i, j;while(xms){i 2;j 239;do{while (--j);} while (--i);xms--;}
}unsigned char MatrixRanksScan()
{unsigned char keyNum 0;P1 0xf7;//第一列低电平if(P1 ! 0xf7)//表示第一列有按键按下{DelayXms(1);//消抖处理switch(P1){case 0x77:keyNum 1;break;case 0xb7:keyNum 5;break;case 0xd7:keyNum 9;break;case 0xe7:keyNum 13;break;}}while(P1 ! 0xf7);P1 0xfb;//第二列低电平if(P1 ! 0xfb)//表示第一列有按键按下{DelayXms(1);//消抖处理switch(P1){case 0x7b:keyNum 2;break;case 0xbb:keyNum 6;break;case 0xdb:keyNum 10;break;case 0xeb:keyNum 14;break;}}while(P1 ! 0xfb);P1 0xfd;//第三列低电平if(P1 ! 0xfd)//表示第一列有按键按下{DelayXms(1);//消抖处理switch(P1){case 0x7d:keyNum 3;break;case 0xbd:keyNum 7;break;case 0xdd:keyNum 11;break;case 0xeb:keyNum 15;break;}}while(P1 ! 0xfd);P1 0xfe;//第四列低电平if(P1 ! 0xfe)//表示第一列有按键按下{DelayXms(1);//消抖处理switch(P1){case 0x7e:keyNum 4;break;case 0xbe:keyNum 8;break;case 0xde:keyNum 12;break;case 0xee:keyNum 16;break;}}while(P1 ! 0xfe);return keyNum;
}void main()
{unsigned char temp 0;P0 ~gsmg_code[temp];while(1){temp MatrixRanksScan();if(temp){P0 ~gsmg_code[temp];}}
}代码演示——线翻转法
线翻转法是一种用于矩阵键盘扫描的技术特别适用于单片机控制的场景。它通过交替设置行和列的电平来检测按键的按下位置。扫描4x4矩阵键盘。它首先将列设置为低电平并检查是否有按键按下。如果有按键按下则进一步检查行确定具体的按键位置并返回相应的键值。
#include REGX52.H//共阴极数码管显示 0~F 的段码数据
unsigned char gsmg_code[17]{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void DelayXms(unsigned int xms) //12.000MHz
{unsigned char data i, j;while(xms){i 2;j 239;do{while (--j);} while (--i);xms--;}
}unsigned char MatrixFlipScan()
{unsigned char key_value 0; P1 0x0f;if(P1 ! 0x0f)//列被按下{DelayXms(1);//消抖处理if(P1 ! 0x0f){//测试列switch(P1){case 0x07://第一列有按键按下key_value 1;break;case 0x0b://第二列有按键按下key_value 2;break;case 0x0d://第三列有按键按下key_value 3;break;case 0x0e://第四列有按键按下key_value 4;break; }//测试行P1 0xf0;switch(P1){case 0x70://第一行有按键按下key_value key_value;break;case 0xb0://第二行有按键按下key_value key_value4;break;case 0xd0://第三行有按键按下key_value key_value8;break;case 0xe0://第四行有按键按下key_value key_value12;break; }}}return key_value;
}void main()
{unsigned char temp 0;P0 ~gsmg_code[temp];while(1){temp MatrixFlipScan();if(temp){P0 ~gsmg_code[temp];}}
}代码演示——LCD1602密码锁
这个程序初始化LCD显示屏并不断扫描4x4矩阵键盘。当按键被按下时相应的键号会显示在LCD上。用户可以输入密码并进行验证正确的密码会显示“OK PASS”错误的密码会显示“ERR”。密码输入和验证如果按下S1S10键号110则输入密码。如果按下S11键号11则确认密码是否正确。如果按下S12键号12则取消输入重置密码。
#include REGX52.H
#include LCD1602.hvoid DelayXms(unsigned int xms) //12.000MHz
{unsigned char data i, j;while(xms){i 2;j 239;do{while (--j);} while (--i);xms--;}
}unsigned char MatrixKey()
{unsigned char keyNumber 0;P1 0xff;P1_3 0;//第一列低电平if(P1_7 0){DelayXms(1);while(P1_7 0);DelayXms(1);keyNumber 1;}if(P1_6 0){DelayXms(1);while(P1_6 0);DelayXms(1);keyNumber 5;}if(P1_5 0){DelayXms(1);while(P1_5 0);DelayXms(1);keyNumber 9;}if(P1_4 0){DelayXms(1);while(P1_4 0);DelayXms(1);keyNumber 13;}P1 0xff;P1_2 0;//第二列低电平if(P1_7 0){DelayXms(1);while(P1_7 0);DelayXms(1);keyNumber 2;}if(P1_6 0){DelayXms(1);while(P1_6 0);DelayXms(1);keyNumber 6;}if(P1_5 0){DelayXms(1);while(P1_5 0);DelayXms(1);keyNumber 10;}if(P1_4 0){DelayXms(1);while(P1_4 0);DelayXms(1);keyNumber 14;}P1 0xff;P1_1 0;//第三列低电平if(P1_7 0){DelayXms(1);while(P1_7 0);DelayXms(1);keyNumber 3;}if(P1_6 0){DelayXms(1);while(P1_6 0);DelayXms(1);keyNumber 7;}if(P1_5 0){DelayXms(1);while(P1_5 0);DelayXms(1);keyNumber 11;}if(P1_4 0){DelayXms(1);while(P1_4 0);DelayXms(1);keyNumber 15;}P1 0xff;P1_0 0;//第四列低电平if(P1_7 0){DelayXms(1);while(P1_7 0);DelayXms(1);keyNumber 4;}if(P1_6 0){DelayXms(1);while(P1_6 0);DelayXms(1);keyNumber 8;}if(P1_5 0){DelayXms(1);while(P1_5 0);DelayXms(1);keyNumber 12;}if(P1_4 0){DelayXms(1);while(P1_4 0);DelayXms(1);keyNumber 16;}return keyNumber;
}void main()
{unsigned int password 0;unsigned int countkey 0;LCD_Init();LCD_ShowString(1,1,Password:);while(1){unsigned char temp MatrixKey();if(temp){if(temp10)//如果S1~S10按键按下进行输入密码{if(countkey 4){password*10;passwordtemp%10;//获取一位密码countkey; }LCD_ShowNum(2,1,password,4);//更新密码}if(temp 11)//S11确认{if(password 2345)//2345定义为正确密码{LCD_ShowString(1,14,O K);LCD_ShowString(2,13,PASS);}else{LCD_ShowString(1,14,ERR);password 0;//初始密码countkey 0;//初始次数LCD_ShowNum(2,1,password,4);//更新密码}}if(temp 12)//S12取消键{password 0;//初始密码countkey 0;//初始次数LCD_ShowNum(2,1,password,4);//更新密码 }}}
} 文章转载自: http://www.morning.gcqkb.cn.gov.cn.gcqkb.cn http://www.morning.qxjck.cn.gov.cn.qxjck.cn http://www.morning.bqnhh.cn.gov.cn.bqnhh.cn http://www.morning.jgcrr.cn.gov.cn.jgcrr.cn http://www.morning.gycyt.cn.gov.cn.gycyt.cn http://www.morning.grpfj.cn.gov.cn.grpfj.cn http://www.morning.pkdng.cn.gov.cn.pkdng.cn http://www.morning.qkqpy.cn.gov.cn.qkqpy.cn http://www.morning.wnwjf.cn.gov.cn.wnwjf.cn http://www.morning.ktrdc.cn.gov.cn.ktrdc.cn http://www.morning.smsjx.cn.gov.cn.smsjx.cn http://www.morning.cfmrb.cn.gov.cn.cfmrb.cn http://www.morning.cfqyx.cn.gov.cn.cfqyx.cn http://www.morning.qstjr.cn.gov.cn.qstjr.cn http://www.morning.hrpjx.cn.gov.cn.hrpjx.cn http://www.morning.zlwg.cn.gov.cn.zlwg.cn http://www.morning.cyyhy.cn.gov.cn.cyyhy.cn http://www.morning.grxbw.cn.gov.cn.grxbw.cn http://www.morning.xkhxl.cn.gov.cn.xkhxl.cn http://www.morning.jljwk.cn.gov.cn.jljwk.cn http://www.morning.oumong.com.gov.cn.oumong.com http://www.morning.fjptn.cn.gov.cn.fjptn.cn http://www.morning.ylmxs.cn.gov.cn.ylmxs.cn http://www.morning.kngx.cn.gov.cn.kngx.cn http://www.morning.szzxqc.com.gov.cn.szzxqc.com http://www.morning.ykmg.cn.gov.cn.ykmg.cn http://www.morning.rxsgk.cn.gov.cn.rxsgk.cn http://www.morning.qkqjz.cn.gov.cn.qkqjz.cn http://www.morning.mhnxs.cn.gov.cn.mhnxs.cn http://www.morning.xinyishufa.cn.gov.cn.xinyishufa.cn http://www.morning.rttp.cn.gov.cn.rttp.cn http://www.morning.pzlhq.cn.gov.cn.pzlhq.cn http://www.morning.lgsfb.cn.gov.cn.lgsfb.cn http://www.morning.kwpnx.cn.gov.cn.kwpnx.cn http://www.morning.ghxtk.cn.gov.cn.ghxtk.cn http://www.morning.tsrg.cn.gov.cn.tsrg.cn http://www.morning.pbmkh.cn.gov.cn.pbmkh.cn http://www.morning.jsljr.cn.gov.cn.jsljr.cn http://www.morning.msgrq.cn.gov.cn.msgrq.cn http://www.morning.rzscb.cn.gov.cn.rzscb.cn http://www.morning.sxmbk.cn.gov.cn.sxmbk.cn http://www.morning.mxdhy.cn.gov.cn.mxdhy.cn http://www.morning.jpkk.cn.gov.cn.jpkk.cn http://www.morning.yktr.cn.gov.cn.yktr.cn http://www.morning.pkmcr.cn.gov.cn.pkmcr.cn http://www.morning.jbysr.cn.gov.cn.jbysr.cn http://www.morning.rzysq.cn.gov.cn.rzysq.cn http://www.morning.smszt.com.gov.cn.smszt.com http://www.morning.lqtwb.cn.gov.cn.lqtwb.cn http://www.morning.zmlnp.cn.gov.cn.zmlnp.cn http://www.morning.hmqmm.cn.gov.cn.hmqmm.cn http://www.morning.rgmls.cn.gov.cn.rgmls.cn http://www.morning.fpqq.cn.gov.cn.fpqq.cn http://www.morning.owenzhi.com.gov.cn.owenzhi.com http://www.morning.vtbtje.cn.gov.cn.vtbtje.cn http://www.morning.gbcxb.cn.gov.cn.gbcxb.cn http://www.morning.hsjfs.cn.gov.cn.hsjfs.cn http://www.morning.nqwkn.cn.gov.cn.nqwkn.cn http://www.morning.c7513.cn.gov.cn.c7513.cn http://www.morning.rhdln.cn.gov.cn.rhdln.cn http://www.morning.njnqn.cn.gov.cn.njnqn.cn http://www.morning.qbdqc.cn.gov.cn.qbdqc.cn http://www.morning.tnmmp.cn.gov.cn.tnmmp.cn http://www.morning.pqppj.cn.gov.cn.pqppj.cn http://www.morning.nsncq.cn.gov.cn.nsncq.cn http://www.morning.dwhnb.cn.gov.cn.dwhnb.cn http://www.morning.xfdkh.cn.gov.cn.xfdkh.cn http://www.morning.wjxyg.cn.gov.cn.wjxyg.cn http://www.morning.ktdqu.cn.gov.cn.ktdqu.cn http://www.morning.tlnbg.cn.gov.cn.tlnbg.cn http://www.morning.pphbn.cn.gov.cn.pphbn.cn http://www.morning.lpcct.cn.gov.cn.lpcct.cn http://www.morning.xrnh.cn.gov.cn.xrnh.cn http://www.morning.zzgtdz.cn.gov.cn.zzgtdz.cn http://www.morning.mrckk.cn.gov.cn.mrckk.cn http://www.morning.nfcxq.cn.gov.cn.nfcxq.cn http://www.morning.lthgy.cn.gov.cn.lthgy.cn http://www.morning.wanjia-sd.com.gov.cn.wanjia-sd.com http://www.morning.qgjxt.cn.gov.cn.qgjxt.cn http://www.morning.znlhc.cn.gov.cn.znlhc.cn