Habe jetzt mit dem Multimeter nachgemessen an den Ports, jedoch kommt
nirgendwo spannung an, außer an Pin C4 und Pin C6.
was ist denn da falsch???
Ist eventuell der µc kaputt, aber habe es eigentlich auch mit einem
anderen probier, da passierte aber das Gleiche?
mfg
JTAG noch an?
(fuse/bit) - betrifft aber nur Port C
...Und der Code sieht ganz schön zusammen-ge-copy-n-pasted aus
1) deine Warte-Funktion überschreibt einfach Register
2) du hast EIN Register benannt (".def temp=r16"), benutzt aber alle
andern mit Nummer
3) das hier funktioniert so nicht
1
main:
2
LDI R17, 0b00000001 ;aufbau in rot
3
main1:
4
ROR r17
5
out PORTA, r17
6
call warten ;hab ich getauscht, fuer mehr Uebersicht
7
CPI r17, 255
8
BRNE main1
Um da 1en reinzuRORen, müsstest du das Carry-Bit setzen. Abgesehen von
Punkt 1)
hth. Jörg
Heiner H. wrote:
> Habe jetzt mit dem Multimeter nachgemessen an den Ports, jedoch kommt> nirgendwo spannung an, außer an Pin C4 und Pin C6.> was ist denn da falsch???
Das deutet darauf hin, dass an deinem Mega16 das JTAG Interface
noch eingeschaltet ist (kann per Fuse abgeschaltet werden).
Für den Rest:
Lad dein Programm mal in den Simulator und gehe es Schritt
für Schritt durch. Überleg dir auch was
ROR r17
eigentlich wirklich macht.
PS: Nichts gegen Dezimalzahlen. Aber in diesem Beispiel sind
Dezimalzahlen so ziemlich die ungeeignetste Form. Hex oder
Binär wäre wesentlich besser.
Ich glaube kaum, dass Du hier jemand findest, der Dir diese Wurst von
Code analysiert. Vorschlag: Versuch erst mal EINELED zum Leuchten
(danach: Blinken) zu bringen. Wenn das funktioniert, baust Du darauf
auf, indem Du immer wenig hinzufügst und ständig testest. Dann klappts
auch mit dem µC...
Ohne das jetzt vollständig zu analysieren ein parr worte....
Du verwendest mehrfach sowas wie:
CPI r17, 255
call warten
BRNE main5
wobei "call warten" dir das erbebniss von "CPI r17, 255"
durch die DEC operationen verändert.
Beim verlassen von "warten:" sind die register R17..R19 == 0...
BRNE (springt wenn Z=0) dadurch nie.
und das ROR auf das leere R17 macht auch nicht viel sinn.
Du solltest beachten das der AVR weder beim CALL noch bei
einem IRQ irgend etwas von seinen registern von selbst sichert.
(mit ausnahme des PC).
wenn du also vor "call warten" einen verglich machst und
danach das ergebniss benutzen willst must du das SREG
in "warten:" sichern und wiederherstellen. Gleiches gilt
für die register.
als Beispiel:
warten:
push R17
in R17, SREG
push R17
push R18
push R19
; hier der eigentliche warten kram
pop R19
pop R18
pop R17
out SREG, R17
pop R17
ret
dann kanst du das call warten beliebig einbauen.
oder du rufst "warten:" vernünftig auf:
call warten
CPI r17, 255
BRNE main5
UND benutzt in "warten:" nicht das R17, R18 und R19
ausserdem vermisse ich ein
.cseg vor "init:"
Diese kaum lesbare und mit Fehler vollgestopfte Assemblerwurst ist
wieder mal ein gutes Beispiel dafür in C zu programmieren und den
Assemblercode vom Compiler erzeugen zu lassen.
Bevor man in Assembler programmieren kann MUSS man genau wissen wann
welcher Befehl auf welche Register einwirkt, und wie das geschieht.
@ Heiner:
Leg den µC mal für ein paar Wochen oder Monate zur Seite und fang an zu
lesen und zu lernen was der µC da bei den einzelnen Befehlen macht, oder
nicht macht.
Solange du das nicht weißt, macht es keinen Sinn in Assembler
rumzubasteln.
also vielen Dank für eure Antworten.
Das mit den Registern hatte ich übersehen, denn ich hatte einfach einen
Warteschleifengenerator verwendet.
Ich habe jetzt die Tipps befolgt und stelle das Programm nocheinmal
verkürzt hier rein. Jetzt müsste alles richtig sein, oder?
Achso, muss ich die Register immer sichern wenn ich in ein UP springe
oder nur wenn ich im UP diese Register verwende?
[avrasm]
;***************************************
.include "m16def.inc"
;***************************************
.def temp = r16
.def schieb = r17
.def aus = r18
.def an = r19
.org 0x0000
rjmp init ; Reset Handler
.org OVF0addr
.cseg
init: ldi temp, LOW (RAMEND) ; Stackpointer initialisieren
out SPL, temp
ldi temp, HIGH (RAMEND)
out SPH, temp
LDI R22, 0b11111111 ;initialisieren
OUT DDRA, r22
OUT DDRB, r22
OUT DDRC, r22
OUT DDRD, r22
LDI aus, 0b00000000
LDI an, 0b11111111
main: LDI schieb, 0b00000001 ;aufbau in rot
main1: ROR schieb
out PORTA, schieb
CPI schieb, 0b11111111
call warten
BRNE main1
main2: LDI schieb, 0b00000001
main3: ROR schieb
out PORTB, schieb
CPI schieb, 0b11111111
BRNE main3
call warten
out PORTA, aus ;alles aus
out PORTB, aus
; warte 1999998 Zyklen:
warten: ldi R23, $12
WGLOOP0: ldi R24, $BC
WGLOOP1: ldi R25, $C4
WGLOOP2: dec R25
brne WGLOOP2
dec R24
brne WGLOOP1
dec R23
brne WGLOOP0
ret
also vielen Dank für eure Antworten.
Das mit den Registern hatte ich übersehen, denn ich hatte einfach einen
Warteschleifengenerator verwendet.
Ich habe jetzt die Tipps befolgt und stelle das Programm nocheinmal
verkürzt hier rein. Jetzt müsste alles richtig sein, oder?
Achso, muss ich die Register immer sichern wenn ich in ein UP springe
oder nur wenn ich im UP diese Register verwende?
also jetzt scheint es endlich zu funktionieren :).
Nur bei PortC noch nicht.
Ihr hattet was mit dem JTAG gesagt.
Muss ich diesen setzen? Bei PonyProg steht da JTAGEN. dort muss ich dann
wohl noch ein Häkchen reinsetzten?
mfg
> Achso, muss ich die Register immer sichern wenn ich in ein UP springe> oder nur wenn ich im UP diese Register verwende?
Scheinbar ist die der Grundlegende Aufbau einer CPU noch nicht klar. Die
Register sind die Register. Da steht ein 8-Bit Wert drin, der der als
letztes reingeschrieben wurde. Wenn also eine Unterroutine (oder keine
Unterroutine) etwas in ein Register schreibt, dann steht das da drin und
er alte Wert ist weg. Die Warteroutine verändert also immer die Register
23,24 und 25. Das musst du beachten wenn du die Register auch woanders
im Programm benutzt.
Außerdem die Flags: Das ist auch nur ein Speicherplatz pro Flag. Mit
BRNE übeprüfst du immer den aktuellen Stand des Zero-Flags. Dem Befehl
ist es egal wann das Flag zum letzten mal verändert wurde. D.h. mit
[1] CPI schieb, 0b11111111
[2] call warten
[3] BRNE main1
dem BRNE in Zeile 3 überprüfst du nicht was beim CPI in Zeile 1 als
Ergebnis herausgekommen ist, sondern das BNRE in Zeile 3 prüft ob das
Zero-Flag gesetzt ist. Nur das jeder Befehl sich eventuell auf das
Zero-Flag auswirken kann (manche tun es, manche nicht). Und du hast ein
ganzes Unterprogramm zwischen dem CPI[1] und dem BNRE[2]. Die ganzen
DEC-Befehle im Unterprogramm verändern das Zero-Flag, speziell kann man
im Unterprogramm sehen dass es über einen BRNE-Befehl verlassen wird,
sprich wenn das Unterprogramm zurück kommt ist das Zero-Flag immer
gesetzt, der BNRE in Zeile 3 springt also nie nach main1.
Das Unterprogramm verändert also die Register R22-24 und das
Statusregister, sprich die Flags (du musst mal nachsehen welche Flags
von LDI und DEC verändert werden).
Hast du schon mal in einer höheren Programmiersprache wie Basic,Pascal
oder C programmiert? -> Wenn ja, steig auf C um. Das ist sehr viel
übersichtlicher.
Randy
Also wenn ich bei main1 als erstes warte und dann den Vergleich anstelle
müsste es ja gehen.
Mein Problem ist ja aber eigentlich nur, da bei PORTc kein Strom
ankommt, außer an c4 und c6.
bei den anderen scheint es ja zu gehen, laut Multimeter.
Muss denn ein ein Häkchn bei dem JTAGEN rein?
Ich werde die Porsitino von dem warten nocheinmal verändern.
Heiner