UART funzt nich - ASM (Assembler) - ATMEGA16

#223911
Lesenswert?

Bist du dir sicher, dass er beim Empfang wirklich den Interrupt nach
"INT_RXC" macht? Weil folgendes sagt mir grad nix:
".org URXCaddr
        rjmp INT_RXC"

logischerweise musst du "rjmp INT_RXC" an die Stelle schreiben, wo er
beim USART Receive Complete Interrupt hinspringt und das wäre bei
"         reti;rjmp USART_RXC         ; USART RX Complete Handler"
Gast #223915
Lesenswert?

Hi

Ich weiss zwar nicht wie dein Code jetzt aussieht, aber versuch mal
einfach dir Struktur der Interrupttabelle aus den Datenblatt zu
übernehmen. Ansonsten schau dir die Codebeispiele noch mal genau an.

Mfg HG
Gast #223917
Lesenswert?

; Interruptroutine: wird ausgeführt sobald ein Byte über das UART
empfangen wurde
INT_RXC:
1.  push temp        ; temp im stack sichern
2.  in temp, UDR     ; Empfangenes Byte in R16(temp) laden
3.  ldi temp, 0x02
4.  out PORTA, temp   ; R16 über PortA (LEDs) ausgeben
5.  pop temp   ; temp wiederherstellen
6.  reti     ; Interrupt beenden

Hi,
Was ist mit 3.? Egal was du empfängst, Du gibts immer 0x02 aus...

Muss man in einer Interruptroutine generell das SREG sichern, Du seztz
mit Sicherheit das Z-Flag, wenn du "NULL" empfängst.
Sonst: Es könnte sein, das deine Interrupttabelle aus einem Programm
mit einem anderen Chip stammt. da sieht die Tabelle dann anders aus.
Habe ich jetzt aber nicht überprüft.
Gruß
Axel
Gast #223919
Lesenswert?

Schicke bitte nochmal den Quelltext..

c&p ist nicht immer gut:
"die interrupttabelle ist ja 1 zu 1 von anderen programmen
kopiert.."

Ab 16kB Flash sind die IntVektoren immer mit 2 Words bestückt (für
JMP).

Deswegen nochmal den Quelltext.
Gast #223920
Lesenswert?

nun ich denke eins geht nur:
etweder die Interrupttabelle mit allen Ints untereinander aufführen.
Dann aber mit JMP statt RJMP( siehe Dave, siehe Datenblatt Mega16 Seite
44), oder nur mit den vordefinierten Adressen aus der mega16.inc
(.xxxadr) arbeiten. diese sollten auf alle Fälle stimmen.

Du kannst das Programm doch mal in's AVR Studio laden und das URXC
Flag von Hand setzen, dann siehst du, welcher IntVector angesprungen
wird.
Gast #223922
Lesenswert?

mit reti+nop passt es,

beim ersten posting hat es auch gepasst:

".org URXCaddr
        rjmp INT_RXC"

war schon richtig..

Andere (gemeine) Frage:
Warum hast Du das nicht selbst schonmal im AVR Studio probiert?
Machst wohl noch nicht so lange, oder?

Gruß auch an alle
AxelR.
Angehängte Dateien:
Gast #223923
Lesenswert?

Hier ist nochmal der Quellcode, ich hab die Teile, die nichts damit zu
tun haben, herausgeschnitten.
In der INT_RXC schaltet er nur zum Testen die LEDs in einen
festgelegten Status um, damit ich sehen kann, ob er überhaupt was
empfängt.
und ja, ich schreib das ganze in avr-studio und bin selbstverständlich
blutiger anfänger.. bis jetzt habe ich assembler ausschließlich für den
pc verwendet, das hier ist mein erster controller.
allerdings hatte ich doch auch schon ein programm geschrieben, in dem
der chip empfangen konnte und die leds danach geformt hat.

mfg
Angehängte Dateien:
Gast #223926
Lesenswert?

Ist es zuviel verlangt, mal in das Datasheet vom Controller
reinzuschauen? Da steht auf Seite 44 schon drin wie die IRQ-Tabelle
auszusehen hat. Deine Version braucht 4 Worte pro Eintrag, vorgesehen
sind 2 (Mega16 aufwärts).

Der Tip oben mit den NOPs ist nicht ganz passend. NOP nach RETI
braucht's nur dann, wenn für den jeweiligen Vektor kein JMP drin
steht. Also entweder JMP, oder RETI/NOP.
Gast #223928
Lesenswert?

Sag mal, hast Du Brett vorm Kopf, oder was?
Benutzt Du IRQ-Tabelle mußt Du jeden Eintrag mit 2 Words füllen, OK?

Also, IRQ-Tabelle ohne ISR (Interrupt Service Routine) =

 RETI  ;  1 Word
 NOP   ;+ 1 Word = 2 Words

Mit ISR =

 JMP int_rxc  ;  2 Word

ODER

 RJMP int_rxc ;  1 Word
 NOP          ;+ 1 Word = 2 Words

Machst Du es so wie

.org URXCaddr
        rjmp int_rxc

braucht man das nicht zu machen weil durch .org URXCaddr die Adresse
für den INT-Vektor für URXC an die rivhtige Stelle gepflantzt wird.
Solltest Du aber noch einen Interrupt hinzufügen mußt Du das je nach
Adresse ob niedriger oder höher davor oder dahinter setzen.
Gast #223929
Lesenswert?

sag mal.. entweder blick ich hier überhaupt nix mehr, oder sonst was..
guck dir meinen vorletzten beitrag mal an.. interrupt.asm ...da hab ich
es doch genauso gemacht, wie du es eben beschrieben hast. und ganz am
anfang vom beitrag hatte ich es ja auch noch so:
.org URXCaddr
        rjmp int_rxc
und es funktionierte nicht... und in dem alt.asm was ich hier gepostet
habe, ist auch eine interrupttabelle mit NUR rjmp und reti und die
funktionierte ja komischerweise auch..

ich check langsam echt nix mehr :/
Gast #223930
Lesenswert?

>und ganz am
anfang vom beitrag hatte ich es ja auch noch so:
.org URXCaddr
        rjmp int_rxc
und es funktionierte nicht...

doch, das hat funktioniert!
Nur hast Du die empfangenen Daten mit 0x02 überschrieben. Eigentlich
wolltest Du nur zusätzlich die LED schalten, hast aber mit "ldi
temp,0x02" den Wert den Du vorher mit "in temp, UDR" immer wieder
überschrieben. Wenn Du die Ausgabe "formen" willst, (was immer das
heissen mag) musst Du , wenn überhaupt "andi temp,0x02" machen und
das dann ausgeben.
Gast #223931
Lesenswert?

das hab ich nur als beispiel gemacht, um zu sehen, ob das unterprogramm
überhaupt aufgerufen wird. wäre es aufgerufen worden, wäre es völlig
egal gewesen, WAS empfangen worden wäre. somit hätten sich alle leds
bis auf das 2. ausschalten müssen (oder das 2. an).
--> tut es aber nicht
Gast #223934
Lesenswert?

hier sind doch lauter ehrfahrene leute, die wahrscheinlich schon
ettliche controller programmiert haben. ich selbst habe nur erfahrung
mit pic-controllern, aber ich wollte halt mal nen ATMEL-Controller
ausprobieren. Bloß der will nicht so wie ich.
Wenn jemand mal kurz ein programm schreiben könnte, welches einfach die
empfangenen bytes über port A (LED-Leuchten) wieder ausgibt.. das lad
ich dann mal drauf und teste es, falls derjenige keinen baugleichen
controller hat.

mfg

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren