原创 8个IO接36个按键(没有用二极管)--键扫描程序

2006-12-30 01:44 5296 12 12 分类: MCU/ 嵌入式
note.gif8个IO接36个按键(没有用二极管)--键扫描程序(4916字)hotpower2004-8-8 11:22:54[148次]

showimg.asp?id=11605
/*
备注: 这张图是由网友fsaok提供的.
*/
HotPower 发表于 2004-8-6 20:30 侃单片机 ←返回版面 举报该贴

#include "REG52.h"//不知为何发帖不能用尖括弧?????
#include "intrins.h"//不知为何发帖不能用尖括弧?????


sbit Row0 = P1^0;
sbit Row1 = P1^1;
sbit Row2 = P1^2;
sbit Row3 = P1^3;
sbit Col0 = P1^4;
sbit Col1 = P1^5;
sbit Col2 = P1^6;
sbit Col3 = P1^7;

unsigned char KeyScan(void);

void main(void)
{
KeyScan();
while(1);
}

unsigned char KeyScan(void)
{
unsigned char key, temp;
unsigned char code keytab[] = {//键码表
//键值,//点,键名 键号
0x81,//07,key1 00
0x41,//06,key2 01
0x21,//05,key3 02
0x11,//04,key4 03

0x82,//17,key5 04
0x42,//16,key6 05
0x22,//15,key7 06
0x12,//14,key8 07

0x84,//27,key9 08
0x44,//26,key10 09
0x24,//25,key11 0A
0x14,//24,key12 0B

0x88,//37,key13 0C
0x48,//36,key14 0D
0x28,//35,key15 0E
0x18,//34,key16 0F

0x03,//01,key17 10
0x06,//12,key18 11
0x0c,//23,key19 12
0x05,//02,key20 13
0x09,//03,key21 14
0x0d,//13,key22 15

0xc0,//67,key23 16
0x60,//56,key24 17
0x30,//45,key25 18
0xa0,//57,key26 19
0x50,//46,key27 1A
0x90,//47,key28 1B

/*
0x01,//G0,key29 1C
0x02,//G1,key30 1D
0x04,//G2,key31 1E
0x08,//G3,key32 1F
0x10,//G4,key33 20
0x20,//G5,key34 21
0x40,//G6,key35 22
0x80,//G7,key36 23
*/
0//退出
};
P1 = 0xff;//释放键盘
_nop_();//延时
key = P1;//测试独占键(与GND连接)
key = ~key;//取反,变为正逻辑
if (key) {//有独占键压下,键码28~35,键key29..key36
temp = 35;//最后一个独占键key36
do {
if (key >= 0x80) break;//有独占键压下,退出测试
key <<= 1;//测试下一独占键
temp --;//键号-1
}
while(key);//未测完继续
if (key != 0x80) key = 0xff;//多个独占键压下,出错键码0xff
else key = temp;//得到键码28~35,键号key29~key36.
}
else {//测试组合键,键码0~27
temp = 0x01;//实为从P1_1测起,到P1_7测完
do {//只需扫描7次!!!
temp <<= 1;//继续扫描下一位
P1 = ~temp;//发送某位低电平
_nop_();//延时
key = P1;//接收键盘数据
key = ~key;//取反,变为正逻辑
}
while((temp < 0x80) && (key == temp));//测到P1_6或有键压下结束
if (key == temp) key = 0xff;//无键压下,键码0xff
else {//有组合键压下
temp = 0;//初始键号
while(keytab[temp] && (key != keytab[temp])) temp ++;//查键值表
if (temp >= 28) temp = 0xff;//查无此组合键,出错键码0xff
else key = temp;//得到组合键码0~27,键key1~key28.
}
}
return key;//返回键码0~35或出错码0xff
}




相关帖子>>>:
note.gif8个IO接36个按键(没有用二极管)--键扫描程序

  • note.gif保存(0字)无行风[7次]2004-8-8 11:37:01

  • note.gifIO键盘扫描次数之分析(4086字)hotpower[52次]2004-8-8 11:58:10
    IO键盘扫描次数之分析
    hotpower 发表于 2003-9-7 06:13 EMC 单片机 ←返回版面 举报该贴

    1。在“独占式”键盘中,若采用管脚中断,故在主程序中不需扫描。
    当然若非中断方式,则N个键需N次扫描(不算一次读入)
    2。在“双向双次”键盘“扫描”技术中,由于行列扫描变换一次,故只需2次。
    3。在行扫描中,可分为行列式和组合式
    在“行列式”键盘中(不算双向),扫描次数为行列中的最小值。
    在“组合式”键盘中,最小扫描次数为IO个数-1。
    即:四线6键,五线10键,六线15键,七线21键,八线28键
    在四线 6键中,扫描次数为3次
    在五线10键中,扫描次数为4次
    在六线15键中,扫描次数为5次
    在七线21键中,扫描次数为6次
    在八线28键中,扫描次数为7次
    例:在八线28键中,设8线K1..K8
    组合为:K1K2,K1K3,K1K4,K1K5,K1K6,K1K7,K1K8
    K2K3,K2K4,K2K5,K2K6,K2K7,K2K8
    K3K4,K3K5,K3K6,K3K7,K3K8
    K4K5,K4K6,K4K7,K4K8
    K5K6,K5K7,K5K8
    K6K7,K6K8
    K7K8
    八线最大扫描:发K1,收K2,K3,K4,K5,K6,K7,K8
    发K2,收K1,K3,K4,K5,K6,K7,K8
    发K3,收K1,K2,K4,K5,K6,K7,K8
    发K4,收K1,K2,K3,K5,K6,K7,K8
    发K5,收K1,K2,K3,K4,K6,K7,K8
    发K6,收K1,K2,K3,K4,K5,K7,K8
    发K7,收K1,K2,K3,K4,K5,K6,K8
    发K8,收K1,K2,K3,K4,K5,K6,K7
    八线最小扫描:发K1,收K2,K3,K4,K5,K6,K7,K8
    发K2,收K1,K3,K4,K5,K6,K7,K8
    发K3,收K1,K2,K4,K5,K6,K7,K8
    发K4,收K1,K2,K3,K5,K6,K7,K8
    发K5,收K1,K2,K3,K4,K6,K7,K8
    发K6,收K1,K2,K3,K4,K5,K7,K8
    发K7,收K1,K2,K3,K4,K5,K6,K8
    同理:
    四线最小扫描:发K1,收K2,K3,K4
    发K2,收K1,K3,K4
    发K3,收K1,K2,K4
    五线最小扫描:发K1,收K2,K3,K4,K5
    发K2,收K1,K3,K4,K5
    发K3,收K1,K2,K4,K5
    发K4,收K1,K2,K3,K5
    六线最小扫描:发K1,收K2,K3,K4,K5,K6
    发K2,收K1,K3,K4,K5,K6
    发K3,收K1,K2,K4,K5,K6
    发K4,收K1,K2,K3,K5,K6
    发K5,收K1,K2,K3,K4,K6
    七线最小扫描:发K1,收K2,K3,K4,K5,K6,K7
    发K2,收K1,K3,K4,K5,K6,K7
    发K3,收K1,K2,K4,K5,K6,K7
    发K4,收K1,K2,K3,K5,K6,K7
    发K5,收K1,K2,K3,K4,K6,K7
    发K6,收K1,K2,K3,K4,K5,K7
    由此可知:“组合式”键盘扫描次数较多,但相应的键数也越多。

    世上没有“十全十美”的事和物,既然有“矛”,必然能找出“盾”
    “既生瑜,何生亮”???



    * - 本贴最后修改时间:2003-9-7 23:23:31 修改者:hotpower
    * - 修改原因:*



  • note.gif农民对"独占键"与"组合键"的"定义" (1406字)hotpower[53次]2004-8-8 11:59:57
    农民对"独占键"与"组合键"的"定义"
    HotPower 发表于 2004-8-7 09:40 侃单片机 ←返回版面   举报该贴

    农民不懂词汇,只知道瞎起...

    "独占键"key29~key36
    "组合键"key1~key28

    我说的"独占键"实际就是最简单的IO键(一端接地),所谓"独占"意为优先也.
    所以,键扫描应该从它做起. 并且最好定义为"优先键".

    "组合键"非多键组合之意,乃数学中的"组合"也!
    由于它可归结为组合问题而非排列,所以,单键压下是有"理论基础"的,故必能实现.

    本主题的键正如fsaok所述,它应该分2部分考虑.但常用的是"组合键"或"独占键"."独占
    键"+"组合键"一般很少采用.但可以肯定,这种键的编排是非常"经济实用"的,它要比"行列
    键"更好用!只是编程要采用一些"技巧".(当然这是所长极力反对的)

    我为何参与本主题的讨论,主要是本主题非常实用,而且引深一步就可进入动态IO测试问题.
    我想很多人会遇到过MCU烧写成功但IO却是坏的问题吧...


    fsaok: 真不够意思!扔一个图就跑了...农忙还是"秋收起义"???




  • note.gif本图的"多意键"(1250字)hotpower[35次]2004-8-8 12:01:29
     HotPower 发表于 2004-8-7 13:45 侃单片机 ←返回版面   举报该贴

    以key28为例(先抛开那"该死的key29~key36"):

    因为key28"挂接"在col0和col3上,故将产生6对"多意键":
    key1与key4
    key5与key8
    key9与key12
    key13与key16
    key23与key27
    key25与key26

    即同时压下key28及key1与key28及key4是一样的,这是用户不能容忍的!
    但设计使用说明书是您自己写的,定义自然属于自己.
    这样就可设计出key28除那6对"多意键"外的任意组合,当然这就又需要"技巧"了...

    如果您被逼急了,就拆掉那6对"多意键"的一半.铲除"多意键".
    例: 去掉key4,key8,key12,key16,key25,key27.

    这样,key28就实现了"一夫多妻键"而非"多夫多妻键"这种连自己都不晓得的"东西"...

    fsaok所说的多键值:

    key28与key1  编码为: 0x91
    key28与key4  编码为: 0x91(多意键)



  • note.gif关于6次扫描而非8次扫描之瞎说(6次真是瞎说!!!)(816字)hotpower[28次]2004-8-8 12:02:40
    fsaok: 关于6次扫描而非8次扫描之瞎说
    HotPower 发表于 2004-8-7 14:00 侃单片机 ←返回版面   举报该贴

    由于"组合键"扫描时全为1发7收,即
    发P1.1时,P1.0,P1.2~P1.7为收
    ...........................
    发P1.6时,P1.0~P1.5,P1.7为收

    故发P1.0和P1.7这2次扫描肯定是"浪费感情"了...
    因为在这6次扫描时,每次P1.0和P1.7都在接收,故8次扫描是"多情"的...

    设计不能"无情"(漏掉键),但也不能太"多情"了...
    当然,有时"多情总被无情恼".............





    改错!!!!
    应该是7次扫描而非8次扫描,6次将漏掉键P1.0与P1.7的组合

    这次是"无情总被多情恼".............
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
12
关闭 站长推荐上一条 /3 下一条