📄 kbscan.lst
字号:
__text_start:
__start:
001B E5CF LDI R28,0x5F
001C E0D4 LDI R29,4
001D BFCD OUT 0x3D,R28
001E BFDE OUT 0x3E,R29
001F 51C0 SUBI R28,0x10
0020 40D0 SBCI R29,0
0021 EA0A LDI R16,0xAA
0022 8308 STD Y+0,R16
0023 2400 CLR R0
0024 E6E0 LDI R30,0x60
0025 E0F0 LDI R31,0
0026 E010 LDI R17,0
0027 36E0 CPI R30,0x60
0028 07F1 CPC R31,R17
0029 F011 BEQ 0x002C
002A 9201 ST R0,Z+
002B CFFB RJMP 0x0027
002C 8300 STD Z+0,R16
002D E3E6 LDI R30,0x36
002E E0F0 LDI R31,0
002F E6A0 LDI R26,0x60
0030 E0B0 LDI R27,0
0031 E010 LDI R17,0
0032 33E6 CPI R30,0x36
0033 07F1 CPC R31,R17
0034 F021 BEQ 0x0039
0035 95C8 LPM
0036 9631 ADIW R30,1
0037 920D ST R0,X+
0038 CFF9 RJMP 0x0032
0039 D0A7 RCALL _main
_exit:
003A CFFF RJMP _exit
FILE: H:\嵌入式开发\单片机\Proj\4x4KeyBoard\kbscan.c
(0001) /**************************************************************************
(0002) Description:线翻转法键盘扫描程序,只检测和处理单键
(0003)
(0004) 4*4键盘排列:
(0005) 0 1 2 3
(0006) -----------------
(0007) | 0 1 2 3 | 0
(0008) | 4 5 6 7 | 1
(0009) | 8 9 A B | 2
(0010) | C D E F | 3
(0011) -----------------
(0012)
(0013) Write by:杨震禹
(0014) Time:2007-1-5
(0015) ***************************************************************************/
(0016) #include <iom8v.h>
(0017) #include <macros.h>
(0018)
(0019) #define key_port PORTB //定义键盘接口
(0020) #define port_DDR DDRB
(0021) #define port_PIN PINB
(0022) typedef unsigned int UINT;
(0023) typedef unsigned char UCHAR;
(0024)
(0025) const UCHAR digital[16] =
(0026) {
(0027) 0x3f, 0x6, 0x5b, 0x4f, //0,1,2,3
(0028) 0x66, 0x6d, 0x7d, 0x7, //4,5,6,7
(0029) 0x7f, 0x6f, 0x77, 0x7c, //8,9,A,B
(0030) 0x39, 0x5e, 0x79, 0x71 //C,D,E,F
(0031) };
(0032)
(0033) /*延时程序*/
(0034) void delay_1ms(void)
(0035) {//1ms延时函数
(0036) UINT i;
(0037) for(i=0; i<141; i++)
_delay_1ms:
i --> R16
003B 2700 CLR R16
003C 2711 CLR R17
003D C002 RJMP 0x0040
003E 5F0F SUBI R16,0xFF
003F 4F1F SBCI R17,0xFF
0040 380D CPI R16,0x8D
0041 E0E0 LDI R30,0
0042 071E CPC R17,R30
0043 F3D0 BCS 0x003E
0044 9508 RET
_delay:
i --> R20
n --> R22
0045 D0B7 RCALL push_gset2
0046 01B8 MOVW R22,R16
(0038) {}
(0039) }
(0040)
(0041) void delay(UINT n)
(0042) {//延时n毫秒
(0043) UINT i;
(0044) for(i=0; i<n; i++) //执行n次1毫秒延时
0047 2744 CLR R20
0048 2755 CLR R21
0049 C003 RJMP 0x004D
(0045) delay_1ms();
004A DFF0 RCALL _delay_1ms
004B 5F4F SUBI R20,0xFF
004C 4F5F SBCI R21,0xFF
004D 1746 CP R20,R22
004E 0757 CPC R21,R23
004F F3D0 BCS 0x004A
0050 D0A2 RCALL pop_gset2
0051 9508 RET
(0046) }
(0047)
(0048) /*键盘扫描*/
(0049) void scan_init(void)
(0050) {//初始化键盘扫描端口
(0051) key_port = 0xff;
_scan_init:
0052 EF8F LDI R24,0xFF
0053 BB88 OUT 0x18,R24
(0052) port_DDR = 0x0f; //高四位输入,开上拉电阻
0054 E08F LDI R24,0xF
0055 BB87 OUT 0x17,R24
(0053) key_port = 0xf0; //低四位输出0
0056 EF80 LDI R24,0xF0
0057 BB88 OUT 0x18,R24
0058 9508 RET
(0054) }
(0055)
(0056) void scan_turn(void)
(0057) {//端口输出翻转
(0058) key_port |= 0x0f;
_scan_turn:
0059 B388 IN R24,0x18
005A 608F ORI R24,0xF
005B BB88 OUT 0x18,R24
(0059) port_DDR = 0xf0; //低四位输入,开上拉电阻
005C EF80 LDI R24,0xF0
005D BB87 OUT 0x17,R24
(0060) key_port &= 0x0f; //高四位输出0
005E B388 IN R24,0x18
005F 708F ANDI R24,0xF
0060 BB88 OUT 0x18,R24
0061 9508 RET
_kbscan:
col --> R20
row --> R22
0062 D096 RCALL push_gset4
(0061) }
(0062)
(0063) UCHAR kbscan(void)
(0064) {
(0065) UCHAR row, col; //行、列坐标
(0066) row = 4;
0063 E064 LDI R22,4
(0067) col = 4;
0064 E044 LDI R20,4
(0068) scan_init();
0065 DFEC RCALL _scan_init
(0069) if((port_PIN&0xf0)!=0xf0) { //有键按下
0066 B386 IN R24,0x16
0067 7F80 ANDI R24,0xF0
0068 3F80 CPI R24,0xF0
0069 F409 BNE 0x006B
006A C057 RJMP 0x00C2
(0070) delay(5); //防抖
006B E005 LDI R16,5
006C E010 LDI R17,0
006D DFD7 RCALL _delay
(0071) if((port_PIN&0xf0)!=0xf0) {
006E B386 IN R24,0x16
006F 7F80 ANDI R24,0xF0
0070 3F80 CPI R24,0xF0
0071 F409 BNE 0x0073
0072 C04F RJMP 0x00C2
(0072) row = (port_PIN&0xf0); //行值
0073 B366 IN R22,0x16
0074 7F60 ANDI R22,0xF0
(0073)
(0074) scan_turn(); //翻转
0075 DFE3 RCALL _scan_turn
(0075)
(0076) if((port_PIN&0x0f)!=0x0f)
0076 B386 IN R24,0x16
0077 708F ANDI R24,0xF
0078 308F CPI R24,0xF
0079 F011 BEQ 0x007C
(0077) col = (port_PIN&0x0f); //列值
007A B346 IN R20,0x16
007B 704F ANDI R20,0xF
(0078)
(0079) /*行坐标*/
(0080) switch(row)
007C 2EA6 MOV R10,R22
007D 24BB CLR R11
007E 01C5 MOVW R24,R10
007F 3B80 CPI R24,0xB0
0080 E0E0 LDI R30,0
0081 079E CPC R25,R30
0082 F0E9 BEQ 0x00A0
0083 EB80 LDI R24,0xB0
0084 158A CP R24,R10
0085 059B CPC R25,R11
0086 F034 BLT 0x008D
0087 01C5 MOVW R24,R10
0088 3780 CPI R24,0x70
0089 E0E0 LDI R30,0
008A 079E CPC R25,R30
008B F0B1 BEQ 0x00A2
008C C017 RJMP 0x00A4
008D 01C5 MOVW R24,R10
008E 3D80 CPI R24,0xD0
008F E0E0 LDI R30,0
0090 079E CPC R25,R30
0091 F061 BEQ 0x009E
0092 3D80 CPI R24,0xD0
0093 E0E0 LDI R30,0
0094 079E CPC R25,R30
0095 F074 BLT 0x00A4
0096 01C5 MOVW R24,R10
0097 3E80 CPI R24,0xE0
0098 E0E0 LDI R30,0
0099 079E CPC R25,R30
009A F009 BEQ 0x009C
009B C008 RJMP 0x00A4
(0081) {
(0082) case 0xe0: row = 0;
009C 2766 CLR R22
(0083) break;
009D C007 RJMP 0x00A5
(0084) case 0xd0: row = 1;
009E E061 LDI R22,1
(0085) break;
009F C005 RJMP 0x00A5
(0086) case 0xb0: row = 2;
00A0 E062 LDI R22,2
(0087) break;
00A1 C003 RJMP 0x00A5
(0088) case 0x70: row = 3;
00A2 E063 LDI R22,3
(0089) break;
00A3 C001 RJMP 0x00A5
(0090) default: row=4; //未知数值
00A4 E064 LDI R22,4
(0091) }
(0092) /*列坐标*/
(0093) switch(col)
00A5 2EA4 MOV R10,R20
00A6 24BB CLR R11
00A7 01C5 MOVW R24,R10
00A8 3087 CPI R24,7
00A9 E0E0 LDI R30,0
00AA 079E CPC R25,R30
00AB F099 BEQ 0x00BF
00AC 308B CPI R24,0xB
00AD E0E0 LDI R30,0
00AE 079E CPC R25,R30
00AF F069 BEQ 0x00BD
00B0 308D CPI R24,0xD
00B1 E0E0 LDI R30,0
00B2 079E CPC R25,R30
00B3 F039 BEQ 0x00BB
00B4 308E CPI R24,0xE
00B5 E0E0 LDI R30,0
00B6 079E CPC R25,R30
00B7 F009 BEQ 0x00B9
00B8 C008 RJMP 0x00C1
(0094) {
(0095) case 0x0e: col = 0;
00B9 2744 CLR R20
(0096) break;
00BA C007 RJMP 0x00C2
(0097) case 0x0d: col = 1;
00BB E041 LDI R20,1
(0098) break;
00BC C005 RJMP 0x00C2
(0099) case 0x0b: col = 2;
00BD E042 LDI R20,2
(0100) break;
00BE C003 RJMP 0x00C2
(0101) case 0x07: col = 3;
00BF E043 LDI R20,3
(0102) break;
00C0 C001 RJMP 0x00C2
(0103) default: col=4; //未知数值
00C1 E044 LDI R20,4
(0104) }
(0105) }
(0106) }
(0107) if((row!=4)&(col!=4))
00C2 3064 CPI R22,4
00C3 F021 BEQ 0x00C8
00C4 E081 LDI R24,1
00C5 E090 LDI R25,0
00C6 016C MOVW R12,R24
00C7 C002 RJMP 0x00CA
00C8 24CC CLR R12
00C9 24DD CLR R13
00CA 3044 CPI R20,4
00CB F021 BEQ 0x00D0
00CC E081 LDI R24,1
00CD E090 LDI R25,0
00CE 015C MOVW R10,R24
00CF C002 RJMP 0x00D2
00D0 24AA CLR R10
00D1 24BB CLR R11
00D2 0116 MOVW R2,R12
00D3 202A AND R2,R10
00D4 203B AND R3,R11
00D5 2022 TST R2
00D6 F411 BNE 0x00D9
00D7 2033 TST R3
00D8 F029 BEQ 0x00DE
(0108) return row*4+col;
00D9 E084 LDI R24,4
00DA 9F86 MUL R24,R22
00DB 2D00 MOV R16,R0
00DC 0F04 ADD R16,R20
00DD C001 RJMP 0x00DF
(0109) else return 16; //错误返回
00DE E100 LDI R16,0x10
00DF D015 RCALL pop_gset4
00E0 9508 RET
(0110) }
(0111)
(0112) /*MAIN*/
(0113) void main(void)
(0114) {
(0115) UCHAR key;
(0116) DDRD = 0xff;
_main:
key --> R20
00E1 EF8F LDI R24,0xFF
00E2 BB81 OUT 0x11,R24
00E3 C00D RJMP 0x00F1
(0117) while(1){
(0118) key = kbscan();
00E4 DF7D RCALL _kbscan
00E5 2F40 MOV R20,R16
(0119) if(key!=16)
00E6 3100 CPI R16,0x10
00E7 F049 BEQ 0x00F1
(0120) PORTD = ~digital[key]; //数码管输出相应数字
FILE: <library>
00E8 E286 LDI R24,0x26
00E9 E090 LDI R25,0
00EA 2FE4 MOV R30,R20
00EB 27FF CLR R31
00EC 0FE8 ADD R30,R24
00ED 1FF9 ADC R31,R25
00EE 91E4 LPM R30,0(Z)
00EF 95E0 COM R30
00F0 BBE2 OUT 0x12,R30
00F1 CFF2 RJMP 0x00E4
00F2 9508 RET
pop_gset2:
00F3 E0E2 LDI R30,2
00F4 C00E RJMP pop
pop_gset4:
00F5 E0E8 LDI R30,0x8
00F6 C00C RJMP pop
push_gset5:
00F7 92FA ST R15,-Y
00F8 92EA ST R14,-Y
push_gset4:
00F9 92DA ST R13,-Y
00FA 92CA ST R12,-Y
push_gset3:
00FB 92BA ST R11,-Y
00FC 92AA ST R10,-Y
push_gset2:
00FD 937A ST R23,-Y
00FE 936A ST R22,-Y
push_gset1:
00FF 935A ST R21,-Y
0100 934A ST R20,-Y
0101 9508 RET
pop_gset1:
0102 E0E1 LDI R30,1
pop:
0103 9149 LD R20,Y+
0104 9159 LD R21,Y+
0105 FDE0 SBRC R30,0
0106 9508 RET
0107 9169 LD R22,Y+
0108 9179 LD R23,Y+
0109 FDE1 SBRC R30,1
010A 9508 RET
010B 90A9 LD R10,Y+
010C 90B9 LD R11,Y+
010D FDE2 SBRC R30,2
010E 9508 RET
010F 90C9 LD R12,Y+
0110 90D9 LD R13,Y+
0111 FDE3 SBRC R30,3
0112 9508 RET
0113 90E9 LD R14,Y+
0114 90F9 LD R15,Y+
0115 9508 RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -