;************************************************************************** ; 标题: 直控按键多个键值处理(汇编) ; 作者: wentao http://blog.liuwentao.net ; http://wentao.programfan.com ; 日期: 2007.3.1 ; 软件: Keil A51 V8.00 ; 芯片: AT89X51 ; 说明: 实验板实测通过;可以用多个键 ; 声明: 自用存档!另仅供需要的朋友参考,请勿用做不道德转载及商业用途! ;************************************************************************** key_v equ 30h ;key_v(30单元)存储键值 key_t equ 31h ;key_t(31单元)检测键值时临时存储键值 org 0000h ajmp start start: mov p1,#0xff ;P1口为准双向口,作输入时写入1,使之为高电平 mov p0,#0xff ;关P0口LED mov key_v,#0xff ;初始化键值为ff key: ;键扫描 mov a,p1 ;当前键值送入a mov key_t,a ;存储到临时变量中 xrl a,key_v ;检测键值是否改变 jz key ;未改变则继续扫描 lcall d_10ms ;有键按下则延时10ms消抖 mov a,p1 ;再次读入键值 mov key_t,a ;键值存储到临时变量中 xrl a,key_v ;检测键值是否改变 jz key ;未改变则为抖动继续扫描 mov key_v,key_t ;将最终读到的键值存入key_v lcall key_to ;调用键处理子程序 ajmp key ;循环 key_to: ;按键处理子程序 mov a,key_v ;读入键值 cjne a,#0xef,next ;不是P1.4口键值则查下一个 cpl p0.0 ;P1.4键则取反P0.0 ret next: cjne a,#0xdf,over ;也不是P1.5口键值则结束 cpl p0.1 ;P1.5键则取反P0.1 over: ret d_10ms: mov r5,#20 ;1+(1+2*255)*20+2*20=10.261ms@12M temp1: mov r6,#255 ;1+2*255 djnz r6,$ djnz r5,temp1 ret end /************************************************************************** * 标题: 直控按键多个键值处理(C51) * 作者: wentao http://blog.liuwentao.net http://wentao.programfan.com * 日期: 2007.3.1 * 软件: Keil C51 V8.02 * 芯片: AT89X51 * 说明: 实验板实测通过 * 声明: 自用存档!另仅供需要的朋友参考,请勿用做不道德转载及商业用途! **************************************************************************/ #include <reg51.h> #define uchar unsigned char sbit P00 = P0^0; // 定义P00为P0.0 sbit P01 = P0^1; // 定义P01为P0.1 void key_to(uchar key_s); // 按键处理子程序 void delay_ms(uchar ms); // 延时毫秒@12M,ms最大值255 void main() { uchar data key_v = 0xff; // key_s存储键值,初始为11111111 uchar data key_t = 0x00; // key_t检测键值时临时存储键状态 P1 = 0xff; // P1口为准双向口,作输入时先写入1,使之为高电平 P0 = 0xff; // 关P0口LED while(1) // 循环扫描键值 { key_t = P1; // 读键值到临时变量key_t if(key_t != key_v) // 若键值改变(有键按下) { delay_ms(10); // 延时10ms消抖 key_t = P1; // 再次读键值到key_t if(key_t != key_v) // 若键值改变(经消抖确定有键按下) { key_v = key_t; // 将最终读到的键值存入key_v key_to(key_v); // 调用键处理子程序 } } } } void key_to(uchar key_v) // 按键处理子程序 { if(key_v == 0xef) // 键值为11101111(p1.4) P00 = !P00; // 是P1.4口键按下则取反P0.0口 else { if(key_v == 0xdf) // 键值为11011111(P1.5) P01 = !P01; // 是P1.5口键按下则取反P0.1口 } } void delay_ms(uchar ms) // 延时毫秒@12M,ms最大值255 { uchar i; while(ms--) for(i = 0; i < 124; i++); }

评论