Pfad: Home => AVR-Übersicht => Hardware => Keyboard-Benutzung

Test eines Keyboards an Port B

; Test des Keyboards
;
; Liest das Keyboard am Port B und zeigt die gedrückte Taste auf den LEDs
; in hexadezimaler Form aus.
;
; Keyboard ist an Port B angeschlossen:
; Bit 6: *=Bit0 7=Bit1 4=Bit2 1=Bit3
; Bit 5: 0=Bit0 8=Bit1 5=Bit2 2=Bit3
; Bit 4: #=Bit0 9=Bit1 6=Bit2 3=Bit3
;
; 8515-Definitionen
.NOLIST
.INCLUDE "8515def.inc"
.LIST
;
; Register
.def   mpko=R15 ; Alter Tastenstand
.def   mpr=R16 ; Multifunktionsregister
.def   mpk=R25 ; Multifunktionsregister für Keyboard-Interrupt
;
; RAM-Adressen
.equ   taste=$0060 ; Erste Ramadresse, Hier kommt die Taste hin
;
; Reset-/Interruptvektoren
   RJMP   main
   RETI ; Ext Int 0
   RETI ; Ext Int 1
   RETI ; TC1 Capture
   RJMP   test ; TC1 Compare A
   RETI ; Compare B
   RETI ; TC1 Overflow
   RETI ; TC0 Overflow
   RETI ; Serial Transfer Complete
   RETI ; Serial Rx Complete
   RETI ; Data Register Empty
   RETI ; Serial Tx Complete
   RETI ; Analog Comparator

; Hauptprogramm
main:
   LDI   mpr,HIGH(RAMEND) ; Stack Pointer Init wegen Interrupts
   OUT   SPH,mpr
   LDI   mpr,LOW(RAMEND)
   OUT   SPL,mpr

; General control register
   CLR   mpr ; kein SRAM, kein Wait, kein Sleep-Mode,
   OUT   MCUCR,mpr ; Ext.Int egal

; Port B ist Output und Tastatur-Input
   LDI   mpr,0x70 ; alles auf Output
   OUT   DDRB,mpr
   LDI   mpr,0x00 ; alle Lampen an
   OUT   PORTB,mpr
   STS   Taste,mpr
;
; Timer/Counter 0 initiieren
   LDI   mpr,$00 ; Prescaler = 256
   OUT   TCCR0,mpr
   
; Timer 1 initiieren
   LDI   mpr,0b00000000 ; Disable Timer Output und PWM-Mode
   OUT   TCCR1A,mpr ; in Timer Control Register 1A
   LDI   mpr,0b00001011 ; No input noise canceling, clear counter after
       ; match, Prescaler = 64 ==> 62500 Hz = 16 Ás
   OUT   TCCR1B,mpr ; in Timer Control Register 1B
   LDI   mpr,HIGH(625) ; Compare-Wert in Compare-Register A
   OUT   OCR1AH,mpr ; High Byte zuerst
   LDI   mpr,LOW(625)
   OUT   OCR1AL,mpr ; Low Byte zuletzt
   LDI   mpr,0xFF ; No Interrupt on Compare B
   OUT   OCR1BH,mpr ; High Byte zuerst
   OUT   OCR1BL,mpr ; Low Byte zuletzt

; Interrupts starten
   CLR   mpr ; External interrupts disable
   OUT   GIMSK,mpr ; an General Interrupt mask register
   LDI   mpr,0b01000000 ; Timer 1: Overflow Int Off, Compare A Int on,
   OUT   TIMSK,mpr ; Compare B Int Off, Input Int Off, Timer 0: Int Off
   SEI ; Interrupts zulassen

; Unendlicher Loop, alles Interrupt-gesteuert
loop:   RJMP   loop

; Interrupt Rountine bei TC1 Compare Match B
tc1ci:   IN   mpk,SREG ; Status-Register retten
   PUSH   mpk
   LDI   mpk,0b11110000 ; Oberes Nibble Ausgabe, Unteres Eingabe
   OUT   DDRB,mpk ; an Port B
   LDI   mpk,0x0F ; Oberes Nibble gibt Null aus, unteres setzt Pullups
   OUT   PORTB,mpk
   IN   mpk,PINB ; Lese Ergebnis von Tastatur
   CP   mpk,mpko ; Vergleiche mit altem Stand
   BREQ   tc1cir ; Keine Änderung, Rückkehr
   MOV   mpko,mpk ; Kopiere neuen Stand in alten Stand
   STS   taste,mpk ; Neuer LED-Stand
tc1cir:   LDI   mpk,0xFF ; Port B wieder auf Ausgabe
   OUT   DDRB,mpr
   LDS   mpk,taste ; gedrückte Taste auf LEDs ausgeben
   OUT   PORTB,mpk
   POP   mpk ; Rückkehr vom Interrupt
   OUT   SREG,mpk ; Status-Register wieder herstellen
   RETI

tc0ci:   LDI   mpr,0xFF
   OUT   PORTB,mpr
   RETI
tc2ci:   LDI   mpr,0xAA
   OUT   PORTB,mpr
   RETI
test:   
;   LDI   mpk,0x0F
;   OUT   DDRB,mpk
;   LDI   mpk,0xF0
;   OUT   PORTB,mpk
   RETI


©2002 by http://www.avr-asm-tutorial.net