mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega16: Problem mit serieller schnittstelle


Autor: Bernhard Mayer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>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.

Autor: Bernhard Mayer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das hab ich schon gemacht. wie gesagt, ein kleines testprogramm mit den
selben interrupt-vektoren, include-datei und port-initialisierung läuft
ja.

Autor: Michi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na dann poste mal Dein Programm.

Autor: Bernhard Mayer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
werd ich heute abend gleich machen

Autor: leo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Bernhard Mayer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Du mußt die geänderten Interrupt-Vektoren beachten und
>>anpassen (richtige Include-Dateien) und nochmals genau
>>kontrollieren.

Mach es doch einfach einmal ! (Datenblatt)

Autor: Thomas Burkhardt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Bernhard Mayer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dann ist mir das auch klar. aber wie schreibt man dann jetzt die
Interruptvektorentabelle auch formal richtig, dass da alles drin ist?

Autor: Bernhard Mayer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: dave (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kommt ganz einfach daher, dass man mit nem RJMP nicht mehr in den
ganzen Speicher kommt, folglich muss in den Vektor ein JMP reinpassen.
Wie wärs mit
RETI + NOP
oder einfach die Definitionen ausser Include nehmen?
.org URXC0addr
 rjmp irgendwohin

(aus der m161def.inc)
.equ  INT0addr  =$002  ;External  Interrupt0 Vector Address
.equ  INT1addr  =$004  ;External Interrupt1 Vector Address
.equ  INT2addr  =$006  ;External Interrupt1 Vector Address
.equ  CMP2addr  =$008  ;Input Capture1 Interrupt Vector Address
.equ  OVF2addr  =$00a  ;Overflow1 Interrupt Vector Address
.equ  ICP1addr  =$00c  ;Input Capture1 Interrupt Vector Address
.equ  OC1Aaddr  =$00e  ;Output Compare1A Interrupt Vector Address
.equ  OC1Baddr  =$010  ;Output Compare1B Interrupt Vector Address
.equ  OVF1addr  =$012  ;Overflow1 Interrupt Vector Address
.equ  CMP0addr  =$014  ;Overflow1 Interrupt Vector Address
.equ  OVF0addr  =$016  ;Overflow0 Interrupt Vector Address
.equ  SPIaddr    =$018  ;SPI Interrupt Vector Address
.equ  URXC0addr  =$01a  ;UART Receive Complete Interrupt Vector Address
.equ  URXC1addr  =$01c  ;UART Receive Complete Interrupt Vector Address
.equ  UDRE0addr  =$01e  ;UART Data Register Empty Interrupt Vector
Address
.equ  UDRE1addr  =$020  ;UART Data Register Empty Interrupt Vector
Address
.equ  UTXC0addr  =$022  ;UART Transmit Complete Interrupt Vector Address
.equ  UTXC1addr  =$024  ;UART Transmit Complete Interrupt Vector Address
.equ  EERDYaddr  =$026  ;UART Transmit Complete Interrupt Vector Address
.equ  ACIaddr    =$028  ;Analog Comparator Interrupt Vector Address

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

schau mal ins AVR Tutorial unter Interrupts befindet sich die Mega8
Tabelle. Ich nutze diese und passe Sie nachdem Datenblatt an.

Dirk

Autor: Bernhard Mayer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: leo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: dave (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
.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).

Autor: leo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: thkais (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Autor: Thomas Burkhardt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.