📄 4x4key.s
字号:
.module _4X4key.c
.area text(rom, con, rel)
.dbfile H:\39数码~1\4X4key.c
.dbfunc e delay_ms _delay_ms fV
; i -> R20,R21
; j -> R22,R23
; k -> R16,R17
.even
_delay_ms::
xcall push_gset2
.dbline -1
.dbline 15
; //-----------------------------------------------------------------
; // 名称: 数码管显示4×4 键盘矩阵按键序号
; //-----------------------------------------------------------------
; // 说明: 本例运行时,数码管会显示所按下的任意按键在键盘矩阵上的位置.
; // 扫描程序首先判断按键发生在哪一列,然后判断按键发生在哪一行,
; // 由列号和行号即可得到键盘按键序号.
; //
; //-----------------------------------------------------------------
; #include <iom16v.h>
; #include <macros.h>
; #define uchar unsigned char
; #define uint unsigned int
; //=============================
; void delay_ms(uint k) //毫秒级的延时子函数
; {
.dbline 17
; uint i,j;
; for(i=0;i<k;i++)
clr R20
clr R21
xjmp L5
L2:
.dbline 18
; {
.dbline 19
; for(j=0;j<1140;j++)
clr R22
clr R23
xjmp L9
L6:
.dbline 20
L7:
.dbline 19
subi R22,255 ; offset = 1
sbci R23,255
L9:
.dbline 19
cpi R22,116
ldi R30,4
cpc R23,R30
brlo L6
.dbline 21
L3:
.dbline 17
subi R20,255 ; offset = 1
sbci R21,255
L5:
.dbline 17
cp R20,R16
cpc R21,R17
brlo L2
.dbline -2
L1:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r i 20 i
.dbsym r j 22 i
.dbsym r k 16 i
.dbend
.area lit(rom, con, rel)
_SEG_CODE::
.byte 63,6
.byte 91,'O
.byte 'f,'m
.byte 125,7
.byte 127,'o
.byte 'w,124
.byte 57,94
.byte 'y,'q
.dbsym e SEG_CODE _SEG_CODE A[16:16]kc
.area data(ram, con, rel)
.dbfile H:\39数码~1\4X4key.c
_KeyNo::
.blkb 1
.area idata
.byte 16
.area data(ram, con, rel)
.dbfile H:\39数码~1\4X4key.c
.dbsym e KeyNo _KeyNo c
.area text(rom, con, rel)
.dbfile H:\39数码~1\4X4key.c
.dbfunc e KeyMatrix_Down _KeyMatrix_Down fc
.even
_KeyMatrix_Down::
xcall push_gset1
.dbline -1
.dbline 40
; ;
; }
; }
;
; #define BEEP() PORTD ^= BIT(PD7) //蜂鸣器
;
; //0-9,A-F的数码管段码
; const uchar SEG_CODE[] =
; {
; 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
; 0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71
; };
;
; //当前按键序号,该矩阵中序号范围为0-15,16表示无按键
; uchar KeyNo = 16 ;
;
; //-----------------------------------------------------------------
; // 判断键盘矩阵是否有键按下
; //-----------------------------------------------------------------
; uchar KeyMatrix_Down()
; {
.dbline 42
; //高4位输出,低4位输入,高4位先置0
; DDRB=0xF0;
ldi R24,240
out 0x17,R24
.dbline 43
; PORTB=0x0F;
ldi R24,15
out 0x18,R24
.dbline 44
; delay_ms(2);
ldi R16,2
ldi R17,0
xcall _delay_ms
.dbline 45
; return PINB !=0x0F? 1:0; //如PINB为0x0F,则return 1 ,否则return 0
in R24,0x16
cpi R24,15
breq L11
ldi R20,1
ldi R21,0
xjmp L12
L11:
clr R20
clr R21
L12:
mov R16,R20
.dbline -2
L10:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbend
.dbfunc e Keys_Scan _Keys_Scan fV
.even
_Keys_Scan::
xcall push_gset1
.dbline -1
.dbline 52
; }
;
; //-----------------------------------------------------------------
; // 键盘矩阵扫描子程序
; //-----------------------------------------------------------------
; void Keys_Scan()
; {
.dbline 54
; //下面判断按键发生于0~3列中的哪一列
; switch(PINB)
in R20,0x16
clr R21
cpi R20,7
ldi R30,0
cpc R21,R30
breq L20
cpi R20,11
ldi R30,0
cpc R21,R30
breq L19
cpi R20,13
ldi R30,0
cpc R21,R30
breq L18
cpi R20,14
ldi R30,0
cpc R21,R30
breq L17
xjmp L14
X0:
.dbline 55
; {
L17:
.dbline 56
; case 0B00001110: KeyNo=0;break;
clr R2
sts _KeyNo,R2
.dbline 56
xjmp L15
L18:
.dbline 57
; case 0B00001101: KeyNo=1;break;
ldi R24,1
sts _KeyNo,R24
.dbline 57
xjmp L15
L19:
.dbline 58
; case 0B00001011: KeyNo=2;break;
ldi R24,2
sts _KeyNo,R24
.dbline 58
xjmp L15
L20:
.dbline 59
; case 0B00000111: KeyNo=3;break;
ldi R24,3
sts _KeyNo,R24
.dbline 59
xjmp L15
L14:
.dbline 60
; default:KeyNo=0xFF;
ldi R24,255
sts _KeyNo,R24
.dbline 61
; }
L15:
.dbline 65
;
;
; //反转键盘,高4位输入,低4位输出,低4位先置0,放入4列
; DDRB=0x0F;
ldi R24,15
out 0x17,R24
.dbline 66
; PORTB=0xF0;
ldi R24,240
out 0x18,R24
.dbline 67
; delay_ms(2);
ldi R16,2
ldi R17,0
xcall _delay_ms
.dbline 69
; //下面对0~3行分别附加起始值0、4、8、12
; switch(PINB)
in R20,0x16
clr R21
cpi R20,176
ldi R30,0
cpc R21,R30
breq L26
ldi R24,176
ldi R25,0
cp R24,R20
cpc R25,R21
brlt L29
L28:
cpi R20,112
ldi R30,0
cpc R21,R30
breq L27
xjmp L21
L29:
cpi R20,208
ldi R30,0
cpc R21,R30
breq L25
cpi R20,208
ldi R30,0
cpc R21,R30
brlt L21
L30:
cpi R20,224
ldi R30,0
cpc R21,R30
breq L24
xjmp L21
X1:
.dbline 70
; {
L24:
.dbline 71
; case 0B11100000: KeyNo +=0;break;
lds R2,_KeyNo
sts _KeyNo,R2
.dbline 71
xjmp L22
L25:
.dbline 72
; case 0B11010000: KeyNo +=4;break;
lds R24,_KeyNo
subi R24,252 ; addi 4
sts _KeyNo,R24
.dbline 72
xjmp L22
L26:
.dbline 73
; case 0B10110000: KeyNo +=8;break;
lds R24,_KeyNo
subi R24,248 ; addi 8
sts _KeyNo,R24
.dbline 73
xjmp L22
L27:
.dbline 74
; case 0B01110000: KeyNo +=12;break;
lds R24,_KeyNo
subi R24,244 ; addi 12
sts _KeyNo,R24
.dbline 74
xjmp L22
L21:
.dbline 75
ldi R24,255
sts _KeyNo,R24
.dbline 76
L22:
.dbline -2
L13:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbend
.dbfunc e Beep _Beep fV
; i -> R20
.even
_Beep::
xcall push_gset1
.dbline -1
.dbline 83
; default:KeyNo=0xFF;
; }
; }
;
; //-----------------------------------------------------------------
; // 蜂鸣器子程序
; //-----------------------------------------------------------------
; void Beep()
; {
.dbline 85
; uchar i;
; for(i=0;i<100;i++)
clr R20
xjmp L35
L32:
.dbline 86
.dbline 87
ldi R16,2
ldi R17,0
xcall _delay_ms
.dbline 88
ldi R24,128
ldi R25,0
in R2,0x12
clr R3
eor R2,R24
eor R3,R25
out 0x12,R2
.dbline 89
L33:
.dbline 85
inc R20
L35:
.dbline 85
cpi R20,100
brlo L32
.dbline -2
L31:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbend
.dbfunc e main _main fI
.even
_main::
.dbline -1
.dbline 96
; {
; delay_ms(2);
; BEEP();
; }
; }
;
; //-----------------------------------------------------------------
; // 主程序
; //-----------------------------------------------------------------
; int main()
; {
.dbline 98
; //配置数码管显示端口
; DDRC=0xFF;
ldi R24,255
out 0x14,R24
.dbline 99
; PORTC=0x00;
clr R2
out 0x15,R2
xjmp L38
L37:
.dbline 101
; while(1)
; {
.dbline 103
; //如果键盘矩阵有键按下则扫描键值
; if(KeyMatrix_Down()) Keys_Scan();
xcall _KeyMatrix_Down
tst R16
breq L38
.dbline 103
xcall _Keys_Scan
.dbline 104
; else continue;
L41:
.dbline 105
; if(KeyNo<16) //得到有效值
lds R24,_KeyNo
cpi R24,16
brsh L45
.dbline 106
; {
.dbline 107
; PORTC=SEG_CODE[KeyNo]; //显示键值
ldi R24,<_SEG_CODE
ldi R25,>_SEG_CODE
lds R30,_KeyNo
clr R31
add R30,R24
adc R31,R25
lpm R30,Z
out 0x15,R30
.dbline 108
; Beep(); //响铃
xcall _Beep
.dbline 109
; }
L44:
.dbline 110
L45:
.dbline 110
xcall _KeyMatrix_Down
tst R16
brne L44
.dbline 111
L38:
.dbline 100
xjmp L37
X2:
.dbline -2
L36:
.dbline 0 ; func end
ret
.dbend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -