【C51】单片机独立按键与矩阵按键
独立按键
首先既然是检测输入,对于当然要用到拉电阻,来检测引脚电平变化变化。51单片机中,除了P0口外,P2,P3,P4都是内置上拉电阻的准双向IO口,一般 的 51 P0引脚都外接了上拉电阻,当然也可以用作输入口。
作为输入前需要拉为高电平。 当有按键按下,致使单片机的某个引脚接地,变为低电平时,我们就认为这个按键按下了。当按键松开后,由于输入不会锁存,所以此时拉高的引脚回归到高电平。
独立按键的内部原理。
独立按键的4个引脚中,两两为一组。每一组的2个引脚是连在一起的,当按键按键时,2个组又连接了,也就是4个脚都连接一起了。
在按键没有按下去的时候1,2号脚相连,3,4号脚相连。按键按下去的时候,1,2,3,4号脚就全部接通。
按键的很重要注意点就是消除抖动,消抖。因为人按下按键不是并瞬间到位的,按键在按下的过程中会有抖动。我们需要通过延时来让单片机绕过抖动的时间。
下面是一个用按键作为开关间接控制LED的demo。
注:下图中P2.0连接的按键应该再接一个电阻,我疏忽忘记画出来了。
/***************************************
按键按下,LED亮,松开,LED熄灭 **************************************/ #include<reg51.h>
typedef unsigned int uint;
typedef unsigned char uchar ; sbit button = P2^; //按键输入引脚
sbit led = P0^; //LED控制输出引脚 /***************************/
void delay(uint t);
uchar isKeyPressed(void);
/***************************/ void main(void)
{
button = ; //P2 是 准 IO口,作为输入前要写1
led = ;
while()
{
if(isKeyPressed())
{
led = ;
delay();
led =; } } } uchar isKeyPressed(void)
{
uchar isPressed = ; //是否按下标志位
uchar c=;
if(button==) //初次检测
{
delay(); //消抖延时
if(button==) //再次验证
{
isPressed = ;
while(isPressed== && c--) //如果不用c作为计数器,那么一直按着按键的话,程序就会一直在这里循环。是否要用c需要根据自己的要求。
;
}
} return isPressed; } void delay(uint t)
{
uint i;
uchar j;
for(i=t;i>;i--)
for(j=;j>;j--)
;
}
矩阵按键
矩阵按键的检测方式有多种,最常用的就是行列式扫描检测。原理和独立按键是一样的,只不过我们要扫描一组按键,找出那个被按下的而已。
对行列式扫描的分析。
假如我们按下了按键S6,现在来检测它。
用红色表示1高电平,蓝色表示0低电平。
先给键盘连接的GPIO口赋值为0XF0。
电平反转。
这样就可以判断定了按键的坐标。
demo的连线图。
/******************************
将按键的编号显示到数码管上
*****************************/ #include<reg51.h> typedef unsigned int uint;
typedef unsigned char uchar;
typedef signed char schar;
/*************************/
void delay(uint t) ;
void showDigit(uint num);
schar martixKeyScan(void);
/***************************/ uchar code TABLE[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F} ; #define DUAN_XUAN P1 //数码管的段选
#define KEYS_REC P2 //连接矩阵键盘
sbit Add0 = P0^; //译码器的A0 A1 A3,用来数码管的位选
sbit Add1 = P0^;
sbit Add2 = P0^; void main(void)
{ schar keyRe;
uint number=; while()
{
keyRe = martixKeyScan();
if(- != keyRe){ number = keyRe;
}
showDigit(number); } } void showDigit(uint num)
{
uchar count = ; //根据输入数据的位数来开启数码管的位。
do
{
switch(count)
{
case :Add2 = ;Add1 = ;Add0 = ;break; //送入位选,显示这个数的个位
case :Add2 = ;Add1 = ;Add0 = ;break; //显示十位
case :Add2 = ;Add1 = ;Add0 = ;break;
case :Add2 = ;Add1 = ;Add0 = ;break;
case :Add2 = ;Add1 = ;Add0 = ;break;
case :Add2 = ;Add1 = ;Add0 = ;break;
case :Add2 = ;Add1 = ;Add0 = ;break;
case :Add2 = ;Add1 = ;Add0 = ;break;
} DUAN_XUAN = TABLE[num%]; //送入段选
delay();
DUAN_XUAN = ; //关闭所有段,消影
count++;
}while(num/=); } /**********************
矩阵按键检测。
有按键按下,返回按键的编号,否则返回-1;
***********************/
schar martixKeyScan(void)
{ schar col,row;
uchar c=; //松手计数器
KEYS_REC = 0xF0 ; //让连接键盘的高4位为1 ,低4位为0 if(KEYS_REC != 0xF0) //初次检查到按下
{
delay(); //消抖延时
if(KEYS_REC != 0xF0) //真的被按下了
{ switch(KEYS_REC)
{
case 0X70: row = ;break; // 0111 0000
case 0XB0: row = ; break; // 1011 0000
case 0XD0: row = ;break; // 1101 0000
case 0XE0: row = ;break; // 1110 0000
default:break;
} KEYS_REC = 0x0F; //电平反转,检测列
switch(KEYS_REC)
{
case 0X07: col = ;break; //0000 0111
case 0X0B: col = ; break; //0000 1011
case 0X0D: col = ;break; //0000 1101
case 0X0E: col = ;break; //0000 1110
default:break;
} while((c--) && (KEYS_REC!=0x0F)) //等待按键松手
{
delay(); } return (row-)*+col; //使用4X4的键盘 } //真的按下了
else
return -;
} return -;
} void delay(uint t)
{
uint i,j;
for(i=t;i>;i--)
for(j=;j>;j--)
;
}
【C51】单片机独立按键与矩阵按键的更多相关文章
- AD按键-矩阵按键-独立按键:
原理:利用数组分压+AD采集: 优点:一个IO口可以做成多个按键,节省IO口(矩阵键盘在>4时优点才能体现出来):可备用作为AD基准输入. 缺点:不能做成组合按键(或者电阻要精确选择):且离IO ...
- C51 原创电子琴 (蜂鸣器/计时器/中断/矩阵按键)
需求分析 用C51的16个矩阵按键当作两个八度的琴键 按下时发出相应音调的声音,静态数码管显示相应音符的数字. 为了解锁更多曲目,两个多的琴键设计成#4,显示时加上小数点 下图分别为1和#4的显示,其 ...
- C51 矩阵按键 个人笔记
矩阵按键 电路 每个按键一端和同行一端相连(JP4的高4位),另一端和同列一端相连(JP4的低4位) 判断按键是否按下: 法一:逐行扫描 for(int i = 8 ; i>3 ; i-- ) ...
- 【.NET 与树莓派】矩阵按键
欢迎收看火星卫视,本期节目咱们严重探讨一下矩阵按键. 所谓矩阵按键,就是一个小键盘(其实一块PCB板),上面有几个 Key(开关),你不按下去的时候,电路是断开的,你按下去电路就会接通.至于说有多少个 ...
- 十天学会单片机Day2键盘检测(独立键盘、矩阵键盘)
1.键盘的分类 编码键盘:键盘上闭合键的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘 非编码键盘:靠软件编程来识别的称为非编码键盘.独立键盘.矩阵键盘 2.按键消抖 ...
- AD按键-矩阵按键:
原理:利用数组分压+AD采集: 优点:一个IO口可以做成多个按键,节省IO口(矩阵键盘在>4时优点才能体现出来):可备用作为AD基准输入. 缺点:不能做成组合按键(或者电阻要精确选择):且离IO ...
- C51单片机_day_01(定时器和中断系统)
c51单片机 51单片机是控制电路系统的开关,当然芯片就是51芯片,现在随着科技的发展,也是出了很多,功能更多,更全的芯片. 51是用c语言做为程序编程的语言 ——我对基本基础 ...
- C51单片机中data、idata、xdata、pdata的区别
C51单片机中data.idata.xdata.pdata的区别 data: 固定指前面0x00-0x7f的128个RAM,可以用acc直接读写的,速度最快,生成的代码也最小. idata: 固定指前 ...
- C51单片机头文件和启动文件
STARTUP.A51//启动文件. 清理RAM.设置堆栈等.即执行完start.a51后跳转到.c文件的main函数 <reg51.h> //特殊寄存器的字节地址和位地址,sfr定义字 ...
随机推荐
- 在Linux下搭建SVN服务器
svn不仅仅可以用于程序开发,还可以做很多事情,例如备份文档. CentOS下:安装 这样同一台服务器便可以运行多个svnserver了 检查端口 注:如果修改了svn配置,需要重启svn服务 -j ...
- Java 时间架构图
Java 的Calendar,Date,TimeZone,Locale和DateFormat的关系图如下: 说明: milliseconds表示毫秒. milliseconds = "实际时 ...
- MFC+Android模拟器 实现 自动玩“天天爱消除”
朋友用QT做了个自动玩的,觉得有意思,自己也想用MFC做个试试. 模拟器用的BlueStacks.Android SDK带的那个模拟器不知道是不是设置的问题,开游戏很卡. 用MFC建了对话框工程,配置 ...
- BZOJ1769 : [Ceoi2009]tri
将所有点极角排序,建立线段树,线段树每个节点维护该区间内所有点组成的上下凸壳. 对于一个查询,二分查找出相应区间的左右端点,在线段树上得到$O(\log n)$个节点,在相应凸壳上三分查找出与斜边叉积 ...
- MONO 使用重要提示
重要提示:如果要使用mvc这样的框架(网址没有扩展名或扩展名没有正常规律),请一定用Jexus,而不要用apache/nginx等. ASP.NET跨平台初学者要注意: 1.不要开始就用freeBSD ...
- COJ885 LCS???
试题描述 输入两个字符串A.B,输出他们的最长连续公共子串长度. 输入 第一行为一个字符串A. 第二行为一个字符串B. 输出 输出他们的最长连续公共子串长度. 输入示例 ababab bababbab ...
- ARC指南2 - ARC的开启和禁止
要想将非ARC的代码转换为ARC的代码,大概有2种方式: 1.使用Xcode的自动转换工具 2.手动设置某些文件支持ARC 一.Xcode的自动转换工具 Xcode带了一个自动转换工具,可以将旧的源代 ...
- ARC指南3 - @property
本章介绍引入ARC后@property的使用,跟ARC之前的还是很不一样的 一..h和.m文件的变化说明 1.对于.h头文件,主要是将属性定义由retain变为strong @property ( ...
- Shell下的正则表达式 (鸟哥私房菜)
"Open Source" is a good mechanism to develop programs.$ apple is my favorite food.$ Footba ...
- Linux改变文件或目录的访问权限命令
使用 ll 或 ls -l 指令时 第一列会显示出目录下文件的权限 例如∶ -rw-r-r- 横线代表空许可.r代表只读,w代表写,x代表可执行.注意这里共有10个位置.第一个字符指定了文件类型 ...