mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega128 USART kriegs nicht zum Laufen / bin am verzweifeln


Autor: Uwe Emdot (ujmforum)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

bin inzwischen am verzweifeln, weil ich es einfahc nicht hinbekomme.
Habe zwei Platinen, eine mit ATmega128, eine mit WLAN-Funkmodul.
Das Funkmodul hat eine doppelte serielle Schnittstelle mit einem 
Doppeltreiberbaustein und kann serielle Daten von einem Multimeter wie 
gewünscht übertragen.
Aber ich krieg die USART im ATmega128 nicht zum Laufen. Ich versteh's 
einfach nicht, wie das funktionieren soll.
USART0 soll direkt an die Funkplatine rausgehen, USART1 geht über einen 
Treiberbaustein als RS232 raus, fast tupfengleich, wie der Baustein auf 
der Funkplatine.
Im Endeffekt sollen von 8 digitale Sensoren und 16 analoge Sensoren die 
Daten gesammelt werden und als Paket rausgesendet werden.
Ich bekomm aber nicht mal ein Zeichen hin.
Könnt Ihr mir vielleicht helfen, ich weiß hier einfach nicht mehr 
weiter.

Danke schon mal und viele Grüße,
Uwe

Autor: Uwe Emdot (ujmforum)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier noch Teil 1 des Schaltplans...

Autor: Uwe Emdot (ujmforum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... und noch der zweite Teil des Schaltplans.
Die Spannungsversorgung mit Schaltregler und die zweite Platine habe ich 
weggelassen.

Autor: Uwe Emdot (ujmforum)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
jetzt aber

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Lt. deinem Schaltplan geht USART0 an den RS232-Treiber. Da RXD0/TXD0 
auch zu Programmieren benutzt werden könnte ein Hardwarekonflikt mit dem 
Programmer entstehen.

MfG Spess

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mega103 Modus deaktiviert?

Autor: Uwe Emdot (ujmforum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Programmieren läßt er sich tadellos, wird auch fehlerfrei und richtig 
ausgelesen. Das Problem hatte ich ganz zu Beginn, weil hier MISO/MOSI 
auf die anderen PINs PDO/PDI umgelegt ist.
Der Kompatibilitätsmodus zum Mega103 ist deaktiviert und er läuft sauber 
mit den 7,37 Mhz.
Das mit dem Programmer ist natürlich eine Idee, daran hab ich nicht 
gedacht, da ja die Doppelbelegung genau auf diesen PINs liegt.

Muß ich ausprobieren. Hoffentlich liegt's daran.

Autor: Uwe Emdot (ujmforum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus könnte von euch bitte nochmal jemand über die USART-Funktionen 
drübergucken. Ich bekomm's einfach nicht hin, daß auch nur ein Zeichen 
rübergesendet wird.
Das Einzige was funktioniert ist Loopback auf dem Channel 1 = USART0 und 
dem Channel 3 = USART1 (via MAX 3221).
In meiner void main(void) While-Schleife steht genau folgendes drin
int main (void) {
  startinit();    // das was auch oben im dokument1.txt schon drin ist
  while (1) {
    USART0_Transmit('b');
    USART0_Transmit('a');
  }
}

Also müßten doch, je nach Pins, entweder lauter "b" oder "a" auf dem 
Hyperterminal rauskommen. Aber nüscht passiert. Stattdessen 
funktionieren beide Kanäle wie Loopbacks, egal was ich im Hyperterminal 
eingebe, genau so kommt's auch gleich wieder raus. Im Main ist aber 
nirgends was mit
USART_Tranmit( USART_Receive() );
 drin. Es kommt einfach nichts raus.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Listing ist für eine gepufferte, interruptgesteuerte 
UART-Übertragung.

Bei deinem Code
int main (void) 
{
  startinit();    // das was auch oben im dokument1.txt schon drin ist
  while (1) {
    USART0_Transmit('b');
    USART0_Transmit('a');
  }
}

fehlt mindestens das Einschalten der Interrupts mit sei() nach 
startinit() und vor while().

Wenn das nicht hilft...

...in dem Listing ganz oben ist eine Testroutine drin. Teste mal die 
main-Funktion mit dieser Testfunktion. Die sollte dann alle empfangenen 
Zeichen gleich wieder zurückgeben.
int main (void) 
{
  USART_ISR_test();
}

Wenn das auch nicht funktioniert, würde ich an deiner Stelle alle 
bisherigen Änderungen zurückfahren und mit dem Ausgangslisting neu 
anfangen bis der Test OK verläuft.

Autor: Uwe Emdot (ujmforum)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
cli(); und sei(); und die Initialisierung der beiden USARTs habe ich 
auch in der Funktion startinit(); drin, aber es passiert nix.

Wenn ich das hier als main schreibe, müßten doch einfach permanent auf 
Kanal 1 und auf Kanal 2 'a's ausgegeben werden oder? Ganz ohne Interupt, 
ganz ohne sonstwas dazu. Einfach reinschreiben, senden, reinschreiben, 
senden, ...
int main (void) {
  startinit();
  unsigned char data = 'a';

  while (1) {
    /* USART0: Wait for empty transmit buffer */
    while ( !( UCSR0A & (1<<UDRE0)) );
    /* USART0: Put data into buffer, sends the data */
    UDR0 = data;
    LEDOnOff(2, 25);

    /* USART1: Wait for empty transmit buffer */
    while ( !( UCSR1A & (1<<UDRE1)) );
    /* USART1: Put data into buffer, sends the data */
    UDR1 = data;
    LEDOnOff(3, 25);
//    USART_ISR_test();
  }
  return 0;
}

Ich glaub ich bin zu doof dazu, nicht mal das einfachste bekomm ich hin.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Uwe Emdot (ujmforum)

>Das Einzige was funktioniert ist Loopback auf dem Channel 1 = USART0 und
>dem Channel 3 = USART1 (via MAX 3221).

Ist da ein Kurzschluss auf dem Board?

>Also müßten doch, je nach Pins, entweder lauter "b" oder "a" auf dem
>Hyperterminal rauskommen. Aber nüscht passiert.

Mal mit dem Oszi oder Logiktester nachgeschaut?

>funktionieren beide Kanäle wie Loopbacks, egal was ich im Hyperterminal
>eingebe, genau so kommt's auch gleich wieder raus. Im Main ist aber
>nirgends was mit
>USART_Tranmit( USART_Receive() );
> drin. Es kommt einfach nichts raus.

Schau dir aml deine Hardware GENAU an. Lass mal per Software langsam (1 
Hz oder so) das TX Pin toggeln und verfolge das Signal vom uC über 
MAX232 bis zum PC. Vergiss nicht das Pin als Ausgang zu schalten.

>Dateianhang: Dokument2.txt (19,5 KB, 0 Downloads)

>cli(); und sei(); und die Initialisierung der beiden USARTs habe ich
>auch in der Funktion startinit(); drin, aber es passiert nix.

Das sei() mach erstmal lieber raus, das kann komische Seiteneffekte 
verursachen.

>Wenn ich das hier als main schreibe, müßten doch einfach permanent auf
>Kanal 1 und auf Kanal 2 'a's ausgegeben werden oder?

Nöö, du schreibst nur auf UART0, erst 'a' dann 'b'.

> Ganz ohne Interupt,

Doch, der RXC ist aktiv. Wenn da in der ISR Murks drinsteht kann sich 
der uC aufhängen. Scheint aber OK zu sein. Ich würde dennoch sei() 
erstmal weglassen. UNd räum mal deinen Sourcecode auf, da sieht keiner 
sonderlich durch.

MFG
Falk

Autor: Uwe Emdot (ujmforum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich mach schluß, ich seh den Wald vor lauter Bäumen nicht mehr.
Ich probier das morgen aus und toggel alles langsam durch und geh noch 
einmal jedes einzelne Register und Bit durch, ob vielleicht daran 
irgendwas hängt.
Das einzige was bisher funktioniert ist die LEDs blinken lassen, das 
worauf's ankommt macht nüscht.
Das woran's nicht hakt ist die WLAN-Funkplatine, wo ich dachte, daß es 
hakt, aber da funktionieren beide RS232-Treiber und funken auch fröhlich 
in beide Richtungen.

Mal danke für heute.
Uwe

Autor: Uwe Emdot (ujmforum)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab jetzt mal alles aus dem Code rausgenommen was mit 
USART-Konfiguration, -Interrupt oder sonstwie zu tun hat.
struct usarts {
  byte b0 : 1;
  byte b1 : 1;
  byte b2 : 1;
  byte b3 : 1;
  byte b4 : 1;
  byte b5 : 1;
  byte b6 : 1;
  byte b7 : 1;
} __attribute__((_packed_));

#define USART_BIT(port, bitnummer)  (((volatile struct usarts *)&port)->b##bitnummer)
#define CH1_RXD        USART_BIT(PORTD, 2)          // Port DDDD,  USART1, Eingang
#define CH1_TXD        USART_BIT(PORTD, 3)          // Port DDDD, USART1, Ausgang
#define CH3_RXD        USART_BIT(PORTE, 0)          // Port EEEEE, USART0, Eingang
#define CH3_TXD        USART_BIT(PORTE, 1)          // Port EEEEE, USART0, Ausgang
#define CH1_RXD_DDD2  DDD2                        // Port D2 Direction Register
#define CH1_TXD_DDD3  DDD3                        // Port D3 Direction Register
#define CH3_RXD_DDE0  DDE0                        // Port E0 Direction Register
#define CH3_TXD_DDE1  DDE1                        // Port E1 Direction Register
#define on  1
#define off  0

void startinit (void) {
  DDRA = (1<<MUXSEL3_DDA0  | 1<<MUXSEL4_DDA1  | 1<<MUXSEL7_DDA2  | 1<<MUXSEL8_DDA3  | 1<<MUXSEL1_DDA4  | 1<<MUXSEL2_DDA5  | 1<<MUXSEL5_DDA6  | 1<<MUXSEL6_DDA7);
  DDRB = (1<<EXT_DIG2_DDB0 | 0<<DDB1          | 0<<DDB2          | 1<<DDB3          | 1<<EXT_DIG1_DDB4 | 0<<DDB5          | 0<<ANANUM1_DDB6  | 0<<ANANUM2_DDB7);
  DDRC = (0<<DDC0          | 0<<DDC1          | 0<<DDC2          | 0<<DDC3          | 0<<DDC4          | 0<<DDC5          | 1<<LEDSTAT1_DDC6 | 1<<LEDSTAT2_DDC7);
  DDRD = (0<<DDD0          | 0<<DDD1          | 0<<CH1_RXD_DDD2  | 1<<CH1_TXD_DDD3  | 0<<DDD4          | 0<<DDD5          | 0<<DDD6          | 0<<DDD7);
  DDRE = (0<<CH3_RXD_DDE0  | 1<<CH3_TXD_DDE1  | 1<<EXT_DIG8_DDE2 | 1<<EXT_DIG7_DDE3 | 1<<EXT_DIG6_DDE4 | 1<<EXT_DIG5_DDE5 | 1<<EXT_DIG4_DDE6 | 1<<EXT_DIG3_DDE7);
  DDRF = (0<<MUX_ANA1_DDF0 | 0<<MUX_ANA2_DDF1 | 0<<MUX_ANA3_DDF2 | 0<<MUX_ANA4_DDF3 | 0<<MUX_ANA5_DDF4 | 0<<MUX_ANA6_DDF5 | 0<<MUX_ANA7_DDF6 | 0<<MUX_ANA8_DDF7);
  DDRG = (0<<DDG0          | 0<<DDG1          | 1<<LEDSTAT3_DDG2 | 0<<ANANUM3_DDG3  | 0<<ANANUM4_DDG4);

...
}

int main (void) {
  startinit();

  while (1) {
    CH1_RXD = on;
    CH1_TXD = on;
    CH3_RXD = on;
    CH3_TXD = on;
    LEDSTAT2 = off;
    LEDSTAT3 = on;
    _delay_ms(1000);

    CH1_RXD = off;
    CH1_TXD = off;
    CH3_RXD = off;
    CH3_TXD = off;
    LEDSTAT2 = on;
    LEDSTAT3 = off;
    _delay_ms(1000);
  }
  return 0;
}

Gemessen habe ich direkt an den Pins PE1 (gelb) und PD3 (türkis).

Autor: Uwe Emdot (ujmforum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe die Lösung gefunden.
Die beiden Bausteine MAX3221 (auf uP-Platine) und MAX3223 (auf 
WLAN-Platine) gehen automatisch in Sleep-Mode, wenn keine korrekten 
RS232-Pegel anliegen.
Tristate scheint das Zauberwort, auf das ich auch hereingefallen bin.

Will heißen, daß es funktioniert hat solange ich direkt mit dem PC über 
Kabel verbunden habe. Die PC-Pegel haben einerseits den Baustein 
wachgehalten, andererseits haben diese das Ausgangssignal des 
uP-RS232-Treibers überlagert haben und daher kam nichts an, erst auf dem 
Oszi war das zu erkennen. (Danke an den Verleiher ;-) )

Entgegen der 'typischen Beschaltung' aus dem Datenblatt der 
MAX-322x-Bausteine muß der FORCEON-Pin auf VCC und nicht auf GND liegen. 
Damit bleibt der Baustein immer aktiv und kann in der 3,3-Volt Umgebung 
(wie bei mir eben) normal funktionieren. Andernfalls legen sich die 
Bausteine beide schlafen und können sich mit den kleinen Pegeln nicht 
mehr aus dem Schalfmodus aufwecken.

Mann-O-Mann, das hat Nerven gekostet. Vielen dank an alle, die mir Tips 
gegeben haben und mal drübergeschaut haben.

Viele Grüße und nen streßfreien Jahreswechsel.

Uwe

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Glückwunsch für das erfolgreiche Debuggen. Das war ja mal eine besonders 
hartnäckige und hinterlistige Wanze!

Vielleicht sollte man deine interessanten Erfahrungen irgendwo im Wiki 
bei den beiden ICs MAX3221 und MAX3223 festhalten. Tipps und Tricks bei 
UART vielleicht?

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.