📄 ps2.lst
字号:
__text_start:
__start:
A2 E5CF LDI R28,0x5F
A3 E0D4 LDI R29,4
A4 BFCD OUT 0x3D,R28
A5 BFDE OUT 0x3E,R29
A6 51CE SUBI R28,0x1E
A7 40D0 SBCI R29,0
A8 EA0A LDI R16,0xAA
A9 8308 STD Y+0,R16
AA 2400 CLR R0
AB E6E4 LDI R30,0x64
AC E0F0 LDI R31,0
AD E010 LDI R17,0
AE 36E5 CPI R30,0x65
AF 07F1 CPC R31,R17
B0 F011 BEQ 0x00B3
B1 9201 ST R0,Z+
B2 CFFB RJMP 0x00AE
B3 8300 STD Z+0,R16
B4 E4E0 LDI R30,0x40
B5 E0F1 LDI R31,1
B6 E6A0 LDI R26,0x60
B7 E0B0 LDI R27,0
B8 E011 LDI R17,1
B9 E000 LDI R16,0
BA BF0B OUT 0x3B,R16
BB 34E4 CPI R30,0x44
BC 07F1 CPC R31,R17
BD F021 BEQ 0x00C2
BE 95C8 LPM
BF 9631 ADIW R30,1
C0 920D ST R0,X+
C1 CFF9 RJMP 0x00BB
C2 940E 01CE CALL _main
_exit:
C4 CFFF RJMP _exit
_uart0_init:
tmp --> R10
baud --> R10
C5 940E 025C CALL push_xgsetF00C
C7 0158 MOVW R10,R16
FILE: D:\电子设计\AVR程序\PS2\PS2.C
(0001) #include<iom16v.h>
(0002) #include<macros.h>
(0003) #include "scancodes.h"
(0004)
(0005) #define F_CPU 8000000
(0006) #define Key_Data ((PIND&0x10)>>4)
(0007) #define Key_CLK ((PIND&0x08)>>3)
(0008) static unsigned char IntNum = 0; //中断次数计数
(0009) static unsigned char KeyV; //键值
(0010) static unsigned char Key_UP=0, Shift = 0;//Key_UP是键松开标识,Shift是Shift键按下标识
(0011) static unsigned char BF = 0; //标识是否有字符被收到
(0012)
(0013)
(0014)
(0015) /******************************************************************************/
(0016) /********************************串口的初始化**********************************/
(0017) //UART0 initialize
(0018) // desired baud rate: 9600
(0019) // actual: baud rate:9615 (0.2%)
(0020) void uart0_init(unsigned int baud)
(0021) {
(0022) unsigned int tmp;
(0023) /* 设置波特率*/
(0024) tmp= F_CPU/baud/16-1;
C8 0115 MOVW R2,R10
C9 2444 CLR R4
CA 2455 CLR R5
CB E040 LDI R20,0
CC E152 LDI R21,0x12
CD E76A LDI R22,0x7A
CE E070 LDI R23,0
CF 925A ST R5,-Y
D0 924A ST R4,-Y
D1 923A ST R3,-Y
D2 922A ST R2,-Y
D3 018A MOVW R16,R20
D4 019B MOVW R18,R22
D5 940E 01EE CALL div32s
D7 E140 LDI R20,0x10
D8 E050 LDI R21,0
D9 E060 LDI R22,0
DA E070 LDI R23,0
DB 937A ST R23,-Y
DC 936A ST R22,-Y
DD 935A ST R21,-Y
DE 934A ST R20,-Y
DF 940E 01EE CALL div32s
E1 0118 MOVW R2,R16
E2 0129 MOVW R4,R18
E3 E041 LDI R20,1
E4 E050 LDI R21,0
E5 E060 LDI R22,0
E6 E070 LDI R23,0
E7 1A24 SUB R2,R20
E8 0A35 SBC R3,R21
E9 0A46 SBC R4,R22
EA 0A57 SBC R5,R23
EB 0151 MOVW R10,R2
(0025) UBRRH = (unsigned char)(tmp>>8);
EC 2C23 MOV R2,R3
ED 2433 CLR R3
EE BC20 OUT 0x20,R2
(0026) UBRRL = (unsigned char)tmp;
EF B8A9 OUT 0x09,R10
(0027) /* 接收器与发送器使能*/
(0028) UCSRB = (1<<RXEN)|(1<<TXEN);
F0 E188 LDI R24,0x18
F1 B98A OUT 0x0A,R24
(0029) /* 设置帧格式: 8 个数据位, 2 个停止位*/
(0030) UCSRC = (1<<URSEL)|(1<<USBS)|(1<<UCSZ0)|(1<<UCSZ1);
F2 E88E LDI R24,0x8E
F3 BD80 OUT 0x20,R24
F4 940C 0263 JMP pop_xgsetF00C
(0031) }
(0032)
(0033)
(0034)
(0035)
(0036) // 数据发送【发送5 到8 位数据位的帧】
(0037) void USART_Transmit( unsigned char data )
(0038) {
(0039) /* 等待发送缓冲器为空 */
(0040) while ( !( UCSRA & (1<<UDRE)) )
_USART_Transmit:
data --> R16
F6 9B5D SBIS 0x0B,5
F7 CFFE RJMP _USART_Transmit
(0041) ;
(0042) /* 将数据放入缓冲器,发送数据 */
(0043) UDR = data;
F8 B90C OUT 0x0C,R16
F9 9508 RET
_int1_isr:
FA 921A ST R1,-Y
FB 922A ST R2,-Y
FC 923A ST R3,-Y
FD 938A ST R24,-Y
FE 939A ST R25,-Y
FF B61F IN R1,0x3F
100 921A ST R1,-Y
(0044) }
(0045)
(0046)
(0047)
(0048) #pragma interrupt_handler int1_isr:iv_INT1
(0049) void int1_isr(void)
(0050) {
(0051) if ((IntNum > 0) && (IntNum < 9))
101 9020 0060 LDS R2,PS2.C:IntNum
103 E080 LDI R24,0
104 1582 CP R24,R2
105 F488 BCC 0x0117
106 2D82 MOV R24,R2
107 3089 CPI R24,0x9
108 F470 BCC 0x0117
(0052) {
(0053) KeyV = KeyV >> 1; //因键盘数据是低>>高,结合上一句所以右移一位
109 9020 0064 LDS R2,PS2.C:KeyV
10B 9426 LSR R2
10C 9220 0064 STS PS2.C:KeyV,R2
(0054) if (Key_Data) KeyV = KeyV | 0x80; //当键盘数据线为1时为1到最高位
10E B380 IN R24,0x10
10F 7180 ANDI R24,0x10
110 9582 SWAP R24
111 708F ANDI R24,0xF
112 F021 BEQ 0x0117
113 2D82 MOV R24,R2
114 6880 ORI R24,0x80
115 9380 0064 STS PS2.C:KeyV,R24
(0055) }
(0056) IntNum++;
117 9180 0060 LDS R24,PS2.C:IntNum
119 5F8F SUBI R24,0xFF
11A 9380 0060 STS PS2.C:IntNum,R24
(0057) while (!Key_CLK); //等待PS/2CLK拉高
11C B380 IN R24,0x10
11D 7088 ANDI R24,0x8
11E 9586 LSR R24
11F 9586 LSR R24
120 9586 LSR R24
121 F3D1 BEQ 0x011C
(0058)
(0059) if (IntNum > 10)
122 E08A LDI R24,0xA
123 9020 0060 LDS R2,PS2.C:IntNum
125 1582 CP R24,R2
126 F438 BCC 0x012E
(0060) {
(0061) IntNum = 0; //当中断11次后表示一帧数据收完,清变量准备下一次接收
127 2422 CLR R2
128 9220 0060 STS PS2.C:IntNum,R2
(0062) BF = 1; //标识有字符输入完了
12A E081 LDI R24,1
12B 9380 0063 STS PS2.C:BF,R24
(0063) CLI(); //关中断等显示完后再开中断 (注:如这里不用BF和关中断直接调Decode()则所Decode中所调用的所有函数要声明为再入函数)
12D 94F8 BCLR 7
(0064) }
12E 9019 LD R1,Y+
12F BE1F OUT 0x3F,R1
130 9199 LD R25,Y+
131 9189 LD R24,Y+
132 9039 LD R3,Y+
133 9029 LD R2,Y+
134 9019 LD R1,Y+
135 9518 RETI
_Decode:
TempCyc --> R20
ScanCode --> R10
136 940E 0252 CALL push_xgset300C
138 2EA0 MOV R10,R16
(0065) }
(0066)
(0067) void Decode(unsigned char ScanCode) //注意:如SHIFT+G为12H 34H F0H 34H F0H 12H,也就是说shift的通码+G的通码+shift的断码+G的断码
(0068) {
(0069) unsigned char TempCyc;
(0070)
(0071) if (!Key_UP) //当键盘松开时
139 9020 0061 LDS R2,PS2.C:Key_UP
13B 2022 TST R2
13C F009 BEQ 0x013E
13D C072 RJMP 0x01B0
(0072) {
(0073) switch (ScanCode)
13E 2D4A MOV R20,R10
13F 2755 CLR R21
140 3549 CPI R20,0x59
141 E0E0 LDI R30,0
142 075E CPC R21,R30
143 F0B9 BEQ 0x015B
144 E589 LDI R24,0x59
145 E090 LDI R25,0
146 1784 CP R24,R20
147 0795 CPC R25,R21
148 F02C BLT 0x014E
149 3142 CPI R20,0x12
14A E0E0 LDI R30,0
14B 075E CPC R21,R30
14C F051 BEQ 0x0157
14D C011 RJMP 0x015F
14E 3F40 CPI R20,0xF0
14F E0E0 LDI R30,0
150 075E CPC R21,R30
151 F009 BEQ 0x0153
152 C00C RJMP 0x015F
(0074) {
(0075) case 0xF0 : // 当收到0xF0,Key_UP置1表示断码开始
(0076) Key_UP = 1;
153 E081 LDI R24,1
154 9380 0061 STS PS2.C:Key_UP,R24
(0077) break;
156 C072 RJMP 0x01C9
(0078)
(0079) case 0x12 : // 左 SHIFT
(0080) Shift = 1;
157 E081 LDI R24,1
158 9380 0062 STS PS2.C:Shift,R24
(0081) break;
15A C06E RJMP 0x01C9
(0082)
(0083) case 0x59 : // 右 SHIFT
(0084) Shift = 1;
15B E081 LDI R24,1
15C 9380 0062 STS PS2.C:Shift,R24
(0085) break;
15E C06A RJMP 0x01C9
(0086)
(0087) default:
(0088) //if (DisNum > 15)
(0089) //{
(0090) // DisplayListChar(0, 1, Cls);//清LCD第二行
(0091) // DisNum = 0;
(0092) //}
(0093) if(!Shift) //如果SHIFT没按下
15F 9020 0062 LDS R2,PS2.C:Shift
161 2022 TST R2
162 F539 BNE 0x018A
(0094) {
(0095) for (TempCyc = 0;(UnShifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++); //查表显示
163 2744 CLR R20
164 C001 RJMP 0x0166
165 9543 INC R20
166 E584 LDI R24,0x54
167 E090 LDI R25,0
168 2FE4 MOV R30,R20
169 27FF CLR R31
16A 0FEE LSL R30
16B 1FFF ROL R31
16C 0FE8 ADD R30,R24
16D 1FF9 ADC R31,R25
16E 9024 LPM R2,0(Z)
16F 142A CP R2,R10
170 F011 BEQ 0x0173
171 334B CPI R20,0x3B
172 F390 BCS 0x0165
(0096) if (UnShifted[TempCyc][0] == ScanCode)
173 E584 LDI R24,0x54
174 E090 LDI R25,0
175 2FE4 MOV R30,R20
176 27FF CLR R31
177 0FEE LSL R30
178 1FFF ROL R31
179 0FE8 ADD R30,R24
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -