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


von Uwe E. (ujmforum)


Angehängte Dateien:

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

von Uwe E. (ujmforum)


Angehängte Dateien:

Lesenswert?

Hier noch Teil 1 des Schaltplans...

von Uwe E. (ujmforum)


Lesenswert?

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

von Uwe E. (ujmforum)


Angehängte Dateien:

Lesenswert?

jetzt aber

von Falk B. (falk)


Lesenswert?


von spess53 (Gast)


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

von Markus (Gast)


Lesenswert?

Mega103 Modus deaktiviert?

von Uwe E. (ujmforum)


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.

von Uwe E. (ujmforum)


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
1
int main (void) {
2
  startinit();    // das was auch oben im dokument1.txt schon drin ist
3
  while (1) {
4
    USART0_Transmit('b');
5
    USART0_Transmit('a');
6
  }
7
}

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
1
USART_Tranmit( USART_Receive() );
 drin. Es kommt einfach nichts raus.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Das Listing ist für eine gepufferte, interruptgesteuerte 
UART-Übertragung.

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

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.
1
int main (void) 
2
{
3
  USART_ISR_test();
4
}

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.

von Uwe E. (ujmforum)


Angehängte Dateien:

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, ...
1
int main (void) {
2
  startinit();
3
  unsigned char data = 'a';
4
5
  while (1) {
6
    /* USART0: Wait for empty transmit buffer */
7
    while ( !( UCSR0A & (1<<UDRE0)) );
8
    /* USART0: Put data into buffer, sends the data */
9
    UDR0 = data;
10
    LEDOnOff(2, 25);
11
12
    /* USART1: Wait for empty transmit buffer */
13
    while ( !( UCSR1A & (1<<UDRE1)) );
14
    /* USART1: Put data into buffer, sends the data */
15
    UDR1 = data;
16
    LEDOnOff(3, 25);
17
//    USART_ISR_test();
18
  }
19
  return 0;
20
}

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

von Falk B. (falk)


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

von Uwe E. (ujmforum)


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

von Uwe E. (ujmforum)


Angehängte Dateien:

Lesenswert?

Ich hab jetzt mal alles aus dem Code rausgenommen was mit 
USART-Konfiguration, -Interrupt oder sonstwie zu tun hat.
1
struct usarts {
2
  byte b0 : 1;
3
  byte b1 : 1;
4
  byte b2 : 1;
5
  byte b3 : 1;
6
  byte b4 : 1;
7
  byte b5 : 1;
8
  byte b6 : 1;
9
  byte b7 : 1;
10
} __attribute__((_packed_));
11
12
#define USART_BIT(port, bitnummer)  (((volatile struct usarts *)&port)->b##bitnummer)
13
#define CH1_RXD        USART_BIT(PORTD, 2)          // Port DDDD,  USART1, Eingang
14
#define CH1_TXD        USART_BIT(PORTD, 3)          // Port DDDD, USART1, Ausgang
15
#define CH3_RXD        USART_BIT(PORTE, 0)          // Port EEEEE, USART0, Eingang
16
#define CH3_TXD        USART_BIT(PORTE, 1)          // Port EEEEE, USART0, Ausgang
17
#define CH1_RXD_DDD2  DDD2                        // Port D2 Direction Register
18
#define CH1_TXD_DDD3  DDD3                        // Port D3 Direction Register
19
#define CH3_RXD_DDE0  DDE0                        // Port E0 Direction Register
20
#define CH3_TXD_DDE1  DDE1                        // Port E1 Direction Register
21
#define on  1
22
#define off  0
23
24
void startinit (void) {
25
  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);
26
  DDRB = (1<<EXT_DIG2_DDB0 | 0<<DDB1          | 0<<DDB2          | 1<<DDB3          | 1<<EXT_DIG1_DDB4 | 0<<DDB5          | 0<<ANANUM1_DDB6  | 0<<ANANUM2_DDB7);
27
  DDRC = (0<<DDC0          | 0<<DDC1          | 0<<DDC2          | 0<<DDC3          | 0<<DDC4          | 0<<DDC5          | 1<<LEDSTAT1_DDC6 | 1<<LEDSTAT2_DDC7);
28
  DDRD = (0<<DDD0          | 0<<DDD1          | 0<<CH1_RXD_DDD2  | 1<<CH1_TXD_DDD3  | 0<<DDD4          | 0<<DDD5          | 0<<DDD6          | 0<<DDD7);
29
  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);
30
  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);
31
  DDRG = (0<<DDG0          | 0<<DDG1          | 1<<LEDSTAT3_DDG2 | 0<<ANANUM3_DDG3  | 0<<ANANUM4_DDG4);
32
33
...
34
}
35
36
int main (void) {
37
  startinit();
38
39
  while (1) {
40
    CH1_RXD = on;
41
    CH1_TXD = on;
42
    CH3_RXD = on;
43
    CH3_TXD = on;
44
    LEDSTAT2 = off;
45
    LEDSTAT3 = on;
46
    _delay_ms(1000);
47
48
    CH1_RXD = off;
49
    CH1_TXD = off;
50
    CH3_RXD = off;
51
    CH3_TXD = off;
52
    LEDSTAT2 = on;
53
    LEDSTAT3 = off;
54
    _delay_ms(1000);
55
  }
56
  return 0;
57
}

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

von Uwe E. (ujmforum)


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

von Stefan B. (stefan) Benutzerseite


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?

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.