单片机模拟PS2键盘实现(1)
很多控制项目中会用到小型的工控机,有时还需要用到键盘的部分功能。如果配一个全功能的键盘有些浪费资源,空间也不允许,这时,我们可以用单片机来实现模拟出键盘的部分功能。
小型工控机
常用的键盘有两种接口,PS/2和USB,今天先介绍一下PS/2接口的相关情况。
首先先要弄清楚PS/2的传输协议,然后用单片机管脚直接模拟它的时序就可以了。
从设备发送时序
这是从设备键盘的发送时序,可以看到,每个数据由11个bit组成,1个起始位(0),8个数据位,1个校验位(奇校验)和一个结束位(1);时钟频率控制在10-20K之间,下降沿有效。
从设备接收时序
这是主设备的发送,从设备的接收时序,时序基本和上面的一致,但是要注意,当主设备发送数据时,从设备就不能发送数据。只有当时钟线为高电平时,也就是主设备没有动作,这时从设备才可以发送数据。
熟悉单片机编程的朋友大都了解IIC吧?乍一看,PS/2协议是不是跟IIC很像呢?所以编程也就简单多了。了解时序之后,我们还要知道键盘上字符所对应的"通码"和"断码",按照码表传输对应的字符就可以了。下面就是部分字符的码表:
部分字符码表
如果我们想要给电脑发送一个"G",那么,就先发通码"0x33",再发断码"0xF0"和"0x33"就可以了。
好了,理论的东西先讲到这里,下次,我们结合代码,详细的分析PS/2键盘的实现。
教你玩单片机之矩阵键盘(附程序)
以下所有内容,仅适合新手,大神请绕道。
原理图解析:
组成结构:
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
矩阵键盘扫描原理
方法一:
逐行扫描: 我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。
方法二:
行列扫描: 我们可以通过高四位全部输出低电平,低四位输出高电平。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。
51单片机矩阵键盘实验程序:
使用的IO : 数码管使用P0,键盘使用P3.0、P3.1、P3.2、P3.3
#include<reg51.h>
#define GPIO_DIG P0
#define GPIO_KEY P1
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4; // 138译码器接入端
unsigned char code DIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char KeyValue;
//用来存放读取到的键值
void Delay10ms(); //延时10ms
void KeyDown(); //检测按键函数
void main(void)
{
LSA=0; //给一个数码管提供位选
LSB=0;
LSC=0;
while(1)
{
KeyDown();
GPIO_DIG=DIG_CODE[KeyValue];
}
}
void KeyDown(void)
{
char a=0;
GPIO_KEY=0x0f;
if(GPIO_KEY!=0x0f)//读取按键是否按下
{
Delay10ms();//延时10ms进行消抖
if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
{
//测试列
GPIO_KEY=0X0F;
switch(GPIO_KEY)
{
case(0X07):KeyValue=0;break;
case(0X0b):KeyValue=1;break;
case(0X0d): KeyValue=2;break;
case(0X0e):KeyValue=3;break;
}
//测试行
GPIO_KEY=0XF0;
switch(GPIO_KEY)
{
case(0X70):KeyValue=KeyValue;break;
case(0Xb0):KeyValue=KeyValue+4;break;
case(0Xd0): KeyValue=KeyValue+8;break;
case(0Xe0):KeyValue=KeyValue+12;break;
}
while((a<50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测
{
Delay10ms();
a++;
}
}
}
}
void Delay10ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
相关问答
单片机 4*4按键扫描看不懂第3句key_l=P1& 0xf0;//11100000key_...[最佳回答]key_l=P1&0xf0;//读出高四位,行,检测某行有按键key_l=key_l|0x0f;//把高四位的数据或上0x0fP1=key_l;//把P1口置成输出口(除了有按键的那一...
C51 单片机 按键控制定时闹钟 - 懂得纯粹用51做闹钟,需要有时钟芯片或者内部RTC功能,如果都没有,只通过定时器,你需要不断的给定时器做一些补偿,你要的是代码还是思路?请问还有代码吗
单片机 的独立 键盘 有什么用?很多的嵌入式或者单片机系统中,一般都需要向嵌入式或者单片机系统输入信息的外设,以及嵌入式或者单片机向外输出信息的外设我们常见的显示屏,数码管等就是嵌...
单片机 的按键开关抖动的产生原因,抖动的特点和如何消除抖动 ...件延时去抖(其实是一种忽略)和硬件去抖软件判断:开关闭合——延时——是否还是闭合?——如果是就判定打开,软件解决可以降低成本,但是有时...——...
矩阵 键盘 与 单片机 怎么连接?矩阵键盘是行x列,需要看你矩阵的多少而定,接单片机IO口P0、P1都可以矩阵键盘就是个按键阵列,不需要电源和地,电源和地是接单片机的矩阵键盘是行x列,需要看你...
51 单片机 矩阵 键盘 如何实现两个键同时按下的时候显示其他数字,用c语言程序实现?定义一个按键缓冲区用普通的按键扫描程序,当扫描到有按键按下的时候。按键键的值写入缓冲区。继续扫描直到完成。然后返回缓冲区地址就可以得到多个按键的数...
51 单片机 关于单独按键控制LED灯-ZOL问答6条回答:【推荐答案】刚看你程序,你上电按住就可以了,是你while(1)卡住了按键的扫描了
请问 单片机 怎么用独立按键按一下实现一个功能,按另一个按键实现另一个功能,这个代码要怎么写啊?如果这两个功能都是一个死循环,可以考虑用中断,这样就不必在两个独立的功能中插入按键检测了while(1){while(flag==1){死循环1}while(flag==2){死循环2}}....
单片机 能高电平触发按键吗?1.不可以。2.因为单片机的输入引脚通常是通过电平变化来检测按键的状态,一般情况下是通过低电平触发按键。当按键按下时,引脚的电平会从高电平变为低电平,单...
求解C语言编写的51 单片机 用按键实现 暂停 开启-ZOL问答再次按按键就唤醒单片机};4水位{当水位