1、KEY按键应用大全精修订 集团标准化工作小组 #Q8QGGQT-GX8G08Q8-GNQGJ8-MHHGN#KEY按键应用大全KEY(按键)应用大全 技术类别: 需要确认注册邮箱后才能下载,?设计中你是否遇到过这样的问题:你的产品上要求有几十个按键,处理器IO口很少,PCB的面积又有严格限制,或者你要严格控制成本,无法使用象7219那样的扩展芯片,怎么解决这个问题下面有个方法,大家都见过遥控器吧,上面不但有几十个按键,而且功能还挺多什么去抖动,同时按键处理都有了,最最重要的是控制芯片体积小,价格便宜(也就1,2块钱),外围器件少。不过具体实现起来有点小麻烦,这类芯片的信号一般是PPM输出的,通
2、常为了有更远的遥控距离,按键编码调制在一个38k左右的载波上。所以我们不得不再为这个方案多花上1块钱,加一个有烂运放做的低通滤波器,将载波滤除后在接到单片机的IO脚上,由于两个频率相差较多,这个滤波器并不难做。我使用LM324做的。其中有两级低通,一个比较器。当你的示波器上出现一串可爱的几百赫兹的方波时,你的硬件就成功啦。既然只用一条IO就扩展了几十个按键,软件上自然会多费些事,此类芯片发码都是有引导头,同步部分,用户码,键码等部分组成,有三十多个位,具体可参照sc6121资料。下面时一个完整的接收程序,针对的芯片是sc6121,处理器89c51ib_KeyCode0 用户码低位,ib_Key
3、Code1用户码高位,ib_KeyCode2键码,ib_KeyCode3键码的反码*/ The meaning of SysKBMsg is list as following. Program Design:LiBaizhan Ver: Date:2003-3-16*/#include #include sbitKey1 = P10;sbitKey2 = P11;/* Some System Var Pre_Definition Crystal Frequence is */#define TIME_2MS 0X74#define TIME_20MS 0X043B#define KB_INT
4、ERNAL 3 /*Key DBClk Detection Internal */* SysKBMsg define Keyboard Message,it include Single_Click or Double_Click Its bit6bit0 record key_encode and bit 7 record DBClk(1) or SglClk(0) It can record and encode up to 127(27-1) keys No key is press when it is 0 This method did not deal key such as Ct
5、rl_Key or Alt_Key or Shift_Key.etc.*/ /*_*/data unsigned char SysKBMsg=0; /*|7|6|5|4|3|2|1|0|*/ /*| D/S | KB6 | KB5 | KB4 | KB3 | KB2 | KB1 | KB0 |*/data unsigned char KBCounter=0;bitKBCounterStart=0;bitKBCounterStop=0; /*if KeyBoard counter stop then this bit is 1*/bitKBCounterFlag=0; /*Current Cou
6、nter is used by KeyBoard*/void TimerInt0(void) interrupt 1 /*timer 0 interrupt use to record how long key is press*/ TR0=0; if(KBCounterFlag) /*Current Counter is used by KeyBoard*/ if(KBCounterKB_INTERNAL)/*if DBClk Detection is not finish then detect continue*/ KBCounter+; TR0=1; else KBCounter=0;
7、 /*DBClk Detection is finish*/ KBCounterStop=1; void DelayMS(unsigned int dltime); void Init51(void);unsigned char KBKeyPress(void); /*only return what key is press*/ void KBKeyEncode(void); /*encode which key is pressed and DBClk or SglClk*/ void KBStartTimer(unsigned char CntH,unsigned char CntL);
8、/*load counter initial value and start timer*/ void KBStopTimer(void); void KBDealPressKey(void); /*deal key_press message*/void main(void) Init51(); while(1) KBKeyEncode(); /*recored what KeyBoard Msg occure:which key is press and single clk or db clk*/ KBDealPressKey(); /* Delay Time is :(20+17*dl
9、_time)*12/CrystalFrequence(us)*/void DelayMS(unsigned int dltime) unsigned int i; for(i=0;i=1; /接受数据 低-高if(sda) dat|=0x80;count+;if(count=num)if(count=9)dat1=dat; /中断9次后为键盘所按按键的通码(开始位始终为0在第一次中断时右移中忽略)num=20; /使中断可以继续中断11次if(count=20)dat2=dat; /取回第二个通码if(dat1=0xe0 | dat2=0xf0) /第一个通码是0xe0则证明所按按键为功能键,
10、第二个通码是0xf0证明按键结束tempshu=dat1;tempshu+1=dat2; shu+=2; /将所按按键存到缓冲区中ie=0x82; /关闭外部中断并打开内部中断来处理所按按键tr0=1;elsetempshu=dat1;tempshu+1=dat2; shu+=2; /如果shift键被按下则记录与它同时按下的那个键count=0;if(temp0=18 | temp0=89) & (temp2=18 | temp2=89) ) tr0=1; /如果缓冲区中有两个间隔的shift键则证明需要的铵键结束void getkey() interrupt 1 /内部中断0 用来处理缓冲
11、区里的数据unsigned char i=0;tr0=0;th0=0;tl0=0;count=0; /中断记数则0if(temp0=18 | temp0=89) & temp1!=0xf0 ) /shift被按下 for(i=0;i21;i+)if(addshift0=temp1) /搜索shift被按下的表key=addshift1;ie=0x83; /打开外部中断return;else if(temp0=0xe0) /所按下的按键是功能键for(i=0;i80;i+)if(noshift0=temp1) /功能键的通码在缓冲区的第二位key=noshift1;ie=0x83;return;
12、else /普通按键for(i=0;i80;i+)if(noshift0=temp0) /普按键的通码在缓冲区的第一位key=noshift1;ie=0x83;return; for(i=0;i5;i+) temp=0; /*程序效果:按下按键,蜂鸣器响,数码管有相应的键值显示,按下E键继电器关,按下C键继电器开。这与上一程序的功能相同,比上一程序简洁但理解相对困难些。运行平台:51hei单片机学习板*/#include /头文件#include#define uchar unsigned char /宏定义#define uint unsigned intsbit jdq=P35; /位声明
13、,驱动继电器管脚sbit fmq=P34; /位声明,驱动蜂鸣器管脚code uchar table=0x3f,0x06,0x5b,/数码管显示的数值0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71;code uchar key_tab17= /此数组为键盘编码0xed,0x7e,0x7d,0x7b, / 0,1,2,3,0xbe,0xbd,0xbb,0xde, / 4,5,6,7,0xdd,0xdb,0x77,0xb7, / 8,9,a, b,0xee,0xeb,0xd7,0xe7,0xff; / c,d,e,f
14、,uchar l_key=0x00; /定义变量,存放键值uchar l_keyold=0xff; /作为按键放开否的凭证void readkey(); /扫描键盘,获取键值void display(uchar *lp,uchar lc); /显示子函数void delay(); /延时子函数void main() /主函数EA=1; /打开总中断EX0=1; /打开外部中断P0=0xf0; /键值高4位为高电平,低4位为低电平 while(1) display(&l_key,1); /调用显示子函数 if(l_key=14) /是否按下E键,是则关闭继电器 jdq=1; if(l_key=1
15、2) /是否按下C键,是则打开继电器 jdq=0; void key_scan() interrupt 0/外部中断0,0的优先级最高EX0=0; /在读键盘时,关闭外部中断,防止干扰带来的多次中断TMOD&=0xf1; /设置定时器为工作方式1 TH0=0x2e; /设置初值,为12毫秒,十进制值为11776TL0=0x00;ET0=1; /开启定时器中断0TR0=1; /启动定时器计数void time0() interrupt 1 /定时器0的中断函数TR0=0; /关闭定时器0readkey(); /定时12ms后产生中断,调用此函数,读取键值 void readkey() /扫描键盘子函数uchar i,j,key; /定义局部变量j=0xfe; /设定初值key=0xff;for(i=0;i4;i+) / 逐列扫描键盘 P0=j; if(P0&0xf0
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1