📄 44key.lst
字号:
__start:
__text_start:
0033 E5CF LDI R28,0x5F
0034 E0D4 LDI R29,4
0035 BFCD OUT 0x3D,R28
0036 BFDE OUT 0x3E,R29
0037 51C0 SUBI R28,0x10
0038 40D0 SBCI R29,0
0039 EA0A LDI R16,0xAA
003A 8308 STD Y+0,R16
003B 2400 CLR R0
003C E6E1 LDI R30,0x61
003D E0F0 LDI R31,0
003E E010 LDI R17,0
003F 36E1 CPI R30,0x61
0040 07F1 CPC R31,R17
0041 F011 BEQ 0x0044
0042 9201 ST R0,Z+
0043 CFFB RJMP 0x003F
0044 8300 STD Z+0,R16
0045 E6E4 LDI R30,0x64
0046 E0F0 LDI R31,0
0047 E6A0 LDI R26,0x60
0048 E0B0 LDI R27,0
0049 E010 LDI R17,0
004A 36E5 CPI R30,0x65
004B 07F1 CPC R31,R17
004C F021 BEQ 0x0051
004D 95C8 LPM
004E 9631 ADIW R30,1
004F 920D ST R0,X+
0050 CFF9 RJMP 0x004A
0051 940E00FC CALL _main
_exit:
0053 CFFF RJMP _exit
_delay_ms:
i --> R20
j --> R22
k --> R16
0054 940E0121 CALL push_gset2
FILE: H:\39数码~1\4X4key.c
(0001) //-----------------------------------------------------------------
(0002) // 名称: 数码管显示4×4 键盘矩阵按键序号
(0003) //-----------------------------------------------------------------
(0004) // 说明: 本例运行时,数码管会显示所按下的任意按键在键盘矩阵上的位置.
(0005) // 扫描程序首先判断按键发生在哪一列,然后判断按键发生在哪一行,
(0006) // 由列号和行号即可得到键盘按键序号.
(0007) //
(0008) //-----------------------------------------------------------------
(0009) #include <iom16v.h>
(0010) #include <macros.h>
(0011) #define uchar unsigned char
(0012) #define uint unsigned int
(0013) //=============================
(0014) void delay_ms(uint k) //毫秒级的延时子函数
(0015) {
(0016) uint i,j;
(0017) for(i=0;i<k;i++)
0056 2744 CLR R20
0057 2755 CLR R21
0058 C00B RJMP 0x0064
(0018) {
(0019) for(j=0;j<1140;j++)
0059 2766 CLR R22
005A 2777 CLR R23
005B C002 RJMP 0x005E
005C 5F6F SUBI R22,0xFF
005D 4F7F SBCI R23,0xFF
005E 3764 CPI R22,0x74
005F E0E4 LDI R30,4
0060 077E CPC R23,R30
0061 F3D0 BCS 0x005C
0062 5F4F SUBI R20,0xFF
0063 4F5F SBCI R21,0xFF
0064 1740 CP R20,R16
0065 0751 CPC R21,R17
0066 F390 BCS 0x0059
0067 940E0118 CALL pop_gset2
0069 9508 RET
_KeyMatrix_Down:
006A 940E0123 CALL push_gset1
(0020) ;
(0021) }
(0022) }
(0023)
(0024) #define BEEP() PORTD ^= BIT(PD7) //蜂鸣器
(0025)
(0026) //0-9,A-F的数码管段码
(0027) const uchar SEG_CODE[] =
(0028) {
(0029) 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
(0030) 0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71
(0031) };
(0032)
(0033) //当前按键序号,该矩阵中序号范围为0-15,16表示无按键
(0034) uchar KeyNo = 16 ;
(0035)
(0036) //-----------------------------------------------------------------
(0037) // 判断键盘矩阵是否有键按下
(0038) //-----------------------------------------------------------------
(0039) uchar KeyMatrix_Down()
(0040) {
(0041) //高4位输出,低4位输入,高4位先置0
(0042) DDRB=0xF0;
006C EF80 LDI R24,0xF0
006D BB87 OUT 0x17,R24
(0043) PORTB=0x0F;
006E E08F LDI R24,0xF
006F BB88 OUT 0x18,R24
(0044) delay_ms(2);
0070 E002 LDI R16,2
0071 E010 LDI R17,0
0072 DFE1 RCALL _delay_ms
(0045) return PINB !=0x0F? 1:0; //如PINB为0x0F,则return 1 ,否则return 0
0073 B386 IN R24,0x16
0074 308F CPI R24,0xF
0075 F019 BEQ 0x0079
0076 E041 LDI R20,1
0077 E050 LDI R21,0
0078 C002 RJMP 0x007B
0079 2744 CLR R20
007A 2755 CLR R21
007B 2F04 MOV R16,R20
007C 940E0126 CALL pop_gset1
007E 9508 RET
_Keys_Scan:
007F 940E0123 CALL push_gset1
(0046) }
(0047)
(0048) //-----------------------------------------------------------------
(0049) // 键盘矩阵扫描子程序
(0050) //-----------------------------------------------------------------
(0051) void Keys_Scan()
(0052) {
(0053) //下面判断按键发生于0~3列中的哪一列
(0054) switch(PINB)
0081 B346 IN R20,0x16
0082 2755 CLR R21
0083 3047 CPI R20,7
0084 E0E0 LDI R30,0
0085 075E CPC R21,R30
0086 F0C9 BEQ 0x00A0
0087 304B CPI R20,0xB
0088 E0E0 LDI R30,0
0089 075E CPC R21,R30
008A F089 BEQ 0x009C
008B 304D CPI R20,0xD
008C E0E0 LDI R30,0
008D 075E CPC R21,R30
008E F049 BEQ 0x0098
008F 304E CPI R20,0xE
0090 E0E0 LDI R30,0
0091 075E CPC R21,R30
0092 F009 BEQ 0x0094
0093 C010 RJMP 0x00A4
(0055) {
(0056) case 0B00001110: KeyNo=0;break;
0094 2422 CLR R2
0095 92200060 STS KeyNo,R2
0097 C00F RJMP 0x00A7
(0057) case 0B00001101: KeyNo=1;break;
0098 E081 LDI R24,1
0099 93800060 STS KeyNo,R24
009B C00B RJMP 0x00A7
(0058) case 0B00001011: KeyNo=2;break;
009C E082 LDI R24,2
009D 93800060 STS KeyNo,R24
009F C007 RJMP 0x00A7
(0059) case 0B00000111: KeyNo=3;break;
00A0 E083 LDI R24,3
00A1 93800060 STS KeyNo,R24
00A3 C003 RJMP 0x00A7
(0060) default:KeyNo=0xFF;
00A4 EF8F LDI R24,0xFF
00A5 93800060 STS KeyNo,R24
(0061) }
(0062)
(0063)
(0064) //反转键盘,高4位输入,低4位输出,低4位先置0,放入4列
(0065) DDRB=0x0F;
00A7 E08F LDI R24,0xF
00A8 BB87 OUT 0x17,R24
(0066) PORTB=0xF0;
00A9 EF80 LDI R24,0xF0
00AA BB88 OUT 0x18,R24
(0067) delay_ms(2);
00AB E002 LDI R16,2
00AC E010 LDI R17,0
00AD DFA6 RCALL _delay_ms
(0068) //下面对0~3行分别附加起始值0、4、8、12
(0069) switch(PINB)
00AE B346 IN R20,0x16
00AF 2755 CLR R21
00B0 3B40 CPI R20,0xB0
00B1 E0E0 LDI R30,0
00B2 075E CPC R21,R30
00B3 F111 BEQ 0x00D6
00B4 EB80 LDI R24,0xB0
00B5 E090 LDI R25,0
00B6 1784 CP R24,R20
00B7 0795 CPC R25,R21
00B8 F02C BLT 0x00BE
00B9 3740 CPI R20,0x70
00BA E0E0 LDI R30,0
00BB 075E CPC R21,R30
00BC F0F9 BEQ 0x00DC
00BD C024 RJMP 0x00E2
00BE 3D40 CPI R20,0xD0
00BF E0E0 LDI R30,0
00C0 075E CPC R21,R30
00C1 F071 BEQ 0x00D0
00C2 3D40 CPI R20,0xD0
00C3 E0E0 LDI R30,0
00C4 075E CPC R21,R30
00C5 F0E4 BLT 0x00E2
00C6 3E40 CPI R20,0xE0
00C7 E0E0 LDI R30,0
00C8 075E CPC R21,R30
00C9 F009 BEQ 0x00CB
00CA C017 RJMP 0x00E2
(0070) {
(0071) case 0B11100000: KeyNo +=0;break;
00CB 90200060 LDS R2,KeyNo
00CD 92200060 STS KeyNo,R2
00CF C015 RJMP 0x00E5
(0072) case 0B11010000: KeyNo +=4;break;
00D0 91800060 LDS R24,KeyNo
00D2 5F8C SUBI R24,0xFC
00D3 93800060 STS KeyNo,R24
00D5 C00F RJMP 0x00E5
(0073) case 0B10110000: KeyNo +=8;break;
00D6 91800060 LDS R24,KeyNo
00D8 5F88 SUBI R24,0xF8
00D9 93800060 STS KeyNo,R24
00DB C009 RJMP 0x00E5
(0074) case 0B01110000: KeyNo +=12;break;
00DC 91800060 LDS R24,KeyNo
00DE 5F84 SUBI R24,0xF4
00DF 93800060 STS KeyNo,R24
00E1 C003 RJMP 0x00E5
(0075) default:KeyNo=0xFF;
00E2 EF8F LDI R24,0xFF
00E3 93800060 STS KeyNo,R24
(0076) }
00E5 940E0126 CALL pop_gset1
00E7 9508 RET
_Beep:
i --> R20
00E8 940E0123 CALL push_gset1
(0077) }
(0078)
(0079) //-----------------------------------------------------------------
(0080) // 蜂鸣器子程序
(0081) //-----------------------------------------------------------------
(0082) void Beep()
(0083) {
(0084) uchar i;
(0085) for(i=0;i<100;i++)
00EA 2744 CLR R20
00EB C00B RJMP 0x00F7
(0086) {
(0087) delay_ms(2);
00EC E002 LDI R16,2
00ED E010 LDI R17,0
00EE DF65 RCALL _delay_ms
(0088) BEEP();
00EF E880 LDI R24,0x80
00F0 E090 LDI R25,0
00F1 B222 IN R2,0x12
00F2 2433 CLR R3
00F3 2628 EOR R2,R24
00F4 2639 EOR R3,R25
00F5 BA22 OUT 0x12,R2
00F6 9543 INC R20
00F7 3644 CPI R20,0x64
00F8 F398 BCS 0x00EC
00F9 940E0126 CALL pop_gset1
00FB 9508 RET
(0089) }
(0090) }
(0091)
(0092) //-----------------------------------------------------------------
(0093) // 主程序
(0094) //-----------------------------------------------------------------
(0095) int main()
(0096) {
(0097) //配置数码管显示端口
(0098) DDRC=0xFF;
_main:
00FC EF8F LDI R24,0xFF
00FD BB84 OUT 0x14,R24
(0099) PORTC=0x00;
00FE 2422 CLR R2
00FF BA25 OUT 0x15,R2
0100 C015 RJMP 0x0116
(0100) while(1)
(0101) {
(0102) //如果键盘矩阵有键按下则扫描键值
(0103) if(KeyMatrix_Down()) Keys_Scan();
0101 DF68 RCALL _KeyMatrix_Down
0102 2300 TST R16
0103 F091 BEQ 0x0116
0104 DF7A RCALL _Keys_Scan
(0104) else continue;
(0105) if(KeyNo<16) //得到有效值
0105 91800060 LDS R24,KeyNo
0107 3180 CPI R24,0x10
0108 F450 BCC 0x0113
(0106) {
(0107) PORTC=SEG_CODE[KeyNo]; //显示键值
0109 E584 LDI R24,0x54
010A E090 LDI R25,0
010B 91E00060 LDS R30,KeyNo
010D 27FF CLR R31
010E 0FE8 ADD R30,R24
010F 1FF9 ADC R31,R25
0110 91E4 LPM R30,0(Z)
0111 BBE5 OUT 0x15,R30
(0108) Beep(); //响铃
0112 DFD5 RCALL _Beep
(0109) }
(0110) while(KeyMatrix_Down());
FILE: <library>
0113 DF56 RCALL _KeyMatrix_Down
0114 2300 TST R16
0115 F7E9 BNE 0x0113
0116 CFEA RJMP 0x0101
0117 9508 RET
pop_gset2:
0118 E0E2 LDI R30,2
0119 940C0127 JMP pop
push_gset5:
011B 92FA ST R15,-Y
011C 92EA ST R14,-Y
push_gset4:
011D 92DA ST R13,-Y
011E 92CA ST R12,-Y
push_gset3:
011F 92BA ST R11,-Y
0120 92AA ST R10,-Y
push_gset2:
0121 937A ST R23,-Y
0122 936A ST R22,-Y
push_gset1:
0123 935A ST R21,-Y
0124 934A ST R20,-Y
0125 9508 RET
pop_gset1:
0126 E0E1 LDI R30,1
pop:
0127 9149 LD R20,Y+
0128 9159 LD R21,Y+
0129 FDE0 SBRC R30,0
012A 9508 RET
012B 9169 LD R22,Y+
012C 9179 LD R23,Y+
012D FDE1 SBRC R30,1
012E 9508 RET
012F 90A9 LD R10,Y+
0130 90B9 LD R11,Y+
0131 FDE2 SBRC R30,2
0132 9508 RET
0133 90C9 LD R12,Y+
0134 90D9 LD R13,Y+
0135 FDE3 SBRC R30,3
0136 9508 RET
0137 90E9 LD R14,Y+
0138 90F9 LD R15,Y+
0139 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -