; Test of a 16-switch keypad
;
; Reads the keyboard on port B and displays the activated key on the LEDs
; in hex format.;
; The decimal keyboard is attached to port B:
; 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
;
; Tests with this program showed that parallel operation of the LEDs and
; of the keyboard on the same port (B) is practically impossible due to
; insufficient driving currents of the port pins. No correct values are read.
;
; 8515-Definitions
.NOLIST
.INCLUDE "8515def.inc"
.LIST
;
; Registers
.def   mpko=R15 ; Former key status
.def   mpr=R16 ; Multi funktion register
.def   mpk=R25 ; Multi funktion register for keyboard-Interrupts
;
; RAM-Adresses
.equ   taste=$0060 ; First Ramadress, keys are here
;
; Reset-/Interruptvector table
   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

; Main program
main:
   LDI   mpr,HIGH(RAMEND) ; Stack Pointer Init for Interrupts
   OUT   SPH,mpr
   LDI   mpr,LOW(RAMEND)
   OUT   SPL,mpr

; General control register
   CLR   mpr ; no SRAM use, no Wait, no Sleep-Mode,
   OUT   MCUCR,mpr ; Ext.Int not used

; Port B is output and keypad-Input
   LDI   mpr,0x70 ; all to Output
   OUT   DDRB,mpr
   LDI   mpr,0x00 ; all lamps on
   OUT   PORTB,mpr
   STS   Taste,mpr
;
; Timer/Counter 0 init
   LDI   mpr,$00 ; Prescaler = 256
   OUT   TCCR0,mpr
   
; Timer 1 init
   LDI   mpr,0b00000000 ; Disable Timer Output and 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-value in Compare-Register A
   OUT   OCR1AH,mpr ; High Byte first
   LDI   mpr,LOW(625)
   OUT   OCR1AL,mpr ; Low Byte last
   LDI   mpr,0xFF ; No Interrupt on Compare B
   OUT   OCR1BH,mpr ; High Byte first
   OUT   OCR1BL,mpr ; Low Byte last

; Interrupts start here
   CLR   mpr ; External interrupts disable
   OUT   GIMSK,mpr ; to General Interrupt mask register
   LDI   mpr,0b01000000 ; Timer 1: Overflow Int Off, Compare A nt on,
   OUT   TIMSK,mpr ; Compare B Int Off, Input Int Off, Timer 0: Int Off
   SEI ; Interrupt enable

; Indefinit loop, all Interrupt-controlled
loop:   RJMP   loop

; Interrupt Routine at TC1 Compare Match B
tc1ci:   IN   mpk,SREG ; save Status-Register
   PUSH   mpk
   LDI   mpk,0b11110000 ; Upper nibble output, lower input
   OUT   DDRB,mpk ; to Port B direction
   LDI   mpk,0x0F ; Upper nibble =0, lower sets Pullups on
   OUT   PORTB,mpk
   IN   mpk,PINB ; Read results from keypad
   CP   mpk,mpko ; Compare with older status
   BREQ   tc1cir ; No change, return
   MOV   mpko,mpk ; Copy new status over old status
   STS   taste,mpk ; New LED-Status
tc1cir:   LDI   mpk,0xFF ; Port B to output
   OUT   DDRB,mpr
   LDS   mpk,taste ; status on LEDs
   OUT   PORTB,mpk
   POP   mpk ; Return from Interrupt
   OUT   SREG,mpk ; restore Status-Register
   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