Hallo,
erstmal Danke für dieses Forum. Ich habe gerade erst mit der
ARV-Programmierung angefangen und möchte meine Modeleisenbahn damit
erweitern. Mein erstes Übungsobjet eine Ampelsteuerung scheint aber
schon recht schwierig zu werden. Ich benutze einen Atmel Tiny2313 mit
dem PollinAVR . Ich habe zwei Ampeln (LEDs) an den PORTD angeschlossen.
(Ampel_1: Rot, gelb, grün: PD0, PD1, PD2) (Ampel_2: PD3, PD4, PD5). Das
Progamm habe ich mir mit Hilfe von AVR-Studio erstellt:
1
2
.include "tn2313def.inc"
3
.def Trafficlight = R16 ; Define R16 als Traficlight
4
.def Timer1 = R17
5
.def Timer2 = R18 ; Define R17 als Timer1
6
.def Temp1 = R19 ; Tempregister
7
.def Null = R20 ; Tempregister (sonst null)
8
.EQU RAM_Ampel=0x0060 ; Define Speicer für Ampel
9
.equ TIMERWERT = 3906 ; Compwert für Timmer_Counter1
ERAMlesenLoop1: ; Werte aus ERAM holen und im SRAM Speichern
51
adiW ZL,1
52
OUT EEARL,ZL
53
SBI EECR,0
54
IN Temp1,EEDR
55
ST X+, Temp1
56
DEC Timer1
57
BRNE ERAMlesenLoop1
58
;---------------
59
ldi Temp1, Low(Timerwert) ; Timer vorbelegen
60
out OCR1AL,Temp1
61
ldi Temp1, High(Timerwert)
62
out OCR1AH,Temp1
63
ldi Temp1,0x0c ; Prescaller
64
out TCCR1B,Temp1
65
ldi temp1,0x50 ; Interupt Comp
66
out TIMSK,Temp1
67
sei
68
AmpelInit:
69
rcall AmpelTag
70
rcall AmpelTagLoop1
71
rjmp DoNothing
72
AmpelTag:
73
LDI XH, high(RAM_Ampel); Zeiger auf RAM_Ampel
74
LDI XL, Low(RAM_Ampel)
75
LD Timer1, X+ ; Anzahl der Werte holen
76
ret
77
AmpelTagloop1:
78
LD Trafficlight, X+ ; Ampelwert holen
79
out PORTD, Trafficlight
80
LD Timer2, X+ ; Zeitspanne holen
81
DEC Timer1 ; Zähler der noch zu holenden Werte
82
ret
83
;------------------
84
TIM1_COMPA:
85
in Temp1,Sreg ; SREG retten
86
push Temp1
87
Dec Timer2 ; Zeitzähler verringern
88
cpse Timer2,Null
89
rjmp TIM1_COMPA_Exit ; wenn Timer2 <>0
90
mov Temp1,timer1 ; merken
91
cpse Timer1,Null
92
rcall AmpelTagLoop1 ; wenn Timer2=0 und Timer1 <>0
93
cpse Temp1,Null
94
rjmp TIM1_COMPA_Exit
95
rcall AmpelTag ; wenn Timer2=Timer1=0
96
rcall AmpelTagLoop1
97
98
TIM1_COMPA_Exit:
99
pop Temp1 ; SREG setzen
100
out SREG,Temp1
101
reti
102
103
DoNothing:
104
rjmp DoNothing
In der Simulation funkt alles wunderbar!
Also habe ich das Prog via PonyProg auf meinen Tiny geschrieben und
getestet: Klappt nur einmal wunderbar danach macht er nur MIST. Also ein
kompletter Druchlauf funktioniert und dann macht es scheinbar was er
will... nach einem Reset klappt der Durchlauf wieder einmal.
Ich komme einfach nicht mehr weiter, evtl. kann mir jem helfen?
Schönen Sonntag
Gruß Ralf
Was heißt mist?
Ach ja für Interupts gibt es in der .def Datei (nach dem kompilieren
unter dem Punkt included files) extra defines:
.org ICP1addr z.b. für den InputCapture des Timer 1, dann kannst du dir
die ganze Regi orgie sparen.
.org INT_VECTORS_SIZE sezt dann dein Programm "dahinter"
Außerdem erscheint "ERAMlesen" etwas wirr. Was genau willst du da
machen?
Hi
Ich finde keine Stelle, an der überprüft wird, wann der Durchlauf zu
Ende ist. Irgendwann zeigt X auf undefinierten RAM.
Sieh dir mal an, wo du mit 'rjmp ERAMlesen' hin springst. Die
EEPROM-Leseroutine solltest du so wie im Datenblatt machen.
Deine Konstanten kannst du auch im Flash speichern und dort auslesen. da
ersparst du dir das ganze umkopieren.
MfG Spess
Hi.
Danke das mit dem .org OC1Aaddr ist ne gute Idee.
das ERAMlesen, habe ich mir von einem anderem Code abgeschaut, (ehrlich
nicht ganz verstanden, aber es klappt ganz gut.)
zuerst wird ein Wert gelesen (0x0d) --> es sollen 13 Werte gelesen
werden)
dann wird eine Schleife zum Lesen aus ERAM und Speichern im SRAM
durchgeführt, dabei wird jeder Wert einzeln übertragen, ich dachte mir
dadurch bin ich später mal flexibler. Das ist aber scheinbar auch nicht
das Problem, denn die übertragenen Werte werden später richtig benutzt.
0x06,0x21,0x06,0x11,0x01,.... sind meine Ampelphase:
wobei der 1. Wert (wie beim ERAM kopieren die Anzahl der Werte gibt,
nach der die Ampelphase von vor beginnt.)
6 das sechs Ausgaben nötig sind, mit jeweils einer Zeitangabe, also 12
Werte.
0x06 ,0x21 ,0x06 ,0x11 ,0x01 ,....
6Werte | A1:rot, A2 grün| 6x Timer | A1:rot A2:gelb | 1x Timer ...
soweit so gut, wie gesagt beim 1.Durchlauf funktioniert die Ausgabe an
den Pins von PORTD richtig. jedoch beim 2.Durchlauf zeigt die Ausgabe
immer unterschiedliche Werte.
Ich habe es auch schon mit einem Mega16 getestet mit dem selben
Ergebnis. :-( Ich denke das Problem muss beim neuInit liegen, wobei in
der Simulation alles klasse klappt. -> Habe ich evtl. einen Interupt
falsch gesetzt? oder muss ich die nicht benutzten Pins vom Tiny auf
Masse legen, damit sie nicht umkippen? <-dann wundert es mich aber warum
der 1.Druchlauf klappt.
Ist mein Progi sonst soweit verständlich? Ich bin erst eine Woche dabei
und habe evtl. eine leicht seltsame Logik im Ablauf.
Gruß
Ralf
Hallo @ Spess53
...
mov Temp1,timer1 ; in timer1 stehen die Anzahl der zulesenden
Doppelwerte
...
cpse Temp1,Null ; Wenn der Timer 0 ist (kein weiterer Wert mehr
zu
lesen ist beginnt die AmtelTag ...
rjmp TIM1_COMPA_Exit
rcall AmpelTag
rcall AmpelTagLoop1
>> Irgendwann zeigt X auf undefinierten RAM.
hast du das eep geladen?
Gruß
Ralf
Soo, hier mal eine aufgeräumte und debuggte Version.
- Kopieren der Daten vom EEPROM ins RAM fehlerhaft, das erste Byte,
welches die Anzahl der Datensätze definiert, wurde nicht kopiert
- Nicht mit kodierten Adressen arbeiten, das geht fix schief. Labels
verwenden!
- erst ALLES initialisieren, dann erst die Interrupts freigeben. *GANZ
WICHTIG!*
- Kuddelmuddel im Interrupt aufgeräumt, war auch fehlerhafte Logik
- Formatierung ist wichtig, um den Durchblick zu behalten!
MfG
Falk
Uuups, noch ein kleiner Bug. Update siehe Anhang.
Ach ja, ein weiterer Fehler im Original
- Beim Schreibzugriff auf 16 Bit Register muss man erst das HIGH und
dann das Low Byte schreiben!
MFg
Falk
Danke @Falk
Ich habe mir grad den Code von Dir angesehen, Vielen Dank, ich denke da
muss ich wohl noch etwas lernen, na, ja aber für die erste Woche reicht
es mir. Die Abfolge stimmte jetzt leider nicht mehr ganz, konnte ich
aber beheben.
Ich denke, die Logik habe ich verstanden, bei mir war es etwas
kompliziert, da ich mit dem Statusregister nicht ganz "grün" war, und
ich es zuerst ohne Interupt programmiert hatte.
Im ARV-Simulator klappt es, so wie es soll, ich werden es morgen auf dem
Tiny testen und mich dann melden.
Danke am Alle die mir geholfen haben!
Gruß
Ralf