📄 ps2_kb.s
字号:
.byte 124,42
.byte 125,57
.byte 0,0
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
.dbsym e unshifted _unshifted A[130:65:2]c
_shifted::
.byte 14,126
.byte 21,'Q
.byte 22,33
.byte 26,'Z
.byte 27,'S
.byte 28,'A
.byte 29,'W
.byte 30,64
.byte 33,'C
.byte 34,'X
.byte 35,'D
.byte 36,'E
.byte 37,36
.byte 38,35
.byte 41,32
.byte 42,'V
.byte 43,'F
.byte 44,'T
.byte 45,'R
.byte 46,37
.byte 49,'N
.byte 50,'B
.byte 51,'H
.byte 52,'G
.byte 53,'Y
.byte 54,94
.byte 57,'L
.byte 58,'M
.byte 59,'J
.byte 60,'U
.byte 61,38
.byte 62,42
.byte 'A,60
.byte 'B,'K
.byte 'C,'I
.byte 'D,'O
.byte 'E,41
.byte 'F,40
.byte 'I,62
.byte 'J,63
.byte 'K,'L
.byte 'L,58
.byte 'M,'P
.byte 'N,95
.byte 'R,34
.byte 'T,123
.byte 'U,43
.byte 91,125
.byte 93,124
.byte 'a,62
.byte 'i,49
.byte 'k,52
.byte 'l,55
.byte 'p,48
.byte 'q,46
.byte 'r,50
.byte 's,53
.byte 't,54
.byte 'u,56
.byte 'y,43
.byte 'z,51
.byte 123,45
.byte 124,42
.byte 125,57
.byte 0,0
.dbsym e shifted _shifted A[130:65:2]c
.area data(ram, con, rel)
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
_ascii::
.blkb 1
.area idata
.byte 32
.area data(ram, con, rel)
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
.dbsym e ascii _ascii c
.area text(rom, con, rel)
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
.dbfunc e Init_kb _Init_kb fV
.even
_Init_kb::
.dbline -1
.dbline 166
; 0x73,'5',
; 0x74,'6',
; 0x75,'8',
; 0x79,'+',
; 0x7a,'3',
; 0x7b,'-',
; 0x7c,'*',
; 0x7d,'9',
; 0,0
; };
; #pragma data:data //将以后的变量放在RAM
; void Decode(uchar scancode);//声明函数原型
; uchar edge, bitcount,ascii=' '; //edge为0下降沿中断,为1上升沿中断
; //bitcount为位计数值
; //ascii为翻译后的ASCII码,初值为空格
;
; /*******************************************
; 函数名称: Init_kb
; 功 能: 初始化PS2函数
; 参 数: 无
; 返回值 : 无
; /********************************************/
; void Init_kb(void)
; {
.dbline 167
; MCUCR = 2; //设置INT0为下降沿触发中断
ldi R24,2
out 0x35,R24
.dbline 168
; edge = 0; //0为下降沿中断标志,1为上升沿中断标志
clr R2
sts _edge,R2
.dbline 169
; bitcount = 11; //每次11位数据,一个起始位(0),8个数据位,一个奇偶校验位,一个停止位(1)
ldi R24,11
sts _bitcount,R24
.dbline 170
; DDRD&=~BIT(PD2); //配置中断管脚为输入
cbi 0x11,2
.dbline 171
; PORTD|=BIT(PD2); //使能中断管脚的上拉
sbi 0x12,2
.dbline 172
; DDRA&=~BIT(PA0); //配置键盘数据输入口为输入
cbi 0x1a,0
.dbline 173
; PORTA|=BIT(PA0); //使能数据输入管脚的上拉
sbi 0x1b,0
.dbline 174
; SREG|=BIT(GLOBAL);//打开全局中断
bset 7
.dbline 175
; GICR|=BIT(EXTINT0);
in R24,0x3b
ori R24,64
out 0x3b,R24
.dbline -2
.dbline 176
; }
L46:
.dbline 0 ; func end
ret
.dbend
.dbfunc e Disp_ascii _Disp_ascii fV
; ascii -> R20
.even
_Disp_ascii::
xcall push_gset1
mov R20,R16
.dbline -1
.dbline 184
; /*******************************************
; 函数名称: Disp_ascii
; 功 能: 在1602液晶上显示键盘上的ASCII码
; 参 数: ascii--将要显示的ASCII码
; 返回值 : 无
; /********************************************/
; void Disp_ascii(uchar ascii)
; {
.dbline 185
; LCD1602_gotoXY(1,2);
ldi R18,2
ldi R16,1
xcall _LCD1602_gotoXY
.dbline 186
; LCD1602_sendstr("KEY_ASCII:");
ldi R16,<L48
ldi R17,>L48
xcall _LCD1602_sendstr
.dbline 187
; LCD1602_sendbyte(iDat,ascii);
mov R18,R20
ldi R16,1
xcall _LCD1602_sendbyte
.dbline -2
.dbline 188
; }
L47:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r ascii 20 c
.dbend
.area bss(ram, con, rel)
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
L50:
.blkb 1
.area text(rom, con, rel)
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
.dbfunc e Int0 _Int0 fV
.dbsym s data L50 c
.even
_Int0::
xcall push_lset
.dbline -1
.dbline 196
; /*******************************************
; 函数名称: Int0
; 功 能: 外部中断0的中断服务函数,上升沿中断读入11位数据,下降沿调用解码程序
; 参 数: 无
; 返回值 : 无
; /********************************************/
; void Int0(void)
; {
.dbline 198
; static uchar data; // 声明局部静态变量来保存扫描码
; if (!edge) // 如果是下降沿触发中断
lds R2,_edge
tst R2
brne L51
.dbline 199
; {
.dbline 200
; if(bitcount < 11 && bitcount > 2) //3到10位是数据,起始位,校验位和停止位忽略
lds R24,_bitcount
cpi R24,11
brsh L53
ldi R24,2
lds R2,_bitcount
cp R24,R2
brsh L53
.dbline 201
; {
.dbline 202
; data = (data >> 1); //右移保存数据
lds R2,L50
lsr R2
sts L50,R2
.dbline 203
; if(PINA&0x01)
sbis 0x19,0
rjmp L55
.dbline 204
; {
.dbline 205
; data|=0x80; //存储一个'1'
mov R24,R2
ori R24,128
sts L50,R24
.dbline 206
; }
L55:
.dbline 207
; }
L53:
.dbline 208
; MCUCR=3; //设置INT0为上升沿触发中断
ldi R24,3
out 0x35,R24
.dbline 209
; edge=1; //设置上升沿中断标志
ldi R24,1
sts _edge,R24
.dbline 210
; }
xjmp L52
L51:
.dbline 212
; else //如果是上升沿触发中断
; {
.dbline 213
; MCUCR=2; //设置INT0为下降沿触发中断
ldi R24,2
out 0x35,R24
.dbline 214
; edge=0; //设置下降沿中断标志
clr R2
sts _edge,R2
.dbline 215
; if(--bitcount==0) //如果11位全部接收完毕
lds R24,_bitcount
subi R24,1
mov R2,R24
sts _bitcount,R2
tst R24
brne L57
.dbline 216
; {
.dbline 217
; Decode(data); //将扫描码翻译成ASCII码
lds R16,L50
xcall _Decode
.dbline 218
; bitcount = 11; //重新设为11位数据
ldi R24,11
sts _bitcount,R24
.dbline 219
; }
L57:
.dbline 220
L52:
.dbline -2
.dbline 221
; }
; }
L49:
xcall pop_lset
.dbline 0 ; func end
reti
.dbend
.area data(ram, con, rel)
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
L60:
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
L61:
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
.area text(rom, con, rel)
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
.dbfunc e Decode _Decode fV
.dbsym s shift L61 c
.dbsym s up L60 c
; i -> R20
; scancode -> R16
.even
_Decode::
xcall push_gset1
.dbline -1
.dbline 229
; /*******************************************
; 函数名称: Decode
; 功 能:
; 参 数: scancode--需要翻译的扫描码
; 返回值 : 无
; /********************************************/
; void Decode(uchar scancode)
; {
.dbline 232
; static uchar up=0,shift=0; //up为通、断码标志,shift为shift键按下标志
; uchar i;
; if (!up) //已接收的11位数据是通码(up为0)
lds R2,L60
tst R2
breq X3
xjmp L62
X3:
.dbline 233
; {
.dbline 234
; switch (scancode)//开始翻译扫描码
mov R20,R16
clr R21
cpi R20,89
ldi R30,0
cpc R21,R30
breq L69
ldi R24,89
ldi R25,0
cp R24,R20
cpc R25,R21
brlt L89
L88:
cpi R20,18
ldi R30,0
cpc R21,R30
breq L68
xjmp L64
L89:
cpi R20,240
ldi R30,0
cpc R21,R30
breq L67
xjmp L64
X1:
.dbline 235
; {
L67:
.dbline 237
; case 0xF0: //键盘释放标志(随后的一个字节是断码)
; up=1; //设置up为断码标志
ldi R24,1
sts L60,R24
.dbline 238
; break;
xjmp L63
L68:
.dbline 240
; case 0x12: //左shift键按下
; shift=1; //设置shift为按下标志
ldi R24,1
sts L61,R24
.dbline 241
; break;
xjmp L63
L69:
.dbline 243
; case 0x59: //右shift键按下
; shift=1; //设置shift为按下标志
ldi R24,1
sts L61,R24
.dbline 244
; break;
xjmp L63
L64:
.dbline 246
; default:
; if(!shift) //如果shift键没有按下
lds R2,L61
tst R2
brne L70
.dbline 247
; { //查找unshifted表,表中左列是扫描码,右列是对应的ASCII码
.dbline 248
clr R20
xjmp L75
L72:
.dbline 248
L73:
.dbline 248
inc R20
L75:
.dbline 248
; for(i=0;unshifted[i][0]!=scancode&&unshifted[i][0];i++);
ldi R24,2
mul R24,R20
movw R30,R0
ldi R24,<_unshifted
ldi R25,>_unshifted
add R30,R24
adc R31,R25
lpm R2,Z
clr R3
cp R2,R16
breq L76
tst R2
brne L72
L76:
.dbline 249
; if(unshifted[i][0]==scancode)
ldi R24,2
mul R24,R20
movw R30,R0
ldi R24,<_unshifted
ldi R25,>_unshifted
add R30,R24
adc R31,R25
lpm R30,Z
cp R30,R16
breq X4
xjmp L63
X4:
.dbline 250
; {
.dbline 251
; ascii=unshifted[i][1];
ldi R24,2
mul R24,R20
movw R30,R0
ldi R24,<_unshifted+1
ldi R25,>_unshifted+1
add R30,R24
adc R31,R25
lpm R30,Z
sts _ascii,R30
.dbline 252
; }
.dbline 253
; }
xjmp L63
L70:
.dbline 255
; else //如果shift键按下
; { //查找shifted表
.dbline 256
clr R20
xjmp L83
L80:
.dbline 256
L81:
.dbline 256
inc R20
L83:
.dbline 256
; for(i=0;shifted[i][0]!=scancode&&shifted[i][0];i++);
ldi R24,2
mul R24,R20
movw R30,R0
ldi R24,<_shifted
ldi R25,>_shifted
add R30,R24
adc R31,R25
lpm R2,Z
clr R3
cp R2,R16
breq L84
tst R2
brne L80
L84:
.dbline 257
; if(shifted[i][0]==scancode)
ldi R24,2
mul R24,R20
movw R30,R0
ldi R24,<_shifted
ldi R25,>_shifted
add R30,R24
adc R31,R25
lpm R30,Z
cp R30,R16
brne L63
.dbline 258
; {
.dbline 259
; ascii=shifted[i][1];
ldi R24,2
mul R24,R20
movw R30,R0
ldi R24,<_shifted+1
ldi R25,>_shifted+1
add R30,R24
adc R31,R25
lpm R30,Z
sts _ascii,R30
.dbline 260
; }
.dbline 261
; }
.dbline 262
; break;
.dbline 264
; }
; }
xjmp L63
L62:
.dbline 266
; else //已接收的11位数据是断码(up为1)
; {
.dbline 267
; up = 0; //将断码标志复位
clr R2
sts L60,R2
.dbline 268
; switch (scancode) //检测shift键释放
mov R20,R16
clr R21
cpi R20,18
ldi R30,0
cpc R21,R30
breq L93
cpi R20,18
ldi R30,0
cpc R21,R30
brlt L91
L95:
cpi R20,89
ldi R30,0
cpc R21,R30
breq L94
xjmp L91
X2:
.dbline 269
; {
L93:
.dbline 271
; case 0x12 : //左shift键
; shift = 0;
clr R2
sts L61,R2
.dbline 272
; break;
xjmp L91
L94:
.dbline 274
; case 0x59 : //右shift键
; shift = 0;
clr R2
sts L61,R2
.dbline 275
; break;
.dbline 277
; default:
; break;
L91:
.dbline 279
L63:
.dbline -2
.dbline 280
; }
; }
; }
L59:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbsym r scancode 16 c
.dbend
.dbfunc e main _main fV
.even
_main::
.dbline -1
.dbline 288
; /*******************************************
; 函数名称: main
; 功 能: 实现PS2键盘的驱动,在1602液晶上显示键盘上的ASCII码
; 参 数: 无
; 返回值 : 无
; /********************************************/
; void main(void)
; {
.dbline 289
; Board_init( ); //初始化开发板
xcall _Board_init
.dbline 290
; LCD1602_initial( ); //初始化1602
xcall _LCD1602_initial
.dbline 291
; Init_kb(); //初始化PS2键盘接口
xcall _Init_kb
xjmp L98
L97:
.dbline 293
.dbline 294
lds R16,_ascii
xcall _Disp_ascii
.dbline 295
L98:
.dbline 292
xjmp L97
X5:
.dbline -2
.dbline 296
; while(1)
; {
; Disp_ascii(ascii); //显示翻译后的ASCII码
; }
; }
L96:
.dbline 0 ; func end
ret
.dbend
.area bss(ram, con, rel)
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
_bitcount::
.blkb 1
.dbsym e bitcount _bitcount c
_edge::
.blkb 1
.dbsym e edge _edge c
.area data(ram, con, rel)
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
L48:
.blkb 11
.area idata
.byte 'K,'E,'Y,95,'A,'S,'C,'I,'I,58,0
.area data(ram, con, rel)
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\19_PS2\PS2_KB.C
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -