Code:
	
.include "TN15def.inc"                                                          ; Prozessor ATtiny15
.cseg                                                                     ; Kennung für Programmcode
.def TMP        = R0                                                      ; Allgemeine Variable für Rückgabewerte
.def TMP1       = R16                                                     ; Allgemeine Variable
.def Status     = R20                                                     ; Statusregister für Betriebszustände
.def Helligkeit = R21                                                     ; Wert für PWM Regelung
.def KeyOld     = R26                                                     ; Taster die gedrückt waren
.def KeyNew     = R27                                                     ; Taster die gedrückt sind
.def KeyEnter   = R28                                                     ; Taster die neu gedrückt wurden
.def KeyExit    = R29                                                     ; Taster die neu losgelassen wurden
.def ZL         = R30                                                     ; 16-Bit Variable L-Byte
.def ZH         = R31                                                     ; 16-Bit Variable H-Byte
; Status 7 6 5 4 3 2 1 0
;                      ^- 0=Lampe aus, 1=Lampe an
.org 0x0000                                                               ; Programm Startadresse $0000
  rjmp  Init                                                              ; Einsprung ins Hauptprogramm
.org 0x0001                                                               ; Interrupt Pin 7 (INT0)
  rjmp  Test                                                              ; Sprung zur Testroutine 
Init:
  ; *******************************************************
  ; *            Internen Oszillator kalibrieren          *
  ; *******************************************************
  
  ldi   ZL, low (2*Kalibrierung)                                          ; Low-Byte Endadresse Flashspeicher lesen
  ldi   ZH, high(2*Kalibrierung)                                          ; High-Byte Endadresse Flashspeicher lesen
  lpm                                                                     ; Kalibrierungsbyte auslesen
  ser   ZL                                                                ; $FF in ZL setzen für Vergleich
  cpse  TMP, ZL                                                           ; Kalibrierungsbyte gültig? (Nein, wenn $FF)
  out   OSCCAL, TMP                                                       ; Ja, dann Chip kalibrieren und danach
  clr   ZL                                                                ; den Vergleich löschen.
  mov   Status, ZL                                                        ; Statusregister löschen.
  in    TMP1, MCUCR                                                       ; Controllregister des Prozessors einlesen
  sbr   TMP1, 1<<ISC00                                                    ; PowerDown-Modus freischalten
  out   MCUCR, TMP1                                                       ; und speicehrn.
  ; *******************************************************
  ; *           Ports des ATtiny15 einstellen             *
  ; *******************************************************
  ldi   TMP1, 1<<DDB4 | 1<<DDB3 | 1<<DDB1                                 ; Pin 2, 3, 6 auf Ausgabe schalten.
  out   DDRB, TMP1                                                        ; schalten und entsprechende
  com   TMP1
  out   PORTB, TMP1                                                       ; PullUp-Widerstände einschalten.
  in    TMP1, PORTB                                                       ; Aktuellen Portinhalt einlesen und
  ori   TMP1, 0b011000                                                    ; grüne + rote LED ausschalten
  out   PORTB, TMP1                                                       ; neuen Zustand ausgeben.
  ; *******************************************************
  ; *               Interrupts freigeben                  *
  ; *******************************************************
  in    TMP1, GIMSK                                                       ; Interrupt an INT0 (Taster Aus/Ein) freigeben
  sbr   TMP1, 1<<INT0
  out   GIMSK, TMP1                                                       ; und speichern.
  sei                                                                     ; Interrupts freigeben.
  in    TMP1, MCUCR 
  sbr   TMP1, 1<<SE | 1<<SM1
  out   MCUCR, TMP1
;  sleep 
; >>>>>>> Hauptprogramm Anfang <<<<<<<
Start:
  rcall KeyCheck                                                          ; Tasten abfragen
  cpi   KeyExit, 0x04                                                     ; Taste "Ein/Aus" gedrückt $04
  brne  Weiter1                                                           ; Nein, dann weiter, sonst
  rcall PinInt0                                                           ; Sprung nach Ein- Ausschaltroutine
Weiter1:
  rjmp  Start
; >>>>>>>> Hauptprogramm Ende <<<<<<<<
; >>>>>>>> INTERRUPTPROGRAMME <<<<<<<<
  ; *******************************************************
  ; *     Testinterrupt um PowerDown-Mode zu beenden      *
  ; *******************************************************
Test:
  nop
  reti
PinInt0:
  ; *******************************************************
  ; *          Ein- / Ausschalter $04 an INT0             *
  ; *******************************************************
  cpi   Status, 0x00                                                      ; Lampe ausgeschaltet?
  breq  LampeEin                                                          ; Dann Lampe einschalten
  cbr   Status, 1                                                         ; Ist die Lampe an? Dann Lampe aus und
  in    TMP1, PORTB
  sbr   TMP1, 0b001000
  out   PORTB, TMP1
;  in    TMP1, MCUCR                                                       ; Prozessorcontrollregister auslesen um
;  sbr   TMP1, 1<<SE | 1<<SM1                                              ; PowerDown-Mode zu aktivieren
;  out   MCUCR, TMP1                                                       ; Speichern.
; sleep                                                                   ; Prozessor in PowerDown-Mode versetzen.
  reti                                                                    ; Rücksprung.
  
LampeEin:  
  sbr   Status, 1                                                         ; Kennung für Lampe an setzen
  ; --------- TEST -----------
  in    TMP1, PORTB
  cbr   TMP1, 0b001000
  out   PORTB, TMP1
  reti 
; >>>>>>>>>> UNTERPROGRAMME <<<<<<<<<<
 
  ; *******************************************************
  ; *          Tasterabfrage mit Entprellung              *
  ; *******************************************************
  ; * Keyenter (R28) = Rückgabe neu gedrückte Taste       *
  ; * Keyexit  (R29) = Rückgabe der losgelassenen Taste   *
  ; * Taste an PB0 (Hell/Dunkel) = 01                     *
  ; * Taste an PB2 (Ein/Aus)     = 04                     *
  ; *******************************************************
KeyCheck:                                                                 ; Unterprogramm zur Tastaturabfrage
  ldi   KeyEnter, 0
  ldi   KeyExit, 0
  in    KeyNew, PINB                                                      ; Lade PB
  com   KeyNew                                                            ; invertieren
  andi  KeyNew, 0b000101                                                  ; Maskieren der nicht verwendeten Pins
  cpse  KeyOld, KeyNew                                                    ; Test ob Veränderung
  rjmp  KeyAction                                                         ; Veränderung
  ret 
                                                                          ; alles gleich
KeyAction:
  rcall Wait12ms                                                          ; etwas warten
  in    ZL, PINB                                                          ; nochmal einlesen
  com   ZL                                                                ; invertieren bei neg. Logik
  andi  ZL, 0b000101                                                      ; maskieren der nicht verwendeten Pins
  cpse  KeyNew, ZL                                                        ; ist es stabil
  ret                                                                     ; war nix, da nicht stabil
  
  mov   KeyEnter, KeyOld
  com   KeyEnter                                                          ; invertieren
  and   KeyEnter, KeyNew                                                  ; steigende Flanken, !alt & neu
  mov   KeyExit, KeyNew
  com   KeyExit                                                           ; invertieren
  and   KeyExit, KeyOld                                                   ; fallende Flanken, alt & !neu
  mov   KeyOld, KeyNew                                                    ; alt := neu
  ret                                                                     ; Interrupt verlassen
  ; *******************************************************
  ; *            Warteschleife mit ca. 12ms               *
  ; *******************************************************
Wait12ms:
  ldi   ZL, low (2500)                                                    ; 16-Bit Zähler mit Startwert laden
  ldi   ZH, high(2500)                                                    ; für Taktfrequenz 1.6MHz
WaitMs1:
  dec   ZL                                                                ; Low-Byte des Zählers erniedrigen
  brne  WaitMs1                                                           ; wenn 0, dann 
  dec   ZH                                                                ; High-Byte des Zählers erniedrigen
  brne  WaitMs1                                                           ; wenn auch0, dann Warteschleife
  ret                                                                     ; verlassen.
Kalibrierung: .db 0x79                                                    ; Kalibrierungswert für int. Oszillator
.exit
 
						
Lesezeichen