📄 keyboard.lst
字号:
__text_start:
__start:
00BF E5CF LDI R28,0x5F
00C0 E0D4 LDI R29,4
00C1 BFCD OUT 0x3D,R28
00C2 BFDE OUT 0x3E,R29
00C3 51C0 SUBI R28,0x10
00C4 40D0 SBCI R29,0
00C5 EA0A LDI R16,0xAA
00C6 8308 STD Y+0,R16
00C7 2400 CLR R0
00C8 E7EA LDI R30,0x7A
00C9 E0F0 LDI R31,0
00CA E010 LDI R17,0
00CB 3BEF CPI R30,0xBF
00CC 07F1 CPC R31,R17
00CD F011 BEQ 0x00D0
00CE 9201 ST R0,Z+
00CF CFFB RJMP 0x00CB
00D0 8300 STD Z+0,R16
00D1 E6E4 LDI R30,0x64
00D2 E0F1 LDI R31,1
00D3 E6A0 LDI R26,0x60
00D4 E0B0 LDI R27,0
00D5 E011 LDI R17,1
00D6 37EE CPI R30,0x7E
00D7 07F1 CPC R31,R17
00D8 F021 BEQ 0x00DD
00D9 95C8 LPM
00DA 9631 ADIW R30,1
00DB 920D ST R0,X+
00DC CFF9 RJMP 0x00D6
00DD 940E022C CALL _main
_exit:
00DF CFFF RJMP _exit
FILE: F:\李鹏飞\sl-avrad-m16\键盘演示程序\Keyboard.c
(0001) /******************************************/
(0002) /* 广州天河双龙电子公司 */
(0003) /* http://www.sl.com.cn */
(0004) /* PS2键盘驱动程序 */
(0005) /* 作者:lpf@sl.com.cn */
(0006) /* 2003年8月28日 */
(0007) /* 目标MCU:MEGA16 晶振:外部(EXT) 8MHZ */
(0008) /******************************************/
(0009) #include<iom16v.h>
(0010) #include<macros.h>
(0011) #define PIN_DIR DDRD
(0012) #define PIN_KB PIND
(0013) #define PORT_KB PORTD
(0014) #define CLOCK 3
(0015) #define DATAPIN 2
(0016) #define BUFF_SIZE 64
(0017) #define fosc 8000000
(0018) //晶振8MHZ
(0019) #define baud 19200
(0020) //波特率
(0021) #pragma data:code
(0022) //设置数据区为程序存储器
(0023) //没有按下shift键的PC机键盘扫描码
(0024) const unsigned char unshifted[][2] = {
(0025) 0x0d,9,0x0e,'`',0x15,'q',0x16,'1',0x1a,'z',0x1b,'s',0x1c,'a',0x1d,'w',0x1e,'2',
(0026) 0x21,'c',0x22,'x',0x23,'d',0x24,'e',0x25,'4',0x26,'3',0x29,' ',0x2a,'v',0x2b,'f',0x2c,'t',0x2d,'r',0x2e,'5',
(0027) 0x31,'n',0x32,'b',0x33,'h',0x34,'g',0x35,'y',0x36,'6',0x39,',',0x3a,'m',0x3b,'j',0x3c,'u',0x3d,'7',0x3e,'8',
(0028) 0x41,',',0x42,'k',0x43,'i',0x44,'o',0x45,'0',0x46,'9',0x49,'.',0x4a,'/',0x4b,'l',0x4c,';',0x4d,'p',0x4e,'-',
(0029) 0x52,0x27,0x54,'[',0x55,'=',0x5a,13, 0x5b,']',0x5d,0x5c,0x61,'<',0x66,8,0x69,'1',0x6b,'4',0x6c,'7',
(0030) 0x70,'0',0x71,',',0x72,'2',0x73,'5',0x74,'6',0x75,'8',0x79,'+',0x7a,'3',0x7b,'-',0x7c,'*',0x7d,'9',0,0
(0031) };
(0032) //按下shift键的PC机键盘扫描码
(0033) const unsigned char shifted[][2] = {
(0034) 0x0d,9,0x0e,'~',0x15,'Q',0x16,'!',0x1a,'Z',0x1b,'S',0x1c,'A',0x1d,'W',0x1e,'@',
(0035) 0x21,'C',0x22,'X',0x23,'D',0x24,'E',0x25,'$',0x26,'#',0x29,' ',0x2a,'V',0x2b,'F',0x2c,'T',0x2d,'R',0x2e,'%',
(0036) 0x31,'N',0x32,'B',0x33,'H',0x34,'G',0x35,'Y',0x36,'^',0x39,'L',0x3a,'M',0x3b,'J',0x3c,'U',0x3d,'&',0x3e,'*',
(0037) 0x41,'<',0x42,'K',0x43,'I',0x44,'O',0x45,')',0x46,'(',0x49,'>',0x4a,'?',0x4b,'L',0x4c,':',0x4d,'P',0x4e,'_',
(0038) 0x52,'"',0x54,'{',0x55,'+',0x5a,13, 0x5b,'}',0x5d,'|',0x61,'>',0x66,8,0x69,'1',0x6b,'4',0x6c,'7',
(0039) 0x70,'0',0x71,',',0x72,'2',0x73,'5',0x74,'6',0x75,'8',0x79,'+',0x7a,'3',0x7b,'-',0x7c,'*',0x7d,'9',0,0
(0040) };
(0041) #pragma data:data
(0042) //设置数据区回到数据存储器
(0043) unsigned char bitcount; //pc键盘数据长度计数
(0044) unsigned char kb_buffer[BUFF_SIZE]; //键盘缓冲区
(0045) unsigned char input=0; //缓冲区读指针
(0046) unsigned char output=0; //缓冲区写指针
(0047) //键盘缓冲区使用软件模拟FIFO
(0048) void put_kbbuff(unsigned char c) //送键盘按键ASCII码到键盘缓冲区
(0049) {
(0050) kb_buffer[input]=c;
_put_kbbuff:
c --> R16
00E0 E78E LDI R24,0x7E
00E1 E090 LDI R25,0
00E2 91E00060 LDS R30,0x60
00E4 27FF CLR R31
00E5 0FE8 ADD R30,R24
00E6 1FF9 ADC R31,R25
00E7 8300 STD Z+0,R16
(0051) if (input<(BUFF_SIZE-1))
00E8 91800060 LDS R24,0x60
00EA 338F CPI R24,0x3F
00EB F420 BCC 0x00F0
(0052) input++;
00EC 5F8F SUBI R24,0xFF
00ED 93800060 STS 0x60,R24
00EF C003 RJMP 0x00F3
(0053) else
(0054) input=0;
00F0 2422 CLR R2
00F1 92200060 STS 0x60,R2
(0055) }
00F3 9508 RET
(0056) unsigned char get_char(void) //从键盘缓冲区读取按键的ASCII码
(0057) {
(0058) unsigned char temp;
(0059) if (output==input)
_get_char:
temp --> R16
00F4 90200060 LDS R2,0x60
00F6 90300061 LDS R3,0x61
00F8 1432 CP R3,R2
00F9 F411 BNE 0x00FC
(0060) return 0;
00FA 2700 CLR R16
00FB C013 RJMP 0x010F
(0061) else
(0062) {
(0063) temp=kb_buffer[output];
00FC E78E LDI R24,0x7E
00FD E090 LDI R25,0
00FE 91E00061 LDS R30,0x61
0100 27FF CLR R31
0101 0FE8 ADD R30,R24
0102 1FF9 ADC R31,R25
0103 8100 LDD R16,Z+0
(0064) if (output<(BUFF_SIZE-1))
0104 91800061 LDS R24,0x61
0106 338F CPI R24,0x3F
0107 F420 BCC 0x010C
(0065) output++;
0108 5F8F SUBI R24,0xFF
0109 93800061 STS 0x61,R24
010B C003 RJMP 0x010F
(0066) else
(0067) output=0;
010C 2422 CLR R2
010D 92200061 STS 0x61,R2
(0068) return temp;
010F 9508 RET
(0069) }
(0070) }
(0071) void uart_init(void)
(0072) {
(0073) UCSRB=(1<<RXEN)|(1<<TXEN); //允许发送和接收
_uart_init:
0110 E188 LDI R24,0x18
0111 B98A OUT 0x0A,R24
(0074) UBRRL=(fosc/16/(baud+1))%256;
0112 E18A LDI R24,0x1A
0113 B989 OUT 0x09,R24
(0075) UBRRH=(fosc/16/(baud+1))/256; //波特率19200
0114 2422 CLR R2
0115 BC20 OUT 0x20,R2
(0076) UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //8位数据+1位STOP位
0116 E886 LDI R24,0x86
0117 BD80 OUT 0x20,R24
(0077) }
0118 9508 RET
(0078) void putchar(unsigned char c)
(0079) {
(0080) while (!(UCSRA&(1<<UDRE)));
_putchar:
c --> R16
0119 9B5D SBIS 0x0B,5
011A CFFE RJMP _putchar
(0081) UDR=c;
011B B90C OUT 0x0C,R16
(0082) }
011C 9508 RET
_puts:
s --> R10
011D 940E0254 CALL push_gset3x
011F 0158 MOVW R10,R16
(0083) int puts(char *s)
(0084) {
0120 C006 RJMP 0x0127
(0085) while (*s)
(0086) {
(0087) putchar(*s);
0121 01F5 MOVW R30,R10
0122 8100 LDD R16,Z+0
0123 DFF5 RCALL _putchar
(0088) s++;
0124 01C5 MOVW R24,R10
0125 9601 ADIW R24,1
0126 015C MOVW R10,R24
0127 01F5 MOVW R30,R10
0128 8020 LDD R2,Z+0
0129 2022 TST R2
012A F7B1 BNE 0x0121
(0089) }
(0090) putchar(0x0a); //回车换行
012B E00A LDI R16,0xA
012C DFEC RCALL _putchar
(0091) putchar(0x0d);
012D E00D LDI R16,0xD
012E DFEA RCALL _putchar
(0092) return 1;
012F E001 LDI R16,1
0130 E010 LDI R17,0
0131 940E0245 CALL pop_gset3x
0133 9508 RET
(0093) }
(0094) void init_kb(void)
(0095) {
(0096) PIN_DIR&=~((1<<CLOCK)|(1<<DATAPIN));
_init_kb:
0134 B381 IN R24,0x11
0135 7F83 ANDI R24,0xF3
0136 BB81 OUT 0x11,R24
(0097) PORT_KB|=(1<<CLOCK)|(1<<DATAPIN);
0137 B382 IN R24,0x12
0138 608C ORI R24,0xC
0139 BB82 OUT 0x12,R24
(0098) MCUCR = 0x08;
013A E088 LDI R24,0x8
013B BF85 OUT 0x35,R24
(0099) GICR = 0x80;
013C E880 LDI R24,0x80
013D BF8B OUT 0x3B,R24
(0100) SEI();
013E 9478 BSET 7
(0101) bitcount = 11;
013F E08B LDI R24,0xB
0140 938000BE STS _bitcount,R24
(0102) }
0142 9508 RET
_decode:
i --> R10
sc --> R12
0143 940E025B CALL push_gset5x
0145 2EC0 MOV R12,R16
(0103)
(0104)
(0105) void decode(unsigned char sc) //对PC键盘的扫描码进行解码
(0106) {
(0107) static unsigned char shift,up,shiftup;
(0108) unsigned char i;
(0109) if (sc==0xf0) //按键释放
0146 2D8C MOV R24,R12
0147 3F80 CPI R24,0xF0
0148 F421 BNE 0x014D
(0110) {
(0111) up=1;
0149 E081 LDI R24,1
014A 9380007B STS 0x7B,R24
(0112) return;
014C C08C RJMP 0x01D9
(0113) }
(0114) if (up==1) //SHIFT键开关
014D 9180007B LDS R24,0x7B
014F 3081 CPI R24,1
0150 F509 BNE 0x0172
(0115) {
(0116) up=0;
0151 2422 CLR R2
0152 9220007B STS 0x7B,R2
(0117) if ((sc==0x12)|(sc==0x59)) shift=0;
0154 2D8C MOV R24,R12
0155 3182 CPI R24,0x12
0156 F421 BNE 0x015B
0157 E081 LDI R24,1
0158 E090 LDI R25,0
0159 017C MOVW R14,R24
015A C002 RJMP 0x015D
015B 24EE CLR R14
015C 24FF CLR R15
015D 2D8C MOV R24,R12
015E 3589 CPI R24,0x59
015F F421 BNE 0x0164
0160 E081 LDI R24,1
0161 E090 LDI R25,0
0162 015C MOVW R10,R24
0163 C002 RJMP 0x0166
0164 24AA CLR R10
0165 24BB CLR R11
0166 0117 MOVW R2,R14
0167 282A OR R2,R10
0168 283B OR R3,R11
0169 2022 TST R2
016A F419 BNE 0x016E
016B 2033 TST R3
016C F409 BNE 0x016E
016D C06B RJMP 0x01D9
016E 2422 CLR R2
016F 9220007A STS 0x7A,R2
(0118) return;
0171 C067 RJMP 0x01D9
(0119) }
(0120) switch (sc) //检测左SHIFT键
0172 2CAC MOV R10,R12
0173 24BB CLR R11
0174 01C5 MOVW R24,R10
0175 3182 CPI R24,0x12
0176 E0E0 LDI R30,0
0177 079E CPC R25,R30
0178 F051 BEQ 0x0183
0179 3182 CPI R24,0x12
017A E0E0 LDI R30,0
017B 079E CPC R25,R30
017C F084 BLT 0x018D
017D 01C5 MOVW R24,R10
017E 3589 CPI R24,0x59
017F E0E0 LDI R30,0
0180 079E CPC R25,R30
0181 F031 BEQ 0x0188
0182 C00A RJMP 0x018D
(0121) {
(0122) case 0x12:{
(0123) shift=1;
0183 E081 LDI R24,1
0184 9380007A STS 0x7A,R24
(0124) shiftup=1;
0186 9380007C STS 0x7C,R24
(0125) }
(0126) case 0x59:{ //检测右SHIFT键
(0127) shift=1;
0188 E081 LDI R24,1
0189 9380007A STS 0x7A,R24
(0128) shiftup=1;
018B 9380007C STS 0x7C,R24
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -