sebastian.fr
14.03.2006, 23:28
Hallo zusammen,
ich habe vor kurzem angefangen im Assember AVM-Mikroprozessadoren zu programmieren. Jetzt bin ich vor ein für mich unlösbares Problem gestoßen.
Wie ist es möglich während einem laufenden Programm das einen Ausgang aktiviert, diesen in einem Gewissen Takt ein und auszuschalten. Das ganze soll ca. die Geschwindigkeit eines Andreaskreuzes am Bahnübergang haben.
Ich habe folgenden funktionierenden Code geschrieben:
;************************************************* *************
.include "tn2313def.inc" ; Definitionen für Attiny2313 *
;************************************************* *************
; Schrankensteuerung Modelleisenbahn
; Interner RC-Oszi, 1MHz, Tiny 45
; Stand: 03.03.2006
;
; Software um eine Bahnschranke bei durchfahren der Lichtschranke durch
; den Modellzug zu schließen und nach vollständigem Austritt des Zuges
; incl. dessen Anhänger aus dem Schrankenbereich wieder zu öffnen
;
; PORTB
; PB0: IN P Lichtschranke 1
; PB1: IN P Lichtschranke 2
; PB2: OUT - Schranke oeffnen (High aktiv)
; PB3: OUT - Schranke schließen (High aktiv)
; PB4: OUT - Andreaskreuz
; PB5: OUT - Andreaskreuz
; merker1 Durchfahrene Lichtschranke 1
; merker2 Durvhfahrene Lichtschranke 2
; Register Definition
; General Purpose
.def a = r16 ;Register 16 als a definieren
.def b = r17 ;Register 17 als b definieren
; Interrupt
; .def i_a = r19 ;Wird nicht benötigt
; .def sSREG = r1
.DEF merker1 = r21 ;Register 21 wird als merker1 definiert
.DEF merker2 = r22 ;Register 22 wird als merker2 definiert
RESET: ldi a, low(RAMEND) ;Lade in a low(RAMEND)
out SPL, a ;Gebe a im SPL aus
;IO-Init
ldi a, 0b11111111 ;Lade in a die Hex-Zahl
out PORTB, a ;Gebe a an PORTB aus / initialisierung des Ports
ldi a, 0b00111100 ;Lade in a Hex-Zahl
out DDRB, a ;Gebe a an DDRB aus / 0==Eingang; 1==Ausgang
cbi PORTB,2 ;Setze Ausgang PB,2 auf Low
cbi PORTB,3 ;Setze Ausgang PB,3 auf Low
cbi PORTB,4 ;Setze Ausgang PB,4 auf Low
cbi PORTB,5 ;Setze Ausgang PB,5 auf Low
rjmp oeffnen ;Springe zu oeffnen
start: CLR merker1 ;Lade die Zahl 0 in merker1
CLR merker2 ;Lade die Zahl 0 in merker2
ls1: sbic PINB, 0
rjmp ls2 ;Wenn PB0!=0 springe zu ls2
CPI merker1,1
BREQ ls11 ;Wenn merker1==1 springe zu ls11
CPI merker2,1
BREQ ls11 ;Wenn merker2==1 springe zu ls11
ldi merker1 ,1 ;Setze merker1 auf High (1)
ldi a, 20 ;Pause von 20*10ms
rcall WAIT_M ;um beim Steckerziehen eine schließung zu vermeiden
sbi PORTB,3 ;Setze Ausgang PB3 auf High /
;Anfang Schranke schließen
sbi PORTB,4 ;Andreaskreuz aktvieren
sbi PORTB,5
ldi a, 50
rcall WAIT_M ;Pause von 50*10ms
cbi portb,3 ;Setze Ausgang PB3 auf Low /
;Ende Schranke schließen
ls11: CPI merker2,1
BREQ warten ;Wenn merker2==1 springe zu warten
ls2: sbic PINB, 1
rjmp ls1 ;Wenn PB1!=0 springe zu ls1
CPI merker2,1
BREQ ls22 ;Wenn merker2==1 springe zu ls22
CPI merker1,1
BREQ ls22 ;Wenn merker1==1 springe zu ls22
ldi merker2, 1 ;Setze merker2 auf High (1)
ldi a, 20 ;Pause von 20*10ms
rcall WAIT_M ;um beim Steckerziehen eine schließung zu vermeiden
sbi PORTB,3 ;Setze Ausgang PB3 auf High /
;Anfang Schranke schließen
sbi PORTB,4 ;Andreaskreuz aktvieren
sbi PORTB,5
ldi a, 50
rcall WAIT_M ;Pause von 50*10ms
cbi portb,3 ;Setze Ausgang PB3 auf Low /
;Ende Schranke schließen
ls22: CPI merker1,0
BREQ ls1 ;Wenn merker1==0 springe zu ls1
;Die folgende warten-Schleife wird mehrmals durchlaufen
;um die Abstände zwischen den Anhängern zu überbrücken
warten: ldi R25, 0b01111111 ;Lade in das Register25 die Hex Zahl (dez:127) /
;Ein Takt benötigt 1ys
warten0: sbis PINB, 0
rjmp warten ;Wenn PB0==1 springe zu warten
sbis PINB, 1
rjmp warten ;Wenn PB1==1 springe zu warten
ldi a, 1
rcall WAIT_M ;Pause von 1*10ms
DEC R25 ;Decrementierung des Wertes im Register 25 um 1
BRNE warten0 ;Wenn die Zahl im R25!=0 ist springe zu warten0
oeffnen: sbi portb,2 ;Setze Ausgang PB2 auf High / Anfang Schranke öffnen
cbi PORTB,4 ;Andreaskreuz deaktvieren
cbi PORTB,5
ldi a, 50
rcall WAIT_M ;Pause von 50*10ms
cbi portb,2 ;Setze Ausgang PB2 auf Low / Ende Schranke öffnen
rjmp start ;Springe zu start
;Zeitschleife
;Übergabe: a - Länge= 10ms * a (a:1..255)
WAIT_M:
WM_0: ldi b, 0xFF
WM_1: lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
wdr
wdr
dec b
brne WM_1
dec a
brne WM_0
ret
Kann mir jemand helfen wie ich den PB4 und PB5 nach der aktivierung zum blinken bringe und nach der deaktivierung durch das Programm wieder zum ausschalten??
Viele liebe Gruesse
Sebastian Frei
ich habe vor kurzem angefangen im Assember AVM-Mikroprozessadoren zu programmieren. Jetzt bin ich vor ein für mich unlösbares Problem gestoßen.
Wie ist es möglich während einem laufenden Programm das einen Ausgang aktiviert, diesen in einem Gewissen Takt ein und auszuschalten. Das ganze soll ca. die Geschwindigkeit eines Andreaskreuzes am Bahnübergang haben.
Ich habe folgenden funktionierenden Code geschrieben:
;************************************************* *************
.include "tn2313def.inc" ; Definitionen für Attiny2313 *
;************************************************* *************
; Schrankensteuerung Modelleisenbahn
; Interner RC-Oszi, 1MHz, Tiny 45
; Stand: 03.03.2006
;
; Software um eine Bahnschranke bei durchfahren der Lichtschranke durch
; den Modellzug zu schließen und nach vollständigem Austritt des Zuges
; incl. dessen Anhänger aus dem Schrankenbereich wieder zu öffnen
;
; PORTB
; PB0: IN P Lichtschranke 1
; PB1: IN P Lichtschranke 2
; PB2: OUT - Schranke oeffnen (High aktiv)
; PB3: OUT - Schranke schließen (High aktiv)
; PB4: OUT - Andreaskreuz
; PB5: OUT - Andreaskreuz
; merker1 Durchfahrene Lichtschranke 1
; merker2 Durvhfahrene Lichtschranke 2
; Register Definition
; General Purpose
.def a = r16 ;Register 16 als a definieren
.def b = r17 ;Register 17 als b definieren
; Interrupt
; .def i_a = r19 ;Wird nicht benötigt
; .def sSREG = r1
.DEF merker1 = r21 ;Register 21 wird als merker1 definiert
.DEF merker2 = r22 ;Register 22 wird als merker2 definiert
RESET: ldi a, low(RAMEND) ;Lade in a low(RAMEND)
out SPL, a ;Gebe a im SPL aus
;IO-Init
ldi a, 0b11111111 ;Lade in a die Hex-Zahl
out PORTB, a ;Gebe a an PORTB aus / initialisierung des Ports
ldi a, 0b00111100 ;Lade in a Hex-Zahl
out DDRB, a ;Gebe a an DDRB aus / 0==Eingang; 1==Ausgang
cbi PORTB,2 ;Setze Ausgang PB,2 auf Low
cbi PORTB,3 ;Setze Ausgang PB,3 auf Low
cbi PORTB,4 ;Setze Ausgang PB,4 auf Low
cbi PORTB,5 ;Setze Ausgang PB,5 auf Low
rjmp oeffnen ;Springe zu oeffnen
start: CLR merker1 ;Lade die Zahl 0 in merker1
CLR merker2 ;Lade die Zahl 0 in merker2
ls1: sbic PINB, 0
rjmp ls2 ;Wenn PB0!=0 springe zu ls2
CPI merker1,1
BREQ ls11 ;Wenn merker1==1 springe zu ls11
CPI merker2,1
BREQ ls11 ;Wenn merker2==1 springe zu ls11
ldi merker1 ,1 ;Setze merker1 auf High (1)
ldi a, 20 ;Pause von 20*10ms
rcall WAIT_M ;um beim Steckerziehen eine schließung zu vermeiden
sbi PORTB,3 ;Setze Ausgang PB3 auf High /
;Anfang Schranke schließen
sbi PORTB,4 ;Andreaskreuz aktvieren
sbi PORTB,5
ldi a, 50
rcall WAIT_M ;Pause von 50*10ms
cbi portb,3 ;Setze Ausgang PB3 auf Low /
;Ende Schranke schließen
ls11: CPI merker2,1
BREQ warten ;Wenn merker2==1 springe zu warten
ls2: sbic PINB, 1
rjmp ls1 ;Wenn PB1!=0 springe zu ls1
CPI merker2,1
BREQ ls22 ;Wenn merker2==1 springe zu ls22
CPI merker1,1
BREQ ls22 ;Wenn merker1==1 springe zu ls22
ldi merker2, 1 ;Setze merker2 auf High (1)
ldi a, 20 ;Pause von 20*10ms
rcall WAIT_M ;um beim Steckerziehen eine schließung zu vermeiden
sbi PORTB,3 ;Setze Ausgang PB3 auf High /
;Anfang Schranke schließen
sbi PORTB,4 ;Andreaskreuz aktvieren
sbi PORTB,5
ldi a, 50
rcall WAIT_M ;Pause von 50*10ms
cbi portb,3 ;Setze Ausgang PB3 auf Low /
;Ende Schranke schließen
ls22: CPI merker1,0
BREQ ls1 ;Wenn merker1==0 springe zu ls1
;Die folgende warten-Schleife wird mehrmals durchlaufen
;um die Abstände zwischen den Anhängern zu überbrücken
warten: ldi R25, 0b01111111 ;Lade in das Register25 die Hex Zahl (dez:127) /
;Ein Takt benötigt 1ys
warten0: sbis PINB, 0
rjmp warten ;Wenn PB0==1 springe zu warten
sbis PINB, 1
rjmp warten ;Wenn PB1==1 springe zu warten
ldi a, 1
rcall WAIT_M ;Pause von 1*10ms
DEC R25 ;Decrementierung des Wertes im Register 25 um 1
BRNE warten0 ;Wenn die Zahl im R25!=0 ist springe zu warten0
oeffnen: sbi portb,2 ;Setze Ausgang PB2 auf High / Anfang Schranke öffnen
cbi PORTB,4 ;Andreaskreuz deaktvieren
cbi PORTB,5
ldi a, 50
rcall WAIT_M ;Pause von 50*10ms
cbi portb,2 ;Setze Ausgang PB2 auf Low / Ende Schranke öffnen
rjmp start ;Springe zu start
;Zeitschleife
;Übergabe: a - Länge= 10ms * a (a:1..255)
WAIT_M:
WM_0: ldi b, 0xFF
WM_1: lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
lpm
wdr
wdr
dec b
brne WM_1
dec a
brne WM_0
ret
Kann mir jemand helfen wie ich den PB4 und PB5 nach der aktivierung zum blinken bringe und nach der deaktivierung durch das Programm wieder zum ausschalten??
Viele liebe Gruesse
Sebastian Frei