⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyboard.asm

📁 一个键盘模拟器的源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;==========================================
;function: moniter ps2 bus,get command from ps2(keyboard to pc)
;so we can start a communication with pc
;no output clk, listen keyboard send start
;input: no
;output: no
rec_from_key:
        ldi   temp,key_board_err
        mov   cmd_register,temp
        sbic  ps2_dat_in_addr,ps2_dat               ;dat =0 ,start,then low pulse of clk
        rjmp  pc_to_keyboard
rec_key_start:
        ldi key_bit_count,  8
        ldi parity, 0x00
rec_key_loop:
        sbis  ps2_clk_in_addr,ps2_clk               ;clk -> high
        rjmp  $-2
        sbic  ps2_clk_in_addr,ps2_clk               ;clk -> low
        rjmp  $-2
        clc
        sbic  ps2_dat_in_addr,ps2_dat               ;recieve a bit
        sec
        ror   key_bit_buffer
        sbrc  key_bit_buffer,  7
        inc   parity
rec_key_loop1:
        dec   key_bit_count
        brne  rec_key_loop
        sbis  ps2_clk_in_addr,ps2_clk               ;clk -> high
        rjmp  $-2
        sbic  ps2_clk_in_addr,ps2_clk               ;clk -> low
        rjmp  $-2
        sbic  ps2_dat_in_addr,ps2_dat             ;parity bit
        inc   parity                    ;xor rx8 ,here,result must be a 1
        sbis  ps2_clk_in_addr,ps2_clk               ;clk -> high
        rjmp  $-2
        sbic  ps2_clk_in_addr,ps2_clk               ;clk -> low
        rjmp  $-2
        sbis  ps2_dat_in_addr,ps2_dat             ;stop
        ret                                       ;stop error,find  new start bit again
        sbrs  parity, 0                           ;partiy xor rx8 = 1,odd success
        ret                                       ;parity error,find a new start bit
;        st    y+,   key_bit_buffer               ;just for test key rec,for send to uart
        sbis  ps2_clk_in_addr,ps2_clk               ;clk -> high
        rjmp  $-2
        clr   cmd_register
        ret
pc_to_keyboard:
        sbis  ps2_clk_in_addr,ps2_clk
        rjmp  $-2                      ;wait for clk high,show next clk can be detected
        ldi   temp,no_key_in
        mov   cmd_register,temp
        ret
;=================================================
/************** with break ************************
listen_ps2:
        sbic  ps2_clk_in_addr,ps2_clk               ;keyboard_clk -> low
        ret
        clr   counter1                              ;for make
        clr   counter2                              ;for break
        ldi   ZH, key_buffer_high
        ldi   ZL, key_buffer_low
        brie  listen_ps2_loop
        cli                                         ;protect realtime signal
        ori app_state,en_ie
listen_ps2_loop:
        wdr
        sbic  ps2_clk_in_addr,ps2_clk               ;keyboard_clk -> low
        rjmp  listen_ps2_loop
        rcall rec_from_key                          ;get make
        mov temp,cmd_register
        cpi temp,no_key_in
        breq   listen_ps2_loop                      ;a mouse clk occure
        cpi   temp, cmd_ok
        brne  listen_ps2_error11                      ;parity error or stop bit losed
;****** for repeat **************
        cpi   counter1,0                            ;first key
        breq  save_new_key
        mov   temp, key_bit_buffer
        cpi   temp,0xe1                             ;e1 no repeat,but lose other break
        brne  func_repeat_e0
        ldi   XH, key_buffer_high                   ;e1,return to counter = 0
        ldi   XL, key_buffer_low
        ld    temp, X
        cpi   temp,0xe1
        breq  save_new_key
        ldi   ZH, key_buffer_high                   ;first e1,return to counter = 0
        ldi   ZL, key_buffer_low
        clr   counter1
        clr   counter2
        rjmp  save_new_key
listen_ps2_error11:
        rjmp  listen_ps2_error
func_repeat_e0:
        cpi   temp,   0xe0
        brne  repeat_current
        rjmp  save_new_key
repeat_current:
        ld    temp, -Z                              ;current key
        ld    temp1,Z+
        cp    temp, key_bit_buffer
        breq  listen_ps2_loop                       ;normal repeat

        cpi   counter1, 0x02
        brlo  save_new_key
        cpi   temp,   0xe0                          ;current key = e0,now we must find ahead
        brne  save_new_key
        ld    temp,-Z                               ;current
        ld    temp,-Z                               ;last,the next is e0
        cp    temp, key_bit_buffer
        breq  function_repeat                       ;repeat
        ld    temp, Z+                              ;z->current
        ld    temp, Z+                              ;z->new
        rjmp  save_new_key
function_repeat:
        dec   counter1
        dec   counter1
        ld    temp, Z+
        rjmp  listen_ps2_loop

save_new_key:
        mov   temp,key_bit_buffer
        cpi   temp, 0xf0
        breq  listen_ps2_break
        st    Z+, key_bit_buffer
        inc counter1
;**********count for break ***************
        mov   temp, key_bit_buffer

        cpi   temp,0xe1
        breq  listen_ps2_loop
        cpi   temp,0xe0
        breq  listen_ps2_loop       ;e0,function key,then get the real key value
        inc   counter2
        rjmp  listen_ps2_loop       ;get next push down key
listen_ps2_break:

	out	UDR,counter2
	sbis	UCSRA,UDRE
	rjmp	$-2
listen_ps2_break01:
        wdr
        dec     counter2            ;get a key pop up
        breq  listen_ps2_break03
listen_ps2_break02:
        sbic  ps2_clk_in_addr,ps2_clk               ;keyboard_clk -> low
        rjmp  listen_ps2_break02
        rcall rec_from_key                          ;get break
        mov temp,cmd_register
        cpi temp,no_key_in
        breq   listen_ps2_break02                   ;a mouse clk occure
        cpi   temp, cmd_ok
        brne  listen_ps2_error                      ;parity error or stop bit losed
        mov   temp,key_bit_buffer
        cpi   temp,0xf0
        brne  listen_ps2_break02                    ;not f0,just real key,half of break
        rjmp  listen_ps2_break01  ; dec   counter2                              ;get a break start
        ;brne  listen_ps2_break01                    ;get real key,and next f0
listen_ps2_break03:
        wdr
        sbic  ps2_clk_in_addr,ps2_clk               ;keyboard_clk -> low
        rjmp  listen_ps2_break03
        rcall rec_from_key                          ;get last break
        mov temp,cmd_register
        cpi temp,no_key_in
        breq   listen_ps2_break03                   ;a mouse clk occure
        cpi   temp, cmd_ok
        brne  listen_ps2_error                      ;parity error or stop bit losed
;----------------------------------------
;now get a sort of key value,we can compare with config item
/****************** without break ******************/
;=================================================
listen_ps2:
        ;cpi   app_state,  init_state
        ;breq  test_key_data
        ;ret
        ;cpi   app_state,  card_upload_state
       ; breq  test_key_data
        ;ret
test_key_data:
        sbic  ps2_dat_in_addr,ps2_dat               ;keyboard_data -> low
        ret
        clr   find_card_timer1
        clr   find_card_timer2
        clr   counter1                              ;for make
        ldi   ZH, key_buffer_high
        ldi   ZL, key_buffer_low
        cli
        ;protect realtime signal
listen_ps2_loop_data:
        wdr
        sbic  ps2_clk_in_addr,ps2_clk               ;keyboard_clk -> low
        rjmp  listen_ps2_loop_data
        rcall rec_from_key                          ;get make
        mov   temp,cmd_register
        cpi   temp,no_key_in
        breq  listen_ps2_loop                      ;a mouse clk occure
        cpi   temp, cmd_ok
        brne  listen_ps2_error11                      ;parity error or stop bit losed
/****** for repeat **************/
        cpi   counter1,0                            ;first key
        breq  save_new_key
        mov   temp, key_bit_buffer
        cpi   temp,0xe1                             ;e1 no repeat,but lose other break
        brne  func_repeat_e0
        ldi   XH, key_buffer_high                   ;e1,return to counter = 0
        ldi   XL, key_buffer_low
        ld    temp, X
        cpi   temp,0xe1
        breq  save_new_key
        ldi   ZH, key_buffer_high                   ;first e1,return to counter = 0
        ldi   ZL, key_buffer_low
        clr   counter1
        rjmp  save_new_key
listen_ps2_loop:
        wdr
        sbic  ps2_dat_in_addr,ps2_dat               ;keyboard_data -> low
        rjmp  listen_ps2_loop
        rjmp  listen_ps2_loop_data

listen_ps2_error11:
        rjmp  listen_ps2_error
func_repeat_e0:
        cpi   temp,   0xe0
        brne  repeat_current
        rjmp  save_new_key
repeat_current:
        ld    temp, -Z                              ;current key
        ld    temp1,Z+
        cp    temp, key_bit_buffer
        breq  listen_ps2_loop                       ;normal repeat

        cpi   counter1, 0x02
        brlo  save_new_key
        cpi   temp,   0xe0                          ;current key = e0,now we must find ahead
        brne  save_new_key
        ld    temp,-Z                               ;current
        ld    temp,-Z                               ;last,the next is e0
        cp    temp, key_bit_buffer
        breq  function_repeat                       ;repeat
        ld    temp, Z+                              ;z->current
        ld    temp, Z+                              ;z->new
        rjmp  save_new_key
function_repeat:
        dec   counter1
        dec   counter1
        ld    temp, Z+
        rjmp  listen_ps2_loop

save_new_key:
        mov   temp,key_bit_buffer
        cpi   temp, 0xf0
        breq  listen_ps2_break
        st    Z+, key_bit_buffer
        inc   counter1
        rjmp  listen_ps2_loop       ;get next push down key
;----------------------------------------
listen_ps2_break:
;here must delay any time or do something,because break code after f0 would be recongnized as a make code,
;and program will wait another f0 as break,so,betwin two key,nothing can do

        cpi     counter1,0
        breq    no_item_equ         ;recieve no make,just break
  ;rjmp test_send_out_key
//test  ctrl+d    for download config table
/*  ********** for release key *************  2006 9 19 remove
        ldi   temp1,10
        rcall   delay_mS
        wdr
        ldi   temp1,10
        rcall   delay_mS
        wdr
        ldi   temp1,10
        rcall   delay_mS
        */
        wdr
        ldi   ZH,key_buffer_high
        ldi   ZL,key_buffer_low
        clc
        add   ZL,counter1
        adc   ZH,zero_register
        ld    temp,-Z
        cpi   temp,0x23
        brne  goto_lookfor_table
        ld    temp,-Z
        cpi   temp,0x14
        brne  goto_lookfor_table
        rcall download_key_table          ;download config table
        rjmp  exit_ps2_listen
goto_lookfor_table:
/* *********** looking for code *********** *
        ldi   YH, key_buffer_high
        ldi   YL, key_buffer_low
        clc
        add   YL,counter1
        adc   YH,zero_register            ;after last key in buffer
        clr   counter2
        ldi   ZH,high(key_table_func)
        ldi   ZL,low(key_table_func)
        adiw  ZL,2                        ;last key in item1
        lpm
        ld    temp,-Y                     ;last key in buffer
look_for_item:
        cp    temp,R0
        breq  find_equ_item
        inc   counter2                    ;item_index
        clc
        ldi   temp1,0x03
        add   ZL,temp1                        ;next item
        adc   ZH,zero_register
        lpm
        cp    R0, zero_register           ;end of table
        brne  look_for_item
no_item_equ:
        rjmp  exit_ps2_listen
find_equ_item:
        ld    temp,-Z
        lpm
        cp    R0,zero_register            ;second in table
        breq  goto_send_command
        dec   counter1
        breq  no_item_equ
        ld    temp,-Y                     ;before the last key
        cp    temp,R0
        brne  no_item_equ
        ld    temp,-Z
        lpm
        cp    R0,zero_register
        breq  goto_send_command
        dec   counter1
        breq  no_item_equ
        ld    temp,-Y
        cp    temp,R0
        brne  no_item_equ
/*********************************************************/
/* *************** looking for eeprom ****************** */
        ldi   YH, key_buffer_high
        ldi   YL, key_buffer_low
        clc
        add   YL,counter1
        adc   YH,zero_register            ;after last key in buffer
        clr   counter2
        ldi   eeprom_addrl,EEP_SEX           ;item1.0
        dec   eeprom_addrl                  ;item0.2
        clr   eeprom_addrh
        rcall read_eeprom
        ld    temp,-Y                     ;last key in buffer
look_for_item:
        wdr
        cp    temp,eeprom_data
        breq  find_equ_item
look_for_like_item:                        ;add 2006 9 19 for same num item
        inc   counter2                    ;item_index
        clc
        ldi   temp1,0x03
        add   eeprom_addrl,temp1                        ;next item
        rcall read_eeprom
        ldi   temp1,0xff
        cp    eeprom_data, temp1           ;end of table
        brne  look_for_item
no_item_equ:
        rcall delay_200ms
        rcall delay_200ms
        rcall delay_200ms
        rjmp  exit_ps2_listen
look_for_like_item04:
look_for_like_item03:
        inc   counter1                    ;before last
look_for_like_item02:
look_for_like_item01:
        inc   counter1                    ;last key in buffer
        ldi   temp,3
        push  r1
        mul   counter2,temp
        ldi   eeprom_addrl,EEP_SEX           ;item1.0
        dec   eeprom_addrl
        clr   eeprom_addrh
        add   eeprom_addrl,r0             ;current item.2
        pop   r1
                                          ;rewind point to last key ,and get last key
        ldi   YH, key_buffer_high
        ldi   YL, key_buffer_low
        clc
        add   YL,counter1
        adc   YH,zero_register            ;after last key in buffer
        ld    temp,-Y                     ;last key in buffer
        rjmp  look_for_like_item          ;next item same last key
find_equ_item:
        dec   eeprom_addrl
        rcall read_eeprom
        cp    eeprom_data,zero_register            ;second in table
        breq  goto_send_command                  ;0 means item compare completed,ok
        dec   counter1
;        breq  no_item_equ                 ;eeprom item have some keyvalue,but buffer recieved little than eeprom,so item not complete
        breq  look_for_like_item01           ;looking for some like item
        ld    temp,-Y                     ;before the last key
        cp    temp,eeprom_data
;        brne  no_item_equ
        brne  look_for_like_item02           ;looking for some like item
        dec   eeprom_addrl
        rcall read_eeprom
        cp    eeprom_data,zero_register
        breq  goto_send_command02
        dec   counter1
;        brne  no_item_equ
        brne  look_for_like_item03           ;looking for some like item
        ld    temp,-Y
        cp    temp,eeprom_data
;        brne  no_item_equ
        brne  look_for_like_item04           ;looking for some like item
        inc   counter1                       ;old counter1
goto_send_command02:
        inc   counter1                       ;old counter1
/**********************************************/
goto_send_command:
;        rcall delay_200ms             ;for release key 2006 9 19 remove

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -