Hallo!
Hab mit meinem ATmega16 ein Problem mit der seriellen schnittstelle.
Und zwar hab ich ein Programm vom AT90S4433 auf den mega angepasst nur
läufts jetzt nicht. d.h. sobald der mega was über die serielle
schnittstelle empfängt und ein entsprechender interrupt ausgelöst wird
macht er nen neustart.
allerdings hab ich auch noch festgestellt, dass die gleichen routinen
und einstellungen funktionieren, wenn das programm ein bisschen kürzer
ist.
Was kann das jetzt sein? ist doch irgendwas an den einstellungen
falsch? ist das Flash vom mega kaputt und es wird nicht richtig
beschrieben? Hab es aber bis jetzt nur etwa 30 mal beschrieben. oder
liegts vielleicht an irgendwelchen fuse bits?
Danke
Bernhard
>>Und zwar hab ich ein Programm vom AT90S4433 auf den mega angepasst>>nur läufts jetzt nicht.
Das ist normal. Du mußt die geänderten Interrupt-Vektoren beachten und
anpassen (richtige Include-Dateien) und nochmals genau kontrollieren.
Hallo Bernhard,
dein Problem liegt zu 99% an den Interruptvektoren:
Vektor - adress (z.B.Mega8) - address (Mega16)
1 - 0x0000 - 0x0000
2 - 0x0001 - 0x0002
3 - 0x0002 - 0x0004
4 - 0x0003 - 0x0006 usw.
d.h. beim Mega16 (und vermutlich allen größeren avrs) geht z.B. TX
complete auf address 0x001A, bei den kleinen (z.B. Mega8) auf 0x000D,
obwohl TX complete in beiden Fällen der Vektor No. 14 ist.
Grüße leo
Hallo Leo!
Das kann durchaus sein!
Wie macht man dann am vernünftigsten für nen Mega16 die
Interrupt-Vektor-Sprung-Tabelle. Ich habs bisher so:
.org 0x00
rjmp anfang ; Reset
reti ; Int0
reti ; Int1
usw.
und so hauts ja anscheinend ned hin.
also was ist besser?
Danke
Bernhard
>>Du mußt die geänderten Interrupt-Vektoren beachten und>>anpassen (richtige Include-Dateien) und nochmals genau>>kontrollieren.
Mach es doch einfach einmal ! (Datenblatt)
Hi
.org 0x00
rjmp anfang ; Reset
reti ; Int0
reti
Genau das ist das Problem. Das RETI ist ein Wort breit, der Abstand der
Interruptvektoren ist aber zwei Worte, da dort gegebenenfalls ein CALL
stehen muss, welches zwei Worte breit ist.
So ist die ganze Interruptvektorentabelle Murks.
Danke an alle, jetz funktionierts so wie es soll!
Ich hab die Tabelle jetz so gemacht:
*** Sprungtabelle ***
.org 0x00
rjmp anfang ; RESET
.org 0x02
reti ; INT0
.org 0x04
reti ; INT1
.org 0x06
reti ; TIMER2 COMP
usw.
is zwar jetz ein bisschen unübersichtlich aber hauptsache es geht. oder
hat jemand nen besseren vorschlag?
Bernhard
@dave:
Danke! Hab leider die Include nicht, da ich gavrasm benutze. aber so
schauts ganz gut aus. wie hat man das dann früher gemacht? da gabs ja
auch schon avr mit großem speicher und da is ja dann auch nicht mit
rjmp gegangen oder?
@Dirk:
die vom mega8 passt ja nicht und da is ja dann überhaupt erst mit den
problemen angegangen.
mfg
Bernhard
Hallo Bernhard,
im Prinzip hast du ja bereits eine Lösung. Ich füge halt für jedes
"Sicherheits-reti" ein nop dazu: (hat auch den Vorteil dass
undefinierte Int-Ansprünge (0x01,0x03,0x05 usw) einen definierten
Programablauf haben. Wobei dieser Vorteil möglicherweise nur
theoretischer Natur ist; ich habe keine Ahnung ob solche Sprünge in der
Praxis durch irgendetwas ausgelöst werden. Und wenns nichts nutzt
schaden tuts auf keinen Fall ;-)
.org 0x00
rjmp reset.org 0x02
reti ; nicht benötigt
nop
reti ; auch unbenutzt
nop
rjmp int_prg ; INT1
reti ; und wieder unbenutzt
nop ; usw.
grüße leo
.org 0x00
rjmp reset ; 0
.org 0x02
reti ; 2
nop ; 3
reti ; 4
nop ; 5
rjmp int_prg ; 6
reti ; 7
nop ; 8
Bei der Methode würde ich aufpassen... hier wäre z.B. schon ein Vektor
etwas verrutscht (wers nich sieht: nach der 6 fehlt ein NOP, denn 7
müsste ja auf die 8).
@dave:
hast war, rjmps ( 1 word Speicherbedarf) durch calls ( 2 word breit)
ersetzen und es passt oder halt besser aufpassen, in assembler sollte
man sowieso immer wissen was man tut ;-)
grüße leo9
@leo: In der Tat, bei Assembler sollte man wissen, was man tut ;)
Mit nem call anstelle rjmp krachts garantiert. Die richtige Lösung gabs
doch oben schon.
Hi thkais,
stimmt natürlich. Da sollte nicht CALL stehen, sondern JMP (muss
geträumt haben). Wichtig bleibt, dass der der Abstand zwei Worte ist,
weil ein RJMP nicht den ganzen Speicher erreicht.
Eine eigene Frage?
Dieser Thread ist über 21 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.