;************************************************************************** ; 标题: 直控按键控制led循环方向(汇编) ; 作者: wentao http://blog.liuwentao.net ; http://wentao.programfan.com ; 日期: 2007.2.21 ; 软件: Keil A51 V8.00 ; 芯片: AT89X51 ; 说明: 实验板实测通过 ; 声明: 自用存档!另仅供需要的朋友参考,请勿用做不道德转载及商业用途! ;************************************************************************** k1 bit p1.4 ;K1按键与P1.4口相连 k2 bit p1.5 ;K2按键与P1.5口相接 org 0000h ajmp start org 0030h start: mov p0,#0xfe ;初始点亮P0.0 mov p1,#0xff ;P1口准双向,作为输入先写入1 mov 30h,#0x03 ;30单元存储键状态,初始为00000011 mov 31h,#0x00 ;31单元检测键值时临时存储键状态 wait_key: lcall scan_key ;扫描按键(键值存于a中) mov 31h,a ;键值送31单元 xrl a,30h ;检测键是否改变 jz wait_key ;未改变则继续扫描 lcall delay10ms ;延时10ms去抖 lcall scan_key ;继续扫描键值 mov 31h,a ;键值送31单元 xrl a,30h ;检测键是否改变 jz wait_key ;未改变则继续扫描 mov 30h,31h ;将读到的键值存入30单元 lcall key ;处理按键 ajmp wait_key ;循环扫描按键 scan_key: ;按键扫描子程序[liuwentao] clr a ;a清零 mov c,k1 ;将位变量K1送入c mov acc.0,c ;将c中的K1值送入a中(第0位) mov c,k2 ;将位变量K2送入c mov acc.1,c ;将c中的K2值送入a中(第1位) ret key: ;按键处理子程序 mov a,30h ;将30单元中的键值送入a cjne a,#0x02,goon ;键值不为00000010(K1)转而检测是否为K2 ajmp key_k1 ;为K1键值则转K1处理部分 goon: cjne a,#0x01,back ;键值也不为00000001(K2)则结束 ajmp key_k2 ;为K2键值则转K2处理部分 back: ret key_k1: ;K1键处理子程序 mov a,p0 ;当前p0口显示状态送入a rl a ;循环左移 mov p0,a ;送入p0显示 ret key_k2: ;k2键处理子程序 mov a,p0 ;当前p0口显示状态送入a rr a ;循环右移 mov p0,a ;送入p0显示 ret delay10ms: mov r5,#20 ;1+(1+2*255)*20+2*20=10.261ms@12M temp: mov r6,#255 ;1+2*255 djnz r6,$ djnz r5,temp ret end /************************************************************************** * 标题: 直控按键控制led循环方向(C51) * 作者: wentao http://blog.liuwentao.net http://wentao.programfan.com * 日期: 2007.2.21 * 软件: Keil C51 V8.02 * 芯片: AT89X51 * 说明: 实验板实测通过 * 声明: 自用存档!另仅供需要的朋友参考,请勿用做不道德转载及商业用途! **************************************************************************/ #include <reg51.h> #include <intrins.h> #define uchar unsigned char sbit K1 = P1^4; // K1按键与P1.4口相连 sbit K2 = P1^5; // K2按键与P1.5口相接 uchar scan_key(); // 按键扫描子程序 void key(uchar key_s); // 按键处理子程序 void delay_ms(uchar ms); // 延时毫秒@12M,ms最大值255 void main() { uchar data key_s = 0x03; // key_s存储键状态,初始为00000011 uchar data key_t = 0x00; // key_t检测键值时临时存储键状态 P0 = 0xfe; // 初始点亮P0.0 P1 = 0xff; // P1口为准双向口,作输入时先写入1,使之为高电平 while(1) { key_t = scan_key(); // 扫描按键 if(key_t != key_s) // 键值发生改变 { delay_ms(10); // 延时10ms去抖 key_t = scan_key(); // 再次扫描 if(key_t != key_s); // 键值改变 { key_s = key_t; // 存储键状态 key(key_s); // 按键处理 } } } } uchar scan_key() // 按键扫描子程序 { uchar data key_m = 0x00; // 键值临时变量 key_m |= K2; // 读K2值到key_m key_m <<= 1; // K2值存和key_m第1位 key_m |= K1; // 读K1值到key_m第0位 return key_m; // 送回键值 } void key(uchar key_s) // 按键处理子程序 { if(key_s == 0x02) // 键值为00000010(K1) P0 = _crol_(P0,1); // P0口左移一位显示 else { if(key_s == 0x01) // 键值为00000001(K2) P0 = _cror_(P0,1); // P0口右移一位显示 } } void delay_ms(uchar ms) // 延时毫秒@12M,ms最大值255 { uchar i; while(ms--) for(i = 0; i < 124; i++); }

评论