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

📄 keys.asm

📁 Eversmith_-_AVRSMS for pdu mode
💻 ASM
字号:
;==========================================================
; This is a part of: Eversmith - AVRSMS
; Copyright (2003) Martin Thomas, Kaiserslautern,  Germany. 
; This  Software is  distributed  under  the Aladdin  Free 
; Public License (AFPL) Read the file license.txt included 
; in the distibution-package. See main-file for more infor-
; mation and license.
;==========================================================

; Input Key handling (debouncing)

;=========================================
; SRAM Labels
.dseg
; Push-Button-States for debouncing
KeyOldState:	.byte 1
KeyCount:		.byte 8
KeyOnMsg: 		.byte 1
KeyOffMsg:		.byte 1

.cseg

; Input-keys handled by this routines
; as bit-mask (0b00000001=only Pin0 is controlled by this;
; 0b11000011=Pins 7,6,1,0 are controlled by this routines)
; control in this application P0-P4 and P7 (for Menue)
.equ KEYMASK=0b10011111
; Keys are connected to PORTA
.equ KEYPORT=PORTA
.equ KEYDDR=DDRA
.equ KEYPIN=PINA
; number of counts for debouncing:
; this is the number of timer0 interrupts
; for which an input as to stay in the same state
; predefined are 10ms for the interrupt, so the
; key has to stay for KEYMAXCOUNT*10ms in the same
; state to be recognized as switched
.equ KEYMAXCOUNT=5	

;=========================================
; Init Input Key-State
;
; call this from the RESET-Handler
; Input for push-buttons - active LOW

KeysInit:
	push r16
	push r17
	push XL
	push XH

	; direction	
	in r16,KEYDDR				; old direction value
	ldi r17,KEYMASK				; load keymask
	com r17						; invert keymask
	and r16,r17					; mask unmanaged dirs.
	out	KEYDDR,r16				; set direction
	; pull-ups
	in r16,KEYPORT				; old pull-up-state
	ldi r17,KEYMASK				
	or r16,r17					; mask unmanaged pullups
	out KEYPORT,r16				; for input pins
	nop							; set pull-ups and sync
	; init Port-Change values used in T0OVR-Interrupt 
	; (debouncing)
	in r16,KEYPIN				; load actual state
	sts KEYOldState,r16			; save startup-key-state
	clr r16
	sts KEYOnMsg,r16			; clear "On"-"Messages"
	sts KEYOffMsg,r16			; dito for "Off"
	; clear counters
	ldi r16,KEYMAXCOUNT+2		; store maximum value to counters
	clr r17
	ldi XL,low(KEYCOUNT)		; set X to start of counter
	ldi XH,high(KEYCOUNT)		; array
KI_L1:
	st X+,r16					; store $00 to counter array
	inc r17
	cpi r17,$08					; all 8 counters?
	brne KI_L1					; no - go on
	
	pop XH
	pop XL
	pop r17
	pop r16
ret

;=========================================
; Clear Bits in "on"-Message
; Bit-Mask in r16
KeysClearOnMsg:
	push r16
	push r17
	com r16		; invert
	cli			; disable interrupt
	lds r17,KeyOnMsg
	and r17,r16
	sts KeyOnMsg,r17
	sei			; enable interrupt
	pop r17
	pop r16
ret

;=========================================
; Clear Bits in "off"-Message
; Bit-Mask in r16
KeysClearOffMsg:
	push r16
	push r17
	com r16		; invert
	cli			; disable interrupt
	lds r17,KeyOffMsg
	and r17,r16
	sts KeyOffMsg,r17
	sei			; enable interrupt
	pop r17
	pop r16
ret
	


;=========================================
; Key-IRQ-Handler
;
; call this from Inside a Timer-Interrupt-Handler
; example: 
;	PIN=0011 (3,2 on/1,0 off)
;  	OLD=1010 (2,0 on/3,1 off)
; PIN XOR OLD=1001 -> unchanged 0, changed 1
	
KeysIRQHandler:
	push r16
	push r17
	push r18
	push r19
	push r21
	push XL
	push XH

	ldi XL,low(KEYCOUNT)		; set X to start of counter
	ldi XH,high(KEYCOUNT)		; array

	in r16,KEYPIN		; load actual state
	lds r19,KeyOldState	; load old states from SRAM
	eor r19,r16			; Xor with old state
						; changed state results to 1 @ bit-pos.
	
	ldi r18,0b00000001	; mask for Pin_0
KeyIRQ_L1:
	mov r16,r18			; copy to temp-Reg.
	andi r16,KEYMASK	; check if its a managed Pin
	tst r16				; cpi r16,$00
	breq KEYIRQ_L1_CT1	; branch if unmanaged
	
	; process managed Pin
	ld r17,X			; load counter from SRAM
	mov r16,r18			; copy mask
	and r16,r19			; check if Pin changed
	tst r16				; cpi r16,$00			
	breq KEYIRQ_unch	; branch if state changed
	; state has changed 
	clr r17
	rjmp KEYIRQ_L1_STCNT; continue with next Pin/Bit
KEYIRQ_unch:	
	; state is unchanged 
	inc r17				; compare counter
	cpi r17,KEYMAXCOUNT	
	brlo KEYIRQ_L1_STCNT; branch of lower than maxcount
	cpi r17,KEYMAXCOUNT	; counter exactly maxcount ?
	brne KEYIRQ_L1_CT1	; no -> no action
	inc r17				; increment counter
	; store messages
	in r16,KEYPIN		; load aktuell state
	and r16,r18			; mask bit 0->ON (grounded) 1->OFF (pull-up)
	tst r16				; cpi r16,$00
	breq KEYIRQ_L1_ON	; grounded
	lds r16,KeyOffMsg
	or r16,r18			; set bit in "off" Message
	sts KeyOffMsg,r16
	rjmp KEYIRQ_L1_STCNT
KEYIRQ_L1_ON:
	lds r16,KeyOnMsg
	or r16,r18			; set bit in "on" Message
	sts KeyOnMsg,r16	
KEYIRQ_L1_STCNT:
	st X,r17			; store counter
KEYIRQ_L1_CT1:
	adiw XH:XL,$01		; increment counter-array pointer
	clc					; clear carry 
	rol r18				; rotate bit-mask 
	tst r18				; cpi r18,$00, all Pins processed?
	brne KeyIRQ_L1	

KeyIRQ_L1_exit:

	in r16,KEYPIN		; store act state as old state
	sts KeyOldState,r16

	pop XH
	pop XL
	pop r21
	pop r19
	pop r18
	pop r17
	pop r16
ret

⌨️ 快捷键说明

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