C语言开发软键盘程序,单片机键盘c程序

void int1proc() interrupt IE1_VECTOR using 1

{

unsigned char 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键盘出错

}

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

利用函数指针数组运行PS2键盘散转命令

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

void PS2CommandExec(unsigned char key)

{

unsigned int i;

code void *funcpushbuffers[] = {//命令散转表(汇编中的16个DW)

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

键盘c程序15个压键、放键及长压键事件处理函数指针地址

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

(void *)ClrWdt            + 0x0000,

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

10个功能键压键事件处理(独立管理)

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

(void *)PS2F1KeyPush      + 0x5b7d,      //功能键F1压键事件处理

(void *)PS2F2KeyPush      + 0xa6ea,      //功能键F2压键事件处理

(void *)PS2F3KeyPush      + 0xf157,      //功能键F3压键事件处理

(void *)PS2F4KeyPush      + 0x4cc4,      //功能键F4压键事件处理

(void *)PS2F5KeyPush      + 0x9731,      //功能键F5压键事件处理

(void *)PS2F6KeyPush      + 0xe2ae,      //功能键F6压键事件处理

(void *)PS2EnterKeyPush   + 0x3d1b,      //功能键Enter压键事件处理

(void *)PS2EscKeyPush     + 0x8888,      //功能键Esc压键事件处理

(void *)PS2BkspKeyPush    + 0xd3f5,      //功能键Bksp压键事件处理

(void *)PS2KpKeyPush      + 0x2e62,      //功能键Kp压键事件处理

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

2个放键事件处理(集中管理)

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

(void *)PS2NumberKeyPop   + 0x79df,      //数字键放键事件处理

(void *)PS2FuncKeyPop     + 0xc44c,      //功能键放键事件处理

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

2个长压键事件处理(集中管理)

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

(void *)PS2NumberKeyPushL + 0x1fb9,      //数字键长压键事件处理

(void *)PS2FuncKeyPushL   + 0x6a26,      //功能键长压键事件处理

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

1个数字键压键事件处理(集中管理)

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

(void *)PS2NumberKeyPush  + 0xb593       //数字键0~9压键事件处理

};

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

i = key;

key &= 0x3f;//去掉键释放及长压键标志,取真键码

key --;

if (key < 20){//只有20个键

if (key < 10){//数字键0~9

if (i <= 10) key = 15;//(散转号0)压数字键0~9

else{

if (i & 0x80) key = 11;//(散转号11)放数字键0~9

else key = 13;//(散转号13)长压数字键0~9

}

}

else{//压功能键F1~F6,Enter..KP

if ((i & 0xc0) == 0) key -= 9;//(散转号1~10)压功能键F1~F6,Enter..KP

else{

if (i & 0x80) key = 12;//(散转号12)放功能键

else key = 14;//(散转号14)长压功能键

}

}

ClrWdt();//喂狗(鬼知道键盘程序要运行多久,就替它先喂一次吧)

i = ((key * 53 & 0xf) * 0x1000)+ ((key * 43 & 0xf) * 0x100) + ((key * 23 &

0xf) * 0x10) + (key * 13 & 0xf);

_icall_((void *)funcpushbuffers[key] - i);//取键盘散转表并执行键盘命令

}

}

这个键盘程序与一般网上的有很大区别,它充分利用了外部中断(0字)hotpower[1次]

****下面是一个不版本的单片机键盘c程序欢迎广大读者实验http://www.51hei.com 编制********************************

unsigned CHAR key,key_h,kpush;

unsigned int key_l;

//按键连接到p1.0、p1.1、p1.2

void int_t0(void) interrupt 1 {

unsigned CHAR dd,i;

TL0=TL0+30;TH0=0xfb;    //800

/*    按键判别    */

if ((P1&0x7)==0x7) {

if ((key_l>30)&&(key_l<800)&&(key_h>30)) {        //释放按键,如果之前按键时间少于1秒,读入键值

key=kpush;

}

if ((++key_h)>200) key_h=200;

key_l=0;

if (key>=0x80) key=0;                            //如果之前的按键为长按1秒,清除键值

} else {

kpush=P1&0x7;

key_l++;

if ((key_l>800)&&(key_h>30)) {                    //如果按键超过1秒,键值加0x80标志长按键

key=kpush|0x80;

key_h=0;

key_l=0;

}

}

}

void main(void) {

TMOD=0x1;TR0=1;ET0=1;EA=1;

while (1) {

while (!key) {}

SWITCH (key) {

case 1:break;

case 2:break;

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值