📄 keyboard_int.s
字号:
.module keyboard_int.c
.area text(rom, con, rel)
.dbfile D:\实例8_中断唤醒的键盘扫描_加入抗抖动/delay.h
.dbfunc e Delay_ms _Delay_ms fV
; n -> R20
; Time -> R16,R17
.even
_Delay_ms::
rcall push_gset1
.dbline -1
.dbline 14
; #include "iom48v.h"
; #include "macros.h"
; #include "delay.h"
; #include "led_dis.h"
;
; #define Key_X_1 PORTC = 0b11011111 //扫描第1行键
; #define Key_X_2 PORTC = 0b11101111 //扫描第2行键
;
; #define Key_Scan_Port PINC //定义用于扫描键盘的端口
; #define Key_Y_1 0b11110111 //第1列上有键按下
; #define Key_Y_2 0b11111011 //第2列上有键按下
; #define Key_Y_3 0b11111101 //第3列上有键按下
;
; #define Key_A 0x0A
.dbline 15
; #define Key_B 0x0B
clr R20
rjmp L3
L2:
.dbline 17
; #define Key_C 0x0C
; #define Key_D 0x0D
.dbline 18
; #define Key_E 0x0E
ldi R20,1
rjmp L8
L5:
.dbline 19
.dbline 20
nop
.dbline 21
L6:
.dbline 18
inc R20
L8:
.dbline 18
cpi R20,187
brlo L5
.dbline 22
subi R16,1
sbci R17,0
.dbline 23
L3:
.dbline 16
cpi R16,0
cpc R16,R17
brne L2
X0:
.dbline -2
L1:
rcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r n 20 c
.dbsym r Time 16 i
.dbend
.area lit(rom, con, rel)
_DisTab::
.byte 252,96
.byte 218,242
.byte 'f,182
.byte 190,224
.byte 254,246
.byte 238,62
.byte 156,'z
.byte 158,142
.byte 206,28
.byte 'n,124
.byte 10,16
.byte 2
.dbfile D:\实例8_中断唤醒的键盘扫描_加入抗抖动/led_dis.h
.dbsym e DisTab _DisTab A[23:23]kc
.area text(rom, con, rel)
.dbfile D:\实例8_中断唤醒的键盘扫描_加入抗抖动/led_dis.h
.dbfile D:\实例8_中断唤醒的键盘扫描_加入抗抖动\keyboard_int.c
.dbfunc e Key_Scan _Key_Scan fc
.even
_Key_Scan::
.dbline -1
.dbline 25
; #define Key_F 0x0F
; #define NoKey 0x00
;
; #define LedDisPort PORTD
;
; unsigned char Key_Scan (void) //键盘扫描函数,扫描键盘一次并返回键值
; {
.dbline 27
; /*-----------------------扫描第1行-----------------------*/
; Key_X_1;
ldi R24,223
out 0x8,R24
.dbline 29
;
; Delay_ms(1);
ldi R16,1
ldi R17,0
rcall _Delay_ms
.dbline 31
;
; if ((Key_Scan_Port|Key_Y_1)==Key_Y_1)
in R24,0x6
ori R24,247
cpi R24,247
brne L10
.dbline 32
; return Key_A;
ldi R16,10
rjmp L9
L10:
.dbline 33
; else if ((Key_Scan_Port|Key_Y_2)==Key_Y_2)
in R24,0x6
ori R24,251
cpi R24,251
brne L12
.dbline 34
; return Key_B;
ldi R16,11
rjmp L9
L12:
.dbline 35
; else if ((Key_Scan_Port|Key_Y_3)==Key_Y_3)
in R24,0x6
ori R24,253
cpi R24,253
brne L14
.dbline 36
; return Key_C;
ldi R16,12
rjmp L9
L14:
.dbline 39
;
; /*-----------------------扫描第2行-----------------------*/
; Key_X_2;
ldi R24,239
out 0x8,R24
.dbline 41
;
; Delay_ms(1);
ldi R16,1
ldi R17,0
rcall _Delay_ms
.dbline 43
;
; if ((Key_Scan_Port|Key_Y_1)==Key_Y_1)
in R24,0x6
ori R24,247
cpi R24,247
brne L16
.dbline 44
; return Key_D;
ldi R16,13
rjmp L9
L16:
.dbline 45
; else if ((Key_Scan_Port|Key_Y_2)==Key_Y_2)
in R24,0x6
ori R24,251
cpi R24,251
brne L18
.dbline 46
; return Key_E;
ldi R16,14
rjmp L9
L18:
.dbline 47
; else if ((Key_Scan_Port|Key_Y_3)==Key_Y_3)
in R24,0x6
ori R24,253
cpi R24,253
brne L20
.dbline 48
; return Key_F;
ldi R16,15
rjmp L9
L20:
.dbline 50
;
; return NoKey;
clr R16
.dbline -2
L9:
.dbline 0 ; func end
ret
.dbend
.dbfunc e Key_Scan_Ant_Dither _Key_Scan_Ant_Dither fc
; TmpKeyValue -> R20
.even
_Key_Scan_Ant_Dither::
rcall push_gset1
.dbline -1
.dbline 54
; }
;
; unsigned char Key_Scan_Ant_Dither(void) //抗抖动的键盘扫描函数,扫描键盘并返回键值
; {
.dbline 55
; unsigned char TmpKeyValue=NoKey;
clr R20
.dbline 57
;
; TmpKeyValue=Key_Scan();
rcall _Key_Scan
mov R20,R16
.dbline 59
;
; if (TmpKeyValue==NoKey)
tst R16
brne L23
.dbline 60
; return NoKey;
clr R16
rjmp L22
L23:
.dbline 62
;
; Delay_ms(20);
ldi R16,20
ldi R17,0
rcall _Delay_ms
.dbline 64
;
; if (TmpKeyValue!=Key_Scan())
rcall _Key_Scan
cp R20,R16
breq L25
.dbline 65
; return NoKey;
clr R16
rjmp L22
L25:
.dbline 67
;
; return TmpKeyValue;
mov R16,R20
.dbline -2
L22:
rcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r TmpKeyValue 20 c
.dbend
.area vector(rom, abs)
.org 8
rjmp _pcint1_isr
.area text(rom, con, rel)
.dbfile D:\实例8_中断唤醒的键盘扫描_加入抗抖动\keyboard_int.c
.dbfunc e pcint1_isr _pcint1_isr fV
.even
_pcint1_isr::
st -y,R24
in R24,0x3f
st -y,R24
.dbline -1
.dbline 73
; }
;
;
; #pragma interrupt_handler pcint1_isr: iv_PCINT1
; void pcint1_isr(void) //引脚电平变化中断PCINT1中断服务函数
; {
.dbline 74
; SMCR&=0xFE; //禁止休眠功能,以免误触发
in R24,0x33
andi R24,254
out 0x33,R24
.dbline 75
; PCMSK1&=(~((1<<PCINT11)|(1<<PCINT10)|(1<<PCINT9))); //禁止引脚电平变化中断,以免影响键盘扫描程序的运行
lds R24,108
andi R24,241
sts 108,R24
.dbline 76
; PCICR&=(~(1<<PCIE1));
lds R24,104
andi R24,253
sts 104,R24
.dbline -2
L27:
ld R24,y+
out 0x3f,R24
ld R24,y+
.dbline 0 ; func end
reti
.dbend
.dbfunc e main _main fV
; SleepTimer -> R20,R21
; KeyValue -> R22
.even
_main::
.dbline -1
.dbline 80
; }
;
; void main (void)
; {
.dbline 81
; unsigned char KeyValue=NoKey;
clr R22
.dbline 82
; unsigned int SleepTimer=0;
clr R20
clr R21
.dbline 84
;
; DDRC=0xF1; //将键盘的"行"设置为输出,键盘的"列"设置为输入并开启了输入端的内部上拉电阻
ldi R24,241
out 0x7,R24
.dbline 85
; DDRB=0xFF;
ldi R24,255
out 0x4,R24
.dbline 86
; DDRD=0xFF;
out 0xa,R24
.dbline 87
; PORTC=0xFF;
out 0x8,R24
.dbline 88
; PORTB=0xFF;
out 0x5,R24
.dbline 89
; PORTD=0xFF;
out 0xb,R24
.dbline 91
;
; SEI(); //允许全局中断
sei
.dbline 93
;
; LedDisPort=DisTab[0]; //上电后初始化显示"0"
ldi R30,<_DisTab
ldi R31,>_DisTab
lpm R30,Z
out 0xb,R30
rjmp L30
L29:
.dbline 96
;
; while(1)
; {
.dbline 97
; KeyValue=Key_Scan_Ant_Dither();
rcall _Key_Scan_Ant_Dither
mov R22,R16
.dbline 98
; if (KeyValue!=NoKey) //当有按键按下时,显示该键的键值
tst R16
breq L32
.dbline 99
; {
.dbline 100
; LedDisPort=DisTab[KeyValue];
ldi R24,<_DisTab
ldi R25,>_DisTab
mov R30,R22
clr R31
add R30,R24
adc R31,R25
lpm R30,Z
out 0xb,R30
.dbline 101
; SleepTimer=0; //并清0休眠计时器
clr R20
clr R21
.dbline 102
; }
rjmp L33
L32:
.dbline 104
; else //当没有按键按下时,计算连续未操作的时间
; {
.dbline 105
; SleepTimer++; //休眠计时器自加以实现计时
subi R20,255 ; offset = 1
sbci R21,255
.dbline 106
; if (SleepTimer >= 1500) //当连续3秒钟(近似值)没有按任何按键时,将进入休眠状态
cpi R20,220
ldi R30,5
cpc R21,R30
brlo L34
.dbline 107
; {
.dbline 108
; SleepTimer=0; //清0休眠计时器,以便唤醒后继续计时
clr R20
clr R21
.dbline 109
; PORTC=0b11001111; //将键盘的行(PC5,PC4)设置为输出"0"状态
ldi R24,207
out 0x8,R24
.dbline 110
; PORTD=0x00; //关闭数码管显示驱动以节省电能
clr R2
out 0xb,R2
.dbline 111
; PCMSK1|=((1<<PCINT11)|(1<<PCINT10)|(1<<PCINT9)); //使能PCINT9..11
lds R24,108
ori R24,14
sts 108,R24
.dbline 112
; PCICR|=(1<<PCIE1); //使能第一组引脚电平变化中断
lds R24,104
ori R24,2
sts 104,R24
.dbline 113
; SMCR=0x05; //设置掉电状态并使能休眠功能
ldi R24,5
out 0x33,R24
.dbline 114
; asm("SLEEP"); //休眠单片机,进入掉电状态
SLEEP
.dbline 115
; PORTC=0xFF; //休眠唤醒后将PC端口重置回初始化状态
ldi R24,255
out 0x8,R24
.dbline 116
; }
L34:
.dbline 117
; } //End Of Else
L33:
.dbline 118
L30:
.dbline 95
rjmp L29
X1:
.dbline -2
L28:
.dbline 0 ; func end
ret
.dbsym r SleepTimer 20 i
.dbsym r KeyValue 22 c
.dbend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -