Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PB0 = 11min (IN) ;;
;; PB1 = 1 min (IN) ;;
;; PB2 = Relai (5V - OUT) ;;
;; PB3 = LED (5V - OUT) ;;
;; ;;
;; Zeitzähler für Internen 1MHZ takt ausgelegt ;;
;; mit 1024 vorfaktor ergibt für 250ms 240 ;;
;; Interrupts, somit brauch 1s 4*250ms Inter. ;;
;; ;;
;; Gezählt werden die Sek., Min., Stunden ;;
;; Erweiterungsmöglichkeiten sind möglich ;;
;; ;;
;; HINWEIS: Die Zeit hatt alle ca. 5min ein ;;
;; Verzögerung von ca. 5s. Die Ursache ;;
;; ist unbekannt. Genaue messungen für ;;
;; gewünschtenzeitraum empfehlenswert ;;
;; ;;
;; GETESTET bis ca. 5min !!! in diesem Zeitraum ;;
;; ist die korrekte Zeit erreicht ;;
;; worden !!! (bei 11min, +10s) ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.INCLUDE "m32def.inc"
; Registerdefinition
; Zählregister
.DEF SekX4 = R20 ; Register in dem die 250ms * 240 = 60s gespeichert werden (1s/250ms = 4)
.DEF Min = R21 ; Register in dem die Minuten gespeichert werden
.DEF Stunden = R22 ; Register in dem die Stunden gespeichert werden
.DEF temp = R25
; Konstantenregister
.DEF CSekX4 = R1 ; Register in dem die Konstante 250ms * 240 = 60sgespeichert ist (240)
.DEF CMin = R2 ; Register in dem die Konstante Minuten gespeichert ist (60)
.DEF CStunden = R3 ; Register in dem die Konstante Stunden gespeichert ist (24)
.DEF CTimer = R4 ; Register in dem die Konstante zum Vorladen des Timers gespeichert ist (10)
.DEF Config = R5 ; Reagister zeigt ob die Config schon mal asugeführt wurde
.DEF CompareMIN = R23 ; Vergleichsregister für die Sekunden
.DEF CompareSEC = R24 ; Vergleichsregister für die Minuten
; ... Erweiterung möglich
; Schreibregister für alle Einstellungen
.DEF Port = R16 ; Register für Port zugriffe
.DEF Inter = R17 ; Register für Interrupt zugriffe
.DEF Timer = R18 ; Register für Zeitintervall
.DEF SleepM = R19 ; Register für SleepModiekonfiguration
;Konstenatendefinition
.EQU CFaktor = 4 ; Faktor für die Multiplikation der Sekunden (1s/250ms = 4)
.EQU Initialisiert = 0 ; Bit das Zeigt ob Initialisiert wurde
.EQU KorrektturSek = 1 ; Bit das Zeigt ob KorrektturSek bereits gessetzt wurde
.EQU Korrekttur = 2 ; Bit das Zeigt ob KorrektturSek bereits gessetzt wurde
.EQU LED = 3 ; LED Portbit 3 für 5V Output
.EQU Relai = 2 ; Realai Portbit 2 für 5V Output
.EQU INLang = 0 ; Eingang für 11min Laufzeit
.EQU INKurz = 1 ; Eingang für 1 min Laufzeit
; Lange Laufzeit
.EQU Langmin = 11 ; Laufzeit für die min. (11min)
.EQU Langsec = 0*CFaktor; Laufzeit für die sec. (0sec)
; ... Erweiterung möglich
; Kurze Laufzeit
.EQU Kurzmin = 1 ; Laufzeit für die min. (1min) (min < 60 !!!)
.EQU Kurzsec = 0*CFaktor; Laufzeit für die sec. (0sec) (sec < 60 !!!)
; ... Erweiterung möglich
.ORG 0x000
rjmp main ; Reset Handler
.ORG OVF2addr
rjmp ovf2_handler ; Overflow Timer/Counter 2 Handler
;**************************************Interrupt-Handel-BEGINN**********************************************
ovf2_handler: ; Interrupt Handler für TimerOverflow
in XL, SREG ; SREG register retten
out TCNT2, CTimer ; Timer/Counter 2 mit 12 vorladen (255-243 = 12 <aufgerundet wegen befehlslaufzeiten)
; ES SIND AUF DEM ATMEGA32 -5s NACH DER ERSTEN MIN ALS KORREKTUR NÖTIG !!!
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sbrs Config, KorrektturSek; Korrektursek gesetzt?
rjmp Sek ; Nur einmal, nach der ersten Minute 5s abziehen.
ldi temp, (1<<initialisiert)|(0<<KorrektturSek)|(1<<Korrekttur)
mov Config, temp ; ; Config + KorrektturSek + Korrekttur bereits ausgeführt !!!
ldi SekX4, 20 ; 20/4 = 5s , die abzuziehen sind.
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sek:
inc SekX4 ; Sekunde wird erhöt, da alle 250ms erhöt wird wird bis 240 gezählt
cp SekX4,CSekX4 ; Prüfen ob 60Sekunden um sind (1s/250ms = 4*60 = 240), wenn ja zur Erhöhung der
brne fertig
clr SekX4 ; SekundenZähler wieder auf Null setzen wenn eine Minute um ist
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sbrc Config, Korrekttur ; Korrektur schon mal gesetzt?
rjmp min ; wenn nein dann setzten sonst weiter wie gehabt.
ldi temp, (1<<initialisiert)|(1<<KorrektturSek)|(1<<Korrekttur)
mov Config, temp ; Config + Korrekttur bereits ausgeführt !!!
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
min:
inc Min ; Minuten wird erhöht wenn 60sec vorbei sind
cp Min, CMin ; Prüfen ob 60Minuten um sind, wenn ja zur Erhöhung der
brne fertig
clr Min ; MinutenZähler wieder auf Null setzen wenn eine Stunde um ist
Stunden:
inc Stunden ; Minuten wird erhöht wenn 60sec vorbei sind
cp Stunden, CStunden ; Prüfen ob 60Minuten um sind, wenn ja zur Erhöhung der
brne fertig
clr Stunden ; MinutenZähler wieder auf Null setzen wenn eine Stunde um ist
; ... Erweiterung möglich
fertig:
cpse Min, CompareMin ; Minuten übereinstimmen
rjmp Prüfungoke
cpse SekX4, Comparesec ; Sekunden übereinstimmen
rjmp Prüfungoke
; ... Erweiterung möglich
; Prozedur zum Ausschalten des AVR etc.
ende:
clr TIMER
ldi TIMER, (0<<TOIE2) ; Interrupt ausschalten
out TIMSK, TIMER ; Timer/Counter 2 Overflow Onterrupt aktivated
cbi PORTA, Relai ; Relai Auschalten
Prüfungoke:
out SREG, XL ; SREG register wiederzurückholen
reti
;****************************************************Macros***************************************************
.MACRO CompareSetzen ; Start macro definition
ldi CompareMIN, @1 ; Vergleichsminuten mit der LangenZeit laden
ldi CompareSEC, @0 ; Vergleichssekundenmit der LangenZeit laden
rjmp Compare_gesetzt ; zurück zu main
.ENDMACRO ; End macro definition
;*************************************************Hauptprogramm***********************************************
.CSEG
main:
sbrc Config,initialisiert
rjmp back
Config:
; Konstantendefinition Register
ldi temp, 240 ; CSekX4 Konstante 250ms * 240 = 60s (Sekunden) (240)
mov CSekX4,temp
ldi temp, 60 ; CMin Minuten (60)
mov CMin,temp
ldi temp, 24 ; CStunden Stunden (24)
mov CStunden,temp
ldi temp, 11 ; CTimer Konstante zum vorladen des Timer gespeichert ist (255-244 = 11)
mov CTimer,temp
;Stack initialisieren
ldi temp, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse
out SPL, temp ; Laden der niederen 8-Bit des Stacks
ldi temp, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse
out SPH, temp ; Laden der höheren 8-Bit des Stacks
; Interruptdifinition
sei ; Interrupts global aktivieren
; Ports initialisieren
clr PORT
ldi PORT, 0b11111100 ; Port A bis auf Bit3 und Bit4 alles Eingänge
out DDRA, PORT ; Richtungsregister DDRA als Ausgang konfigurieren
sbi PORTA, LED ; LED anschalten
sbi PORTA, Relai ; Relai anschalten
sbis PINA, INKurz ; Prüfen Ob Kurz oder Lange Laufzeit
rjmp lang
CompareSetzen KurzSec,KurzMin ; Compare werte auf Kurz setzten
lang:
CompareSetzen LangSec,LangMin ; Compare werte auf Lang setzten
Compare_gesetzt:
; SleepModus initialisieren (Idle)
ldi SleepM,(1<<SE) ; Sleep ModusAktivieren, |(0<<SM2)|(0<<SM1)|(0<<SM0) 000 ist der Idle Sleep Modus
out MCUCR, SleepM ; Sleep eingstellen
; Timer/Counter 2 initialisieren
clr TIMER
ldi TIMER, (1<<TOIE2) ;|(1<<OCIE2) < für Compare Interrupt
out TIMSK, TIMER ; Timer/Counter 2 Overflow Onterrupt aktivated
clr TIMER
ldi TIMER, (1<<CS22)|(1<<CS21)|(1<<CS20) ; noPWM, OCR2 update Normal + off, vorfaktor 1024
out TCCR2, TIMER ; Port Timer/Counter 2 mit Funktionen laden, Timer wird gestartet
out TCNT2, CTimer ; Timer/Counter 2 mit 12 vorladen (255-245 = 12 <aufgerundet wegen befehlslaufzeiten)
ldi temp, (1<<initialisiert)
mov Config, temp ; Config bereits ausgeführt !!!
back:
Sleep
rjmp back
Lesezeichen