单片机5个IO口扫描25个按键的程序,怎么只能扫描到下面5个键 哪个单片机大师会写,5个IO扫描25按键的程序,帮我这个,2...
\u6c42\u57fa\u4e8e8051\u5355\u7247\u673a\u7528C\u8bed\u8a00\u7f16\u5199\u7684\u53cc\u77e9\u9635\u952e\u76d8\u626b\u63cf\u7a0b\u5e8f\uff085\u4e2aIO\u53e3\u63a7\u523625\u4e2a\u6309\u952e\uff09\u6211\u8fd9\u91cc\u6709\u4e00\u4e2a\u7a0b\u5e8f\uff0c
#include
#define rowkey() (~P2)&0x0f//\u952e\u76d8\u8f93\u5165\u7aef
#define OUT P0 //\u6570\u7801\u7ba1\u663e\u793a\u8f93\u51fa\u7aef
unsigned char code TAB[]=
{ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
0x88,0x83,0xC6,0xA1,0x86,0x8E,0x89,0xC7,0xC8,0xC1,
0x8C,0xA3,0xBF,0xFF,0xFF
};
void debouncer()
{ int i;
for(i=0;i<2400;i++);
}
void scanner()//\u952e\u76d8\u626b\u63cf\u7a0b\u5e8f
{ unsigned char data row,col;
unsigned char data scan;
unsigned char data keyin;
scan=0xef;
for(row=0;row<4;row++)
{ P2=scan;
keyin=rowkey();
debouncer();
if(keyin!=0)
{ for(col=0;col<4;col++)
{ keyin>>=1;
if(CY)
{ OUT=TAB[col*4+row];//\u6570\u7801\u7ba1\u663e\u793a
break;
}
}
}
scan=(scan<<1)|0x01;
}
}
void main()
{ while(1)
{ scanner();
}
}
\u8fd9\u4e2a\u7535\u8def\u590d\u6742\uff0c\u800c\u4e14\uff0c\u6269\u5145\u51fa\u6765\u7684\u6309\u952e\u6570\u76ee\uff0c\u5e76\u4e0d\u591a\u3002
4*4\uff0c\u867d\u7136\u53ea\u6709 16\u4e2a\u6309\u952e\u3002
\u8ba4\u771f\u7f16\u7a0b\uff0c\u5c31\u53ef\u4ee5\u5b9e\u73b0 31 \u4e2a\u6309\u952e\u7684\u6548\u679c\u3002
http://blog.163.com/asm_c/blog/static/24820311320109178210773/
\u53c2\u8003\u3002
本文以循序渐进的思路,引导大家思考如何用最少的IO驱动更多的按键,并依次给出5种方案原理图提供参考。在实际项目中我们经常会遇到有按键输入的需求,但有的时候为了节省资源成本,我们都会选择在不增加硬件的情况下使用最少的控制器IO驱动更多的按键,那么具体是怎么做的呢,下面我们就以用5个IO引脚为例,讲下怎么设计可以实现更多的按键?共有5种设计思路,下面依次介绍。
思路一
首先通常想到的可能是下面这样的设计:
上图形式的按键就是我们通常说的行列式按键,它的驱动思路是这样的:
1. 对IO1、2、3配置为推挽输出,依次只让其中一个输出为0其他输出为1。
2. 对IO4、5进行读操作,根据读出的结果判断哪个按键按下。
例如:配置IO1、2、3为011,读IO4、5,若IO4为0则SW14按下,若IO5为0则SW15按下;
依次的配置IO1、2、3为101,读IO4、5,若IO4为0则SW24按下,若IO5为0则SW25按下;
依次的配置IO1、2、3为110,读IO4、5,若IO4为0则SW34按下,若IO5为0则SW35按下;
思路二
但是我们在不知道行列式按键之前我们肯定是依次将IO口接一个按键到GND或者到VCC,然后去读IO口去判断哪个按键按下,这也是最简单的方法,但是很浪费IO口,下面这种就结合了这种简单方法和行列式的思路,实现了又多增加3个按键,如下图:
这里我们的思路是先依次读IO1、2、3的电平来识别S1、2、3,哪个按键按下,其后的流程和思路一是一样的,这样就可以识别11个按键了。
思路三
按照扫描的思想,某一时刻设置一个IO口为0,其他IO口读,如果有IO口读到0,则有对应按键按下。比如IO1为0,然后读到IO5也为0,那么K15就是按下的。对照这样的思路,我们可以有下面的设计:
这个电路按键识别思路是这样的:
1. 只配置IO1为0,其他IO读,若IO5读到0,则K15按下,若IO4读到0,则K14按下,依次识别K13,K12;
2. 只配置IO2为0,其他IO读,若IO5读到0,则K25按下,若IO4读到0,则K24按下,依次识别K23;
3. 只配置IO3为0,其他IO读,若IO5读到0,则K35按下,若IO4读到0,则K34按下;
4. 只配置IO4为0,其他IO读,若IO5读到0,则K45按下;
思路四
对于思路3我们发现,如果只配置IO5为0,其他IO读,若IO1读到0,则K15按下,若IO2读到0,则K25按下,依次可识别K35和K45。这样就存在重复,那么有么有好的方法,解决这样的重复呢?我们发现,若配置IO1为0,K15按下,电流流向IO1的,若配置IO5为0,同样K15按下,电流是流向IO5的。这样我们就可以通过区分电流的流向来避免重复。于是就有了下图的设计:
这样就可以避免重复,IO5为0时,按K15,IO1是读不到0的。那么怎样设计,IO5为0时对应一个按键按下IO1为0呢?如是就有人想到下面的设计:
这个电路按键识别思路是这样的:
1. 只配置IO1为0,其他IO读,若IO5读到0,则K51按下,若IO4读到0,则K41按下,依次识别K31,K21;
2. 只配置IO2为0,其他IO读,若IO5读到0,则K52按下,若IO4读到0,则K42按下,依次识别K32,K21';
3. 只配置IO3为0,其他IO读,若IO5读到0,则K53按下,若IO4读到0,则K43按下,依次识别K32’,K31';
4. 只配置IO4为0,其他IO读,若IO5读到0,则K54按下,若IO4读到0,则K43’按下,依次识别K42’,K41';
5. 只配置IO5为0,其他IO读,若IO4读到0,则K54’按下,若IO3读到0,则K53’按下,依次识别K52’,K51'。
思路五
很多人可能认为思路四已经识别20个按键了,但是真的就没有其他方法了吗?不要忘了,我们还没有将思路二你介绍的那种最简单的方法结合进去,于是又可以多5个按键,如下图:
这样我们可以先识别K01、K02、K03、K04、K05,若没有按键按下然后再和思路四的设计一样去识别其他按键。但这样存在一个问题,如果IO1配置为0,IO5读到0,那么怎么知道是K51按下还是K05按下呢,这里只需要在程序里做下判断,先判断下是不是K05按下,若不是就是K51,因为按键K01、K02、K03、K04、K05在5个IO口都为读取的情况下,就可以识别,不需要扫描识别处理,相当于这5个按键优先级高与其他按键。
总结
综合上述,5个IO口最多可以识别25个按键,思路五程序上处理比较麻烦,若实际中只按思路四设计,也可识别20个按键,那么如果有N个IO口可识别多少按键呢?这里给出如下公式:
假设有N个IO口按照思路三可以识别N*(N-1)/2个;
按照思路四可识别N*(N-1)个;
按照思路5可以识别N*(N-1)+N个。
最后再说下,如果实际设计时,还是按思路四设计好,软件也没那么麻烦。如果是你的话你会选择哪种方法呢?你还有没有其他的设计方法呢?
把读出按键的程序,单独写,用位操作指令,就比较清晰。
绛旓細1. 鍙厤缃甀O1涓0锛屽叾浠朓O璇伙紝鑻O5璇诲埌0锛屽垯K15鎸変笅锛岃嫢IO4璇诲埌0锛屽垯K14鎸変笅锛屼緷娆¤瘑鍒獽13锛孠12锛2. 鍙厤缃甀O2涓0锛屽叾浠朓O璇伙紝鑻O5璇诲埌0锛屽垯K25鎸変笅锛岃嫢IO4璇诲埌0锛屽垯K24鎸変笅锛屼緷娆¤瘑鍒獽23锛3. 鍙厤缃甀O3涓0锛屽叾浠朓O璇伙紝鑻O5璇诲埌0锛屽垯K35鎸変笅锛岃嫢IO4璇诲埌0锛屽垯K34鎸変笅锛...
绛旓細鎴戣繖閲屾湁涓涓▼搴忥紝include<reg51.h> define rowkey() (~P2)&0x0f//閿洏杈撳叆绔 define OUT P0 //鏁扮爜绠℃樉绀鸿緭鍑虹 unsigned char code TAB[]= { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x89,0xC7,0xC8,0xC1,0x8C,0xA3,...
绛旓細4*4锛岃櫧鐒跺彧鏈 16涓寜閿銆傝鐪熺紪绋嬶紝灏卞彲浠ュ疄鐜 31 涓寜閿殑鏁堟灉銆俬ttp://blog.163.com/asm_c/blog/static/24820311320109178210773/ 鍙傝冦
绛旓細鍋囪 5*5閿洏 鍏25涓寜閿 鍗犵敤51鍗曠墖鏈 10涓狪O鍙 鎵弿鐨勬柟寮 涓鑸娇鐢ㄥ畾鏃舵壂鎻忔柟寮忥紝鍦ㄥ畾鏃朵腑鏂噷闈㈡墽琛鎸夐敭鎵弿鎿嶄綔銆傚彲鍏堝皢绗竴琛岀殑IO鍙g疆0 鍐嶆壂鎻忓垪鐨5涓狪O鍙鐪嬪摢涓负0 涓0 鐨勫氨璇存槑璇ヤ綅缃寜閿鎸変笅 鍐 灏嗙浜岃鐨処O缃0 鍐嶉噸澶嶄笂闈㈢殑鍒ゆ柇 渚濇鎵弿鍓╀綑涓変釜 褰撶劧瑕佸仛寰楀ソ鐐圭殑璇濆氨瑕佸姞涓...
绛旓細鎸夐敭鎵弿 涓鑸寜閿殑妯″紡閮戒负琛屽垪鎵弿妯″紡 鍋囪 5*5閿洏 鍏25涓寜閿 鍗犵敤51鍗曠墖鏈 10涓狪O鍙 鎵弿鐨勬柟寮 涓鑸娇鐢ㄥ畾鏃舵壂鎻忔柟寮忥紝鍦ㄥ畾鏃朵腑鏂噷闈㈡墽琛屾寜閿壂鎻忔搷浣溿傚彲鍏堝皢绗竴琛岀殑IO鍙g疆0 鍐嶆壂鎻忓垪鐨5涓狪O鍙鐪嬪摢涓负0 涓0 鐨勫氨璇存槑璇ヤ綅缃寜閿鎸変笅 鍐 灏嗙浜岃鐨処O缃0 鍐嶉噸澶嶄笂闈㈢殑鍒ゆ柇...
绛旓細CH451鏄竴涓泦鎴愮殑鏁板瓧鏄剧ず鍜岄敭鐩鎵弿椹卞姩鍣ㄥ拰澶氬姛鑳藉鍥磋姱鐗囄糚鐩戞帶銆 CH451鍐呯疆RC鎸崱鐢佃矾鍙互鍔ㄦ侀┍鍔8涓垨64涓暟鐮佺LED鍙戝厜绠★紝鍏锋湁BCD璇戠爜鍣紝闂儊锛岀Щ浣嶇瓑鍔熻兘;鑰岄敭鐩橈紝涔熷彲鐢ㄤ簬鎵弿64涓寜閿; CH451鍙互閫氳繃涓茶鎺ュ彛绾ц仈鍒颁笌寰帶鍒跺櫒浜ゆ崲鏁版嵁;骞舵彁渚涗笂鐢靛浣嶅拰鐪嬮棬鐙楀姛鑳斤紝濡傜洃娴嬨傦紙涓锛夊唴缃珮...
绛旓細4*4璺5*5鐨勫熀鏈被浼肩殑 瀵圭潃5*5鏀逛笅灏卞ソ浜 涓鑸彲浠ユí鍚戝拰绾靛悜涓や釜瑙掑害鏉ョ湅锛屼竴涓‖浠惰皟鍚戯紝妯悜浼氱敤涓涓狪O鍙锛岀旱鍚戜細鐢ㄤ竴涓狪O鍙o紝涓や釜寰幆锛屼綘渚濇牱鍖栬懌鑺︼紝绋嶆敼鏀逛笅灏卞彲浠ヤ簡銆傘傞殢渚跨粰浣犱竴涓蒋浠讹紝鍏跺疄骞朵笉鏄槸浣犳兂鍚戠殑锛岃繖涓鏍规嵁纭欢鑱旀帴瀹氱殑銆傘備竴鑸富瑕佹槸鏍规嵁鑱旀帴鐨処O鍙i夋嫨銆侀夐氱數骞...
绛旓細濡傛灉涓涓8浣嶇殑ADC妯″潡锛岃璁捐鎴10涓寜閿锛屽氨鏄皢8浣岮DC婊″255绛夊垎鎴10浠斤紝娌′唤涔嬮棿鏈夊ぇ绾25涓宸硷紝姣斿涓涓寜閿寜涓嬬殑ADC鍊煎湪25卤11鐨勪綅缃紝閭d箞瀹冧复杩戠殑鎸夐敭灏辨槸50卤11鐨勪綅缃傚搴旂殑璇嗗埆杩欎簺鍊硷紝灏卞彲浠ヨ瘑鍒偅涓寜閿寜涓嬩簡銆傚綋鐒朵负浜嗘姉骞叉壈寮猴紝鏈濂界瓑鍒嗙殑鏁拌灏戯紝8浣嶇殑璇濈瓑鍒嗘渶濂戒笉瑕佽秴杩8...
绛旓細浠庡浘涓彲浠ョ湅鍑猴紝浣跨敤浜12涓簩鏋佺鍜16涓寜閿锛屾鏂规硶璇嗗埆鎸夐敭杩囩▼濡備笅锛1. 鍏堝皢3涓狪O鍙閮介厤缃垚1锛岀浉褰撲簬涓婃媺杈撳叆锛岀劧鍚庤鍙朓O鐨勫硷紝鍙3涓狪O鐨勫间负闈炲叏1锛屽氨璇存槑鎸夐敭BT01~BT07鏈夋寜閿寜涓嬶紝濡傛灉璇诲彇鍊煎叏涓1锛屽垯杩涜涓嬩竴姝鎵弿璇嗗埆銆2. 渚濇鐨勮缃叾涓竴涓狪O鍙d负0锛屽叾浠栦袱涓狪O鍙h锛屾牴鎹...
绛旓細灏辩畻浣犵殑25涓缁х數鍣ㄥ叏寮锛5V鐨勭户鐢靛櫒鏈澶х殑宸ヤ綔鐢垫祦涔熶笉杩囨槸60mA,25涓户鐢靛櫒鏈澶氬氨 1.5A鐨勭數娴侊紝浣犵敤20A鐨勫紑鍏崇數婧愶紝鎬庝箞鐫涔熶笉鍙兘鐢靛帇涓嶅鐨勶紝鍐典笖锛岃兘宸ヤ綔鍦5V鐨勮姱鐗囷紝鑲畾鑳藉伐浣滃湪4V浠ヤ笂锛屽洜涓虹幇鍦ㄧ殑鑺墖澶氭槸CMOS鐨勩傚簲璇ヤ笉鏄户鐢靛櫒鐨勯棶棰樸傚缓璁綘濡備笅姝ラ妫鏌ワ細鐢ㄤ竾鐢ㄨ〃鐨勭數娴佹。锛屾祴璇曞紑鍏崇數婧愬埌...