视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
PS2键盘C51例程
2025-09-29 04:45:58 责编:小OO
文档
/*------------------------------------

PS2键盘外部INT1中断服务程序

原创: HotPower@126.com

------------------------------------*/

#include"reg51.h"

#define unsigned char uchar

#define DEFPS2PUSHCOUNT 100 //长压最大时间

//定义接口

sbit PS2CLOC=P3^3;

sbit PS2DATA=P3^5;

enum PS2B //枚举

{

uchar PS2KeyTemp; //键盘缓冲区

uchar PS2KeyExtFlage; // 键释放/扩展键标志(小键盘只有回车键)

uchar PS2KeyPopError; //错误

uchar PS2KeyCount; //脉冲计数

uchar PS2KeyVal; //键值值1~20或0x80+(1~20)

uchar PS2KeyPushCount;//长压键计数器清零

uchar PS2KeyMessage;//存键值

}PS2Buffers;

//======================================================

//

void main(void)

{

PS2Buffers.PS2KeyCount == 0;

while(1)

{

;

}

}

//=======================================================

//PS2键盘外部INT1中断服务程序

void int1proc() interrupt IE1_VECTOR using 1

{

uchar i, key;

code unsigned char PS2TAB[] = {//20键PS2小键盘键码表

0x70,//0

0x69,//1

0x72,//2

0x7a,//3

0x6b,//4

0x73,//5

0x74,//6

0x6c,//7

0x75,//8

0x7d,//9

0x05,//F1

0x06,//F2

0x04,//F3

0x0c,//F4

0x03,//F5

0x0b,//F6

0x5a,//Enter

0x76,//Esc

0x66,//Bksp

0x71//KP.

};

if (PS2Buffers.PS2KeyCount == 0) //PS2起始位测试

{

if (!PS2CLOCK && !PS2DATA) //低电平是起始位

{

if (PS2Buffers.PS2KeyExtFlage != 0xf0)

{

PS2Buffers.PS2KeyTemp = 0;

PS2Buffers.PS2KeyExtFlage = 0;

PS2Buffers.PS2KeyPopError = 0;

}

PS2Buffers.PS2KeyCount ++;//脉冲计数

}

else PS2Buffers.PS2KeyPopError = 0xeb;//置键起始位错误号0xeb

}

else if (PS2Buffers.PS2KeyCount < 9) //PS2数据位

{

key = PS2Buffers.PS2KeyTemp;//取键盘缓冲区移位数据

key >>= 1;

if (PS2DATA) key |= 0x80;

PS2Buffers.PS2KeyTemp = key;

PS2Buffers.PS2KeyCount++;//脉冲计数

}

else if (PS2Buffers.PS2KeyCount == 9) //PS2数据奇校验

{

ACC = PS2Buffers.PS2KeyTemp;//取键盘缓冲区移位数据(C51取偶校验位)

if (P != PS2DATA) PS2Buffers.PS2KeyCount ++;//脉冲计数

else

{

PS2Buffers.PS2KeyPopError = 0xec;////置键奇校验位错误号0xec

PS2Buffers.PS2KeyCount = 0;//脉冲计数归零

}

}

else if (PS2Buffers.PS2KeyCount == 10) //停止位

{

key = PS2Buffers.PS2KeyTemp;//取键盘缓冲区移位数据

PS2Buffers.PS2KeyCount = 0;//脉冲计数归零

if (PS2DATA) //高电平是停止位

{

if (key == 0xe0) //本次是扩展键

{

PS2Buffers.PS2KeyExtFlage = 0xe0;//置扩展键标志(小键盘只有回车键)

}

else if (key == 0xf0) //本次是键断码,键释放

{

PS2Buffers.PS2KeyExtFlage = 0xf0;//置键释放标志

}

else //本次必为键值

{

if ((key == 0xaa) || (key == 0xfa))

PS2Buffers.PS2KeyPushCount = 0;//长压键计数器清零

else

{

PS2CLOCK = 0;//阻止PS2键盘立即回送数据

PS2Buffers.PS2KeyPopError = 0xaa;//出错码

for (i = 0; i < 20; i++)

{

if (key == (PS2TAB[i])) //搜索

{

key = i + 1;

if (PS2Buffers.PS2KeyExtFlage == 0xf0)

{

key |= 0x80;//键释放

PS2Buffers.PS2KeyPushCount = 0;//长压键计数器清零

PS2Buffers.PS2KeyMessage = key;//存入当前键值并执行命令

}

else

{

if (key != PS2Buffers.PS2KeyVal) //换了一个键

{

PS2Buffers.PS2KeyPushCount = 0;//长压键计数器清零

PS2Buffers.PS2KeyMessage = key;//存入当前键值并执行命令

}

else //未换键

{

PS2Buffers.PS2KeyPushCount ++;//长压键计数器计数

if (PS2Buffers.PS2KeyPushCount > DEFPS2PUSHCOUNT) //长压时间到

{

PS2Buffers.PS2KeyMessage = key | 0x40;//存入当前键值并执行命令

PS2Buffers.PS2KeyPushCount = 0;//长压键计数器清零

}

}

}

PS2Buffers.PS2KeyVal = key;//存入当前键值值1~20或0x80+(1~20)

PS2Buffers.PS2KeyTemp = 0;//键码移位记录器

PS2Buffers.PS2KeyExtFlage = 0;//扩展键标志

PS2Buffers.PS2KeyPopError = 0;//键释放标志或出错码

break;

}

}

//如果出错长压键计数

if (PS2Buffers.PS2KeyPopError) PS2Buffers.PS2KeyPushCount = 0;器清零

PS2CLOCK = 1;//释放PS2时钟总线

}

}

}

else PS2Buffers.PS2KeyPopError = 0xed;//置停止位错误号0xed

}

else PS2Buffers.PS2KeyCount = 0;//PS2键盘出错

}下载本文

显示全文
专题