Forum: Mikrocontroller und Digitale Elektronik schreiben/lesen ATMega16


von Julian Bozler (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe ein ATMega16@16MHz und programmier ihn mit ICCAVR & dem AVR
Studio (über einen JTAG)
Nun will ich ihm etwas über die serielle schnittstelle schicken und er
soll es mir zurückschicken (Verbindung über 1:1 kabel, MAX3232). Dazu
hab ich den code im anhang geschrieben.
Die Fuse-Bits hab ich im AVR-Studio geändert:
*on-chip debug enable
*JTAG enable
*Boot flash section size = 1024
*Brown out VCC = 2,7
*Ext. Crystal high frequency (CKSEL 1111, SUT 11)

Wenn ich nun etwas sende löst der interrupt aus (RXC wird gesetzt) und
die entsprechende interrupt-routine
(#pragma interrupt_handler uart0_rx_isr:12) wird gestartet. Er
"empfängt" ein zeichen und "sendet" es wieder zurück - zumindest
wird er entsprechende code (putchar bzw. getchar) ausgeführt. Aber
weder bekomm ich ein Signal am PC, noch erkennt der µC wirklich das
zeichen. frag ich nach "character=getchar()" den wert in
"character" ab (zb. if character = 'I') so kann er das zeichen
nicht zuordnen (sprich er hat das geschickte 'I' nicht als solches
erkannt.

ich hab nun schon ne menge foren und tutorials durchgelesen, aber ich
komm nicht weiter - wäre euch sehr dankbar für ein paar tips!

Gruß julian

PS.: hab den beitrag eben schon bei "µC & Elektronik" gepostet, passt
aber wohl eher hier rein. SORRY!

von Wolfram (Gast)


Lesenswert?

Du scheinst eine ganze Menge Verständnisprobleme zu haben.
Wenn der Interrupt aktiviert wird dann IST ein Zeichen in der UART,
man wartet nicht noch auf ein Zeichen! Man holt das Zeichen aus UDR
wenn kein Fehler vorliegt und schaft es in einen
Zwischenpuffer.(volatile)
Dann ist schluss mit dem Interrupt. Vor allem sendet man nicht noch aus
dem Empfangsinterrupt. Auch der aufruf anderer Routinen sollte
tunlichst
unterlassen werden da dies je nach C-Compiler zum Sichern einer ganzen
Menge von Registern führt.
Schau dir in der Codesection ein paar Beispiele an wie man
interruptgesteuerten Betrieb handhabt.

von Julian Bozler (Gast)


Lesenswert?

hmm, du hast recht - ich hab eigentlich ein besseres programm
geschrieben (ohne aufruf in der empfangsroutine), aber das wäre zu lang
gewesen um es hier anzuhängen. deshalb hab ich schnell das geschrieben,
um mein problem zu zeigen. aber da sind ganz klar ein paar fehler die
ich abstellen muss. werd das ändern und dann den verbesserten code
wieder reinstellen.
Dieser fehler ist aber wohl nicht das problem das ich habe, denn wenn
ich einfach nur sende (putchar('I')) empfängt der PC auch nichts.

(zum verständnis sei noch gesagt, dass ich weiß, dass beim auslösen des
interrupts ein zeichen da ist, aber man muss es trotzdem holen (hier mit
getchar)... von warten hab ich doch garnix gesagt?!)

Danke, gruß julian

von Julian Bozler (Gast)


Lesenswert?

ups... soviel zum verständnis... du hast natürlich recht, man kann
einfach den wert zurückgeben. weiß garnicht wie ich auf den mist komm,
danke

von Karl H. (kbuchegg)


Lesenswert?

> Dieser fehler ist aber wohl nicht das problem das ich habe, denn
> wenn ich einfach nur sende (putchar('I')) empfängt der PC auch
> nichts.

Die üblichen Verdächtigen:
* Ist die Max232 Beschaltung in Ordnung?
  Kann einfach getestet werden. Nimm den Mega32 aus dem Sockel.
  Verbinde im Sockel Tx mit RX und klimpere am PC-Keybord
  dahin. Die vom PC gesendeten Zeichen gehen über das Kabel
  durch den Max zum C Sockel, werden sort durch deine Draht-
  brücke wieder zum Max geschickt und gehen über das Kabel
  zurück zum PC, wo das Terminalpgm sie anzeigt.

  Klappt das nicht, dann hast du einen Hund in der Verkabelung
  oder im Max

* Steht diese Verbindung, dann frage ich mich, warum du
  die Baudratenberechnung nicht vom Compiler erledigne lassen
  willst, sondern selbst ausgerechnet hast. Ich hab nicht
  nachgerechnet, stimmen die Werte?

* Bist du 100% sicher, dass dein Mega16 auch wirklich auf
  der Taktfrequenz arbeitet, die du annimmst (16 MhZ). Du
  wärst nicht der erste, der Stein und Bein schwört, daß er
  auf externen Quarz umgeschaltet hat und in Wirklichkeit läuft
  der µC immer noch auf den 1Mhz mit der er ausgeliefert wird.

von Julian Bozler (Gast)


Lesenswert?

Super Vorschlag, das probier ich morgen doch als erstes!!! DANKE!

Ich denk fast die signale könnten vom max falsch zum µC kommen, mir is
aber kein guter test eingefallen... aber das is ja so simpel, dass es
schon wieder genial ist!

Ich hab die Werte für die serielle Schnittstelle nicht selbst
ausgerechnet, sondern mir von einem "application-builder" machen
lassen, werd das aber in dem kleinen prog auch ändern, allein um diese
fehlerquelle auszuschließen.

Und nein, ich bin mir keineswegs sicher, dass er auf 16MHz läuft ;)
aber ich hab folgenden grund zur annahme, dass es so ist:
Bisher hatte ich 1MHz interner takt und hatte die schnittstelle auch so
initialisiert. Hab ich sie auf 16MHz initialisiert (bei wirklichem takt
1MHz) hat der interrupt logischer weise nicht ausgelöst. Jetzt hab ich
die fuse-bits gesetzt, damit er die 16MHz vom oszilator annimt und
jetzt akzeptiert er die initialisierung mit 16MHz. Bei der
initialisierung mit 1MHz (bei vermutetem wirklichen takt 16MHz) spricht
der interrupt nicht an. Daher vermute ich es müsste passen, aber
zugegebenermasen ist das nen schlechter test. Aber ich wußte nicht wie
ich den takt "ablesen" kann, gibt's da was?

Danke Karl-Heinz, du hast mich echt weitergebracht. Wie man sieht bin
ich nicht sehr erfahren auf diesem Gebiet und so "einfache aber
effektive" Kniffe kenn ich nicht...

Gruß Julian

von Julian Bozler (Gast)


Lesenswert?

So - der fehler liegt wirklich bereits am max3232... wenn ich den mega
rausnehm und RX und TX "kurzschließe" meldet das terminal-prog einen
I/O-Error.
Allerdings hab ich nochmal die beschaltung geprüft (vergl. mit dem
datenblatt, C1=0,1µF; C2=C3=C4=0,33µF (wegen VCC=5V) richtig?) und
getestet ob die lötstellen ok sind, sogar den max ausgetauscht hab ich
- da liegt der fehler nicht.
Aber ich werd weiter dran rumprobieren - weiß ja jetzt wenigstens an
welcher stelle ich suchen muss... für hilfe bin ich aber weiterhin
offen, falls mal jemand ein ähnliches problem hatte...

Danke&Gruß

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> So - der fehler liegt wirklich bereits am max3232... wenn ich den
> mega rausnehm und RX und TX "kurzschließe" meldet das
terminal-prog
> einen I/O-Error.

Dann erwartet das vermutlich aktive Modem-Steuersignale, die du mit
dem AVR gar nicht generierst.  Stell das Teil mal um, dass es sowas
nicht tut (kein flow control, kein DSR, kein DCD).  Auf der
RS-232-Ebene gibt es eigentlich gar keine "IO Errors", bestenfalls
framing errors (Stopbit ist nicht in der erwarteten Position
gekommen).

von Julian Bozler (Gast)


Lesenswert?

ahh, auch ein guter tip - werd ich ausprobieren. Aber ganz verstehn tu
ich's ehrlich gesagt nicht:
wenn ich mit den momentanen einstellungen einfach am kabel RX und TX
kurzschließ klappt es - das signal wird sofort wieder vom terminal prog
empfangen. Ich hätte also vermutet, dass es auch klappen muss, wenn ich
es hinter dem MAX kurzschließe - könnte I/O-Error nicht bedeuten, dass
die vom MAX generierten Spannungen außerhalb des erlaubten
spannungsbereich liegen? (werd ich mal mit nem Oszi nachmessen)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Nö, Spannungen kann die serielle Schnittstelle so nicht messen.

Kann natürlich sein, dass dir die framing errors als "IO-Error"
angezeigt werden.  Zumindest hast du ja offensichtlich wirklich
den MAX232 als Fehlerursache eingekreist.

von Marco S. (masterof)


Lesenswert?

schliese mal größere Kondensatoren

von Julian Bozler (Gast)


Lesenswert?

was hattest du gedacht bei größeren kondensatoren? bisher sind's wie
gesagt  C1=0,1µF; C2=C3=C4=0,33µF - so steht's im datenblatt für
VCC=5V...wie kommst du auf größere?
Danke&Gruß

von Marco S. (masterof)


Lesenswert?

ich hatte auch probleme mit dem max und ich hatt einen wert 1.0 µf im
Kopf und da mit ging es dann. Ob wohl es laut daten plat es 0.1µF sein
sollte.
Gruß Marco

von Julian Bozler (Gast)


Lesenswert?

interessant... werd ich doch grad mal ausprobieren... danke

von Julian Bozler (Gast)


Lesenswert?

also das hab ich ausprobiert mit 1,0µF... hat das problem leider eher
verschärft. selbst wenn ich die RX- und TX-Leitung nicht kurzschließe
kommen irgendwelche sonderzeichen zurück.
mit dem andern terminal-prog wird mir wieder ein I/O-Error
ausgegeben...
hab nun mehrfach die beschaltung durchgeschaut - ganz wie im datenblatt
- und auf kurzschlüsse geprüft. Mit fehlt's ein wenig an ideen was ich
noch machen könnte, obwohl der fehler ja klar eingegrenzt ist. (am IC
liegt's übrigens nicht, hab nen andern eingesetzt der genau gleich
reagiert)

Für hilfe wäre ich also sehr dankbar...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Die Abblockung stimmt aber auch?  Nicht, dass deine Betriebs-
spannung an der Ladungspumpe zu weit einbricht.  Im Zweifelsfalle
einfach mal nur den Abblock-Kondensator vergrößeren, aber die
Kondensatoren der Pumpe belassen.  Denk auch dran, dass normale
Elkos eine ziemlich hohe Impedanz für höhere Frequenzen haben,
sodass man ihnen normalerweise noch einen 100-nF-Kerko parallel
schaltet.

von Julian Bozler (Gast)


Lesenswert?

danke auch für diesen tip, aber das problem hat sich zwischenzeitlich
gefunden:
in der standart -eagle-lib war die serielle schnittstelle anders
definiert als sie in wirklichkeit ist, d.h. pin 1=pin 5, pin 2=pin4,
usw... bei den sende- und empfangspins hab ich das recht schnell
gemerkt und verbessert, vergessen hatte ich allerdings den GND pin, der
immernoch falsch lag... das war alles - prog funktioniert einwandfrei
und alles ist wie es sein sollte...
DANKE für eure hilfe, hat mir wirklich viel gebracht(vorallem
fehlereingrenzung war sehr wichtig)!

Gruß Julian

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Pah!

von Julian Bozler (Gast)


Lesenswert?

dummer fehler, ich weiß - dickes sorry und noch viel größeren dank für
deine hilfe...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.