📄 key_board.s
字号:
.module key_board.c
.area lit(rom, con, rel)
_key_board_table::
.byte 0,1
.byte 2,3
.byte 4,5
.byte 6,7
.byte 8,9
.byte 10,11
.byte 12,13
.byte 14,15
.dbfile E:\democode\key_4\source\lib\key_board.c
.dbsym e key_board_table _key_board_table A[16:16]kc
.area data(ram, con, rel)
.dbfile E:\democode\key_4\source\lib\key_board.c
_KEY_FLAG::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile E:\democode\key_4\source\lib\key_board.c
.dbsym e KEY_FLAG _KEY_FLAG c
_key::
.blkb 1
.area idata
.byte 255
.area data(ram, con, rel)
.dbfile E:\democode\key_4\source\lib\key_board.c
.dbsym e key _key c
.area vector(rom, abs)
.org 4
jmp _int_isr
.area data(ram, con, rel)
.dbfile E:\democode\key_4\source\lib\key_board.c
.area text(rom, con, rel)
.dbfile E:\democode\key_4\source\lib\key_board.c
.dbfunc e int_isr _int_isr fV
.even
_int_isr::
xcall push_lset
.dbline -1
.dbline 22
; /**************************************
; ** Filename: key_board.c
; ** Describe: 矩阵键盘程序
; ** Author : 古欣 www.avrvi.com
; ** Time : 2007-2-15
; **************************************/
;
; #include "..\config.h"
;
; const uint8 key_board_table[]={0,1,2,3,
; 4,5,6,7,
; 8,9,10,11,
; 12,13,14,15};
; //键值可以任意设定,请不要使用0xFF
; //const uint8 key_board_table[]={0,1,2,3,4,5,6,7,8,9,10,11,'A','B','C','D'};
;
; //如果使用中断
; #if KEY_USE_INT==1
; volatile uint8 KEY_FLAG=0,key=0xff; //加 volatile 允许在中断中修改
; #pragma interrupt_handler int_isr:IV_number
; void int_isr(void)
; {
.dbline 23
; KEY_FLAG = 1; //中断中标记已经产生按键中断,由于使用低电平触发方式,不用再考虑防抖问题
ldi R24,1
sts _KEY_FLAG,R24
.dbline 24
; key = key_board_get_key(); //读取键值
xcall _key_board_get_key
sts _key,R16
.dbline -2
L1:
xcall pop_lset
.dbline 0 ; func end
reti
.dbend
.dbfunc e key_int_init _key_int_init fV
.even
_key_int_init::
.dbline -1
.dbline 39
; }
; #endif
;
; /***********************************************************
; ** 函数名称: void key_board_int(void)
; ** 功能描述: 中断脚初始化
; ** 输 入: 无
; ** 输出 : 无
; ** 全局变量: 无
; ** 调用模块:
; ** 说明:输入,并使能内部上拉
; ** 注意:
; **********************************************************/
; void key_int_init(void)
; {
.dbline 40
; KEY_INT_DDR &=~ (1<<KEY_INT);
cbi 0x11,2
.dbline 41
; KEY_INT_RORT |= (1<<KEY_INT);
sbi 0x12,2
.dbline 42
; GICR |= (1<<INT_BIT); //中断允许位,如INT0
in R24,0x3b
ori R24,64
out 0x3b,R24
.dbline -2
L2:
.dbline 0 ; func end
ret
.dbend
.dbfunc e key_board_int _key_board_int fV
.even
_key_board_int::
.dbline -1
.dbline 57
; }
;
; /***********************************************************
; ** 函数名称: void key_board_int(void)
; ** 功能描述: 矩阵键盘扫描初始化
; ** 输 入: 无
; ** 输出 : 无
; ** 全局变量: 无
; ** 调用模块:
; ** 说明:默认初始化为行输出低,列输入,并使能内部上拉
; ** 注意:
; **********************************************************/
;
; void key_board_int(void)
; {
.dbline 58
; KEY_DDR_ROW |= KEY_ROW_ALL; //行输出,低
in R24,0x1a
ori R24,240
out 0x1a,R24
.dbline 59
; KEY_PORT_ROW &=~ KEY_ROW_ALL;
in R24,0x1b
andi R24,15
out 0x1b,R24
.dbline 60
; KEY_DDR_COL &=~ KEY_COL_ALL; //列输入,并使能内部上拉
in R24,0x1a
andi R24,240
out 0x1a,R24
.dbline 61
; KEY_PORT_COL |= KEY_COL_ALL;
in R24,0x1b
ori R24,15
out 0x1b,R24
.dbline 63
; #if BEEP_EN ==1
; BEEP_DDR |= (1<<BEEP_BIT);
sbi 0x11,0
.dbline 64
; BEEP_PORT &=~ (1<<BEEP_BIT);
cbi 0x12,0
.dbline -2
L3:
.dbline 0 ; func end
ret
.dbend
.dbfunc e key_board_get_key _key_board_get_key fc
; key_i -> R20
; temp_key -> R22
.even
_key_board_get_key::
xcall push_gset3
.dbline -1
.dbline 80
; #endif
; }
;
; /***********************************************************
; ** 函数名称: uint8 key_board_get_key(void)
; ** 功能描述: 矩阵键盘扫描并读取键值
; ** 输 入: 无
; ** 输出 : 按键的键值,在key_board_table[]定义,无按键返回0xFF
; ** 全局变量: 无
; ** 调用模块: void key_board_int(void)
; ** 说明:通过预定义#define WAIT_KEY_UP设置等待按键抬起(1),不等待按键抬起(0)
; ** 注意:如果不等待按键抬起,很容易产生粘贴键,注意在程序中处理。
; **********************************************************/
;
; uint8 key_board_get_key(void)
; {
.dbline 81
; uint8 key_i=0,temp_key=0;
clr R20
.dbline 81
clr R22
.dbline 82
; if(HAVE_KEY_DOWN)
in R24,0x19
andi R24,15
cpi R24,15
brne X2
xjmp L5
X2:
.dbline 83
; {
.dbline 87
; #if KEY_USE_INT==0
; Delay100us(1); //使用中断进行扫描不加延时
; #endif
; if(HAVE_KEY_DOWN)
in R24,0x19
andi R24,15
cpi R24,15
brne X3
xjmp L7
X3:
.dbline 88
; {
.dbline 91
;
; #if BEEP_EN ==1
; BEEP_PORT |= (1<<BEEP_BIT); //蜂鸣器响
sbi 0x12,0
.dbline 94
; #endif
;
; temp_key = ( KEY_COL_ALL & KEY_PIN_COL ); //读取键值
in R22,0x19
andi R22,15
.dbline 96
;
; switch(temp_key)
mov R10,R22
clr R11
movw R24,R10
cpi R24,7
ldi R30,0
cpc R25,R30
breq L15
cpi R24,11
ldi R30,0
cpc R25,R30
breq L14
cpi R24,13
ldi R30,0
cpc R25,R30
breq L13
cpi R24,14
ldi R30,0
cpc R25,R30
breq L12
xjmp L10
X0:
.dbline 97
; {
L12:
.dbline 99
; case (KEY_COL_ALL&(~(1<<KEY_COL_0))):
; key_i = 0;
clr R20
.dbline 100
; break;
xjmp L10
L13:
.dbline 102
; case (KEY_COL_ALL&(~(1<<KEY_COL_1))):
; key_i = 1;
ldi R20,1
.dbline 103
; break;
xjmp L10
L14:
.dbline 105
; case (KEY_COL_ALL&(~(1<<KEY_COL_2))):
; key_i = 2;
ldi R20,2
.dbline 106
; break;
xjmp L10
L15:
.dbline 108
; case (KEY_COL_ALL&(~(1<<KEY_COL_3))):
; key_i = 3;
ldi R20,3
.dbline 109
; break;
.dbline 133
;
; // 扩展
; #if PER_COL>4
; case (KEY_COL_ALL&(~(1<<KEY_COL_4))):
; key_i = 4;
; break;
; #endif
; #if PER_COL>5
; case (KEY_COL_ALL&(~(1<<KEY_COL_5))):
; key_i = 5;
; break;
; #endif
; #if PER_COL>6
; case (KEY_COL_ALL&(~(1<<KEY_COL_6))):
; key_i = 6;
; break;
; #endif
; #if PER_COL>7
; case (KEY_COL_ALL&(~(1<<KEY_COL_7))):
; key_i = 7;
; break;
; #endif
;
; default:break;
L10:
.dbline 137
; }//end switch
;
; //翻转,与初始化恰好相反
; KEY_DDR_ROW &=~ KEY_ROW_ALL; //行输入,并使能内部上拉
in R24,0x1a
andi R24,15
out 0x1a,R24
.dbline 138
; KEY_PORT_ROW |= KEY_ROW_ALL;
in R24,0x1b
ori R24,240
out 0x1b,R24
.dbline 139
; KEY_DDR_COL |= KEY_COL_ALL; //列输出,低
in R24,0x1a
ori R24,15
out 0x1a,R24
.dbline 140
; KEY_PORT_COL &=~ KEY_COL_ALL;
in R24,0x1b
andi R24,240
out 0x1b,R24
.dbline 142
;
; NOP(); //等待啊你家安稳定,此步骤不能少
nop
.dbline 144
;
; temp_key = ( KEY_ROW_ALL & KEY_PIN_ROW ); //读取翻转后键值
in R22,0x19
andi R22,240
.dbline 146
;
; switch(temp_key)
clr R23
cpi R22,176
ldi R30,0
cpc R23,R30
breq L21
ldi R24,176
ldi R25,0
cp R24,R22
cpc R25,R23
brlt L24
L23:
cpi R22,112
ldi R30,0
cpc R23,R30
breq L22
xjmp L27
L24:
cpi R22,208
ldi R30,0
cpc R23,R30
breq L20
cpi R22,208
ldi R30,0
cpc R23,R30
brlt L27
L25:
cpi R22,224
ldi R30,0
cpc R23,R30
breq L27
xjmp L27
X1:
.dbline 147
; {
.dbline 150
; case (KEY_ROW_ALL&(~(1<<KEY_ROW_0))):
; // key_i += 0; //加零,直接省掉
; break;
L20:
.dbline 152
; case (KEY_ROW_ALL&(~(1<<KEY_ROW_1))):
; key_i += PER_POW;
subi R20,252 ; addi 4
.dbline 153
; break;
xjmp L27
L21:
.dbline 155
; case (KEY_ROW_ALL&(~(1<<KEY_ROW_2))):
; key_i += PER_POW*2;
subi R20,248 ; addi 8
.dbline 156
; break;
xjmp L27
L22:
.dbline 158
; case (KEY_ROW_ALL&(~(1<<KEY_ROW_3))):
; key_i += PER_POW*3;
subi R20,244 ; addi 12
.dbline 159
; break;
.dbline 183
;
; // 扩展 PER_POW 最大值为8
; #if PER_POW>4
; case (KEY_ROW_ALL&(~(1<<KEY_ROW_4))):
; key_i += PER_POW*4;
; break;
; #endif
; #if PER_POW>5
; case (KEY_ROW_ALL&(~(1<<KEY_ROW_5))):
; key_i += PER_POW*5;
; break;
; #endif
; #if PER_POW>6
; case (KEY_ROW_ALL&(~(1<<KEY_ROW_6))):
; key_i += PER_POW*6;
; break;
; #endif
; #if PER_POW>7
; case (KEY_ROW_ALL&(~(1<<KEY_ROW_7))):
; key_i += PER_POW*7;
; break;
; #endif
;
; default:break;
L26:
.dbline 189
L27:
.dbline 188
; }//end switch
;
; //检测按键抬起
; #if WAIT_KEY_UP==1
; while((KEY_ROW_ALL & KEY_PIN_ROW)!=KEY_ROW_ALL)
in R24,0x19
andi R24,240
cpi R24,240
brne L26
.dbline 192
; ;
; #endif
;
; key_board_int(); //恢复键盘IO口的初时状态
xcall _key_board_int
.dbline 194
;
; }//end if have key
L7:
.dbline 195
; return key_board_table[key_i]; //返回键值
ldi R24,<_key_board_table
ldi R25,>_key_board_table
mov R30,R20
clr R31
add R30,R24
adc R31,R25
lpm R16,Z
xjmp L4
L5:
.dbline 198
; }
; else
; return 0xFF;
ldi R16,255
.dbline -2
L4:
xcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r key_i 20 c
.dbsym r temp_key 22 c
.dbend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -