Forum: Mikrocontroller und Digitale Elektronik UART an ATMEGA328P-MMU


von Peter (Gast)


Lesenswert?

Hallo Zusammen,

ich möchte gerne zwei ATmega328 miteinandern kommunizieren lassen. Einer 
ist ein ATMEGA328P im DIP Gehäuse, der andere ist ein ATMEGA328P-MMU (28 
Pin SMD).

Aufgabe ist nun, dass der eine ATMEGA ein Teststring sendet und der 
andere soll diesen einfach per Echo zurück senden. Das Problem ist, dass 
der ATMEGA328P im SMD Gehäuse nur einmal das Echo zurück sendet und dann 
immer einen leeren string. Der ATMEGA328P im DIP Gehäuse macht das aber 
richtig. Also würde der im SMD Gehäuse die variable zum weiter Zählen 
nicht richtig einsetzen. Anbei mein Programm mit welchem ich teste.
1
 #define F_CPU 8000000ul
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <string.h>
6
7
void uart_putc(unsigned char c)
8
{
9
  while(!(UCSR0A & (1<<UDRE0)))
10
  {
11
    ;
12
  }
13
  UDR0 = c;
14
}
15
16
void USARTsend(char *s)
17
{
18
  while(*s)
19
  {
20
    uart_putc(*s);
21
    s++;
22
  }
23
}
24
25
int main(void)
26
{
27
  DDRD |= (1<<DDD2);
28
  UBRR0L = 51;
29
  UCSR0B = (1<<RXEN0) | (1<<TXEN0);
30
  UCSR0C = (3<<UCSZ00);
31
32
  volatile uint8_t zahler = 0;
33
  int strComplete1 = 0;
34
  char uartString1[20] = "";
35
36
    /* Replace with your application code */
37
    while (1) 
38
    {
39
  
40
    char nextChar = ' ';
41
    while (!(UCSR0A & (1<<RXC0)))
42
    ;
43
    nextChar = UDR0;
44
    
45
46
    if (nextChar != '\n')
47
    {
48
      uartString1[zahler] = nextChar;
49
      zahler++;
50
      
51
    }
52
    else
53
    {
54
      uartString1[zahler] = '\0';
55
      zahler = 0;
56
      USARTsend(uartString1);
57
      uart_putc('\n');
58
      memset(uartString1,0,20);
59
    }
60
    }
61
}

von Peter (Gast)


Lesenswert?

Keiner eine Idee oder Hinweise?

von Einer K. (Gast)


Lesenswert?

Peter schrieb:
> Keiner eine Idee oder Hinweise?

Klar!
Wenn sich zwei ATMega328P unterschiedlich verhalten, dann:
1. unterschiedlicher Schaltplan/Aufbau
2. unterschiedliches Programm drauf
3. einer/beide ist/sind defekt.

Deine uart Routinen habe ich nicht geprüft.
Bin da eher so ein Arduino Serial OOP Jünger.
Ich mag die möglichst asynchrone Verarbeitung mit FiFo und Interrupts. 
Ein bisschen Komfort darf schon sein.

von Peter (Gast)


Lesenswert?

Guten Morgen, denke nicht dass es am Schaltpkan liegt da das senden 
immer klappt, nur das Empfangen läuft nur einmal ab. DEr Code ist 
bereits soweit teduziert dass er nur noch auf Zeichen wartet um den 
Fehler einzugrenzen. Es scheint so als würde die Zähl Variable vom 
String nach einem Durchlauf und zurücksetzen auf null nicht mehr 
gezählt. Ich erhalte nur noch einen leeren String.

von Daniel F. (df311)


Lesenswert?

wie lang sind die test-strings?

der hinweis dazu: schau dir deinen code mal genau an und überlege was 
passiert, wenn du einen string der länge 20 schickt bevor \n kommt

von Peter (Gast)


Lesenswert?

Hallo,

der Teststring ist maximal 4 Zeichen lang +  \n. Ein Überlauf ist somit 
ausgeschlossen.

Wenn ich die Routine so abändere, dass nicht das Empfangen Zeichen in 
den String geschrieben wird sondern ein Platzhalter ("Buchstabe T") So 
passt die Anzahl der Platzhalter im String. Somit wird das alles auch 
richtig Durchlaufen. Nur wenn ich dann wieder das Empfange Zeichen 
Einsetzen möchte funktioniert das nur nach einem Neustart.

von S. Landolt (Gast)


Lesenswert?

Das habe ich nicht verstanden: das gezeigte Programm ist ja wohl das für 
den "Echo"-Controller - und womit läuft der "Sende"-Controller?

von Peter (Gast)


Lesenswert?

Gesendet wird einfach vom PC-Terminal.

von S. Landolt (Gast)


Lesenswert?

Okay, dann fällt mir erstmal wenig ein. Wie sehen die Fusebytes aus beim 
DIP- und wie beim SMD-Controller?
  Aber eigentlich tendiere ich eher zu Punkt 2 vom Arduino Fanboy, woher 
sonst sollte ein leerer String kommen?

von Peter (Gast)


Lesenswert?

Also du fuses sing gleich. 2,7V Brown out, intern 8 Mhz.

Programme sind absolut identisch da ich nur einmal kompiliere und auf 
beider aufspiele.

von S. Landolt (Gast)


Lesenswert?

Wäre ich in dieser Lage, würde ich ein ganz simples Echo-Programm für 
diesen zweifelhaften SMD-Controller schreiben: bei Buchstaben wird 
groß/klein umgeschaltet, alle anderen werden unverändert zurückgegeben. 
Darauf aufbauend in Richtung des jetzigen Programms erweitern, in der 
Hoffnung, dass ich irgendwann den Fehler festnageln kann.

von Peter (Gast)


Lesenswert?

Es ist ja schon nur ein ECHO Programm. Wie gesagt auf dem Bruder mit DIP 
Gehäuse geht alles super-

von S. Landolt (Gast)


Lesenswert?

Was soll ich jetzt dazu sagen. Vielleicht, einen zweiten im DIP-Gehäuse 
zu kaufen?

von Peter (Gast)


Lesenswert?

Auch das ist bereits geschehen bzw. lag bereits im Schrank. die beide 
Kommunizieren lustig vor sich her. Langsam denke ich eine schlechte 
Charge erwischt zu haben.

von S. Landolt (Gast)


Lesenswert?

> ... schlechte Charge ...

Kann sein.
Aber meine persönliche Erfahrung und auch die hier im Forum zeigen, dass 
dies mit hoher Wahrscheinlichkeit nicht der Fall ist.
  Tun Sie mir den Gefallen und schreiben&testen Sie kurz das 
beschriebene Einfachst-Echo, das dauert doch keine fünf Minuten. Und 
wenn Sie schon dabei sind, liefern Sie doch bitte noch die Fuse-Bytes, 
komplett, nicht nur zwei Bits daraus.

von wendelsberg (Gast)


Lesenswert?

Mein erster Ansatz waere, den im Sekundentakt 0x30++ senden zu lassen.

Dann sollte auf dem PC 01234567... sichtbar werden.

wendelsberg

von Peter (Gast)


Lesenswert?

Hallo das senden im Sekunden Takt funktioniert ohne Probleme. Das 
Problem ist tatsächlich das Echo. Das funktioniert nur das erste mal und 
nach jedem Neustart jedoch bei Wiederholungen kommt nur ein leeren 
String.

Fuse:

Extended 0xFD
High 0xD6
Low 0xEL

von m.n. (Gast)


Lesenswert?

Peter schrieb:
> Low 0xEL

Da ist doch schon der Fehler!
;-)

von EdiR (Gast)


Lesenswert?

Ich könnte mir vorstellen, dass gleich nach dem '\n' noch ein Zeichen 
kommt, vielleicht ein '\0'. Dann wird das Echo einmal zurückgeschickt, 
aber danach besteht der String aus einem einzelnen '\0' am Anfang.

Versuch mal sowas:
1
  ...
2
  nextChar = UDR0;
3
    
4
  if (nextChar != '\0')
5
  {
6
    if (nextChar != '\n')
7
    {
8
      uartString1[zahler] = nextChar;
9
      zahler++;
10
    }
11
    else
12
    {
13
      uartString1[zahler] = '\0';
14
      zahler = 0;
15
      USARTsend(uartString1);
16
      uart_putc('\n');
17
      memset(uartString1,0,20);
18
    }
19
  }
20
  ...

von Conny G. (conny_g)


Lesenswert?

Mach mal ein Foto von jedem Setup.

Sind sie beide mit derselben Spannung betrieben?

von Adam P. (adamap)


Lesenswert?

EdiR schrieb:
> Dann wird das Echo einmal zurückgeschickt,
> aber danach besteht der String aus einem einzelnen '\0' am Anfang.

Dies sollte aber nach einem weiteren empfangenen "\n" und der Ausgabe 
eines "Null-Strings" selbst beheben.

Ablauf:
1. es wurde empfangen "Test\n" -> "Test\n" wird zurückgesendet.
2. Vllt. wurde nach 1. Empfang eine \0 empfangen
3. Es wird "ABC\n" eingegeben, dann steht im Buffer "\0ABC\n"
4. Dies wird versucht zurückzusenden, kommt nichts da Sendefkt. beim \0 
direkt beendet... aber dann ist ja nun der Zähler wieder auf 0 und alles 
beginnt von vorne.

Ich kann es mir auf die schnelle auch nicht erklären, wieso dies nur 1x 
funktionieren sollte.

Besteht nicht die Möglichkeit per One-Wire mal ein Breakpoint zu setzen 
und Step-by-Step durchzuklicken und nachzuschauen, warum dies so 
passiert? Betrachtung des Buffers etc.

: Bearbeitet durch User
von EdiR (Gast)


Lesenswert?

Adam P. schrieb:
> Ich kann es mir auf die schnelle auch nicht erklären, wieso dies nur 1x
> funktionieren sollte.

Dann helfen keine theoretischen Überlegungen. Ausprobieren! Was sagt z. 
B. der Logikanalysator?

von Stefan F. (Gast)


Lesenswert?

Kann es sein, dass du den R/C Oszillator als Taktquelle verwendest?

von Adam P. (adamap)


Lesenswert?

EdiR schrieb:
> Dann helfen keine theoretischen Überlegungen. Ausprobieren! Was sagt z.
> B. der Logikanalysator?

Wäre wohl das einzig wahre, vorausgesetzt der TE ist im Besitz eines LA.

von Peter (Gast)


Lesenswert?

Habe mit internem 8Mhz probiert und externen beides ohne Erfolg. Ich 
wüsste auch Nicht was der SMDer anders macht als der im DIP Gehöuse.

von Conny G. (conny_g)


Lesenswert?

Conny G. schrieb:
> Mach mal ein Foto von jedem Setup.
>
> Sind sie beide mit derselben Spannung betrieben?

Push!

von EdiR (Gast)


Lesenswert?

Peter schrieb:
> Ich
> wüsste auch Nicht was der SMDer anders macht als der im DIP Gehöuse.

Du machst den größten Fehler, den man bei der Fehlersuche machen kann: 
Du triffst Annahmen.

Rechne mit allem, auch mit dem Unmöglichen.

von Stefan F. (Gast)


Lesenswert?

> Ich wüsste auch Nicht was der SMDer anders macht als der im DIP Gehäuse.

Ich auch nicht. Hast du eventuell ein Funkmodul in unmittelbarer Nähe 
platziert?
Ist die Stromversorgung ganz sicher stabil? Vor allem bei einfachen 
Steck-Verbindungen ist das oft nicht der Fall.

von Peter (Gast)


Lesenswert?

Funk ist außer Handy nichts in der Nähe und als Spannungsversorgung 
dienen 5V vom PC USB. Den Aufbau treffe ich bei beiden MCUs. Ich prüfe 
nocheinmal den Anschluss des SMD auf der Platine. Eventuell fehlt da 
irgendein Kondensator.

von S. Landolt (Gast)


Lesenswert?

Auf dem SMD-Board ist doch ein ISP-Anschluss, oder?

von Peter (Gast)


Lesenswert?

Ja da ist einer drauf

von Conny G. (conny_g)


Lesenswert?

Wir wollen den Schaltplan und Fotos der zwei Varianten sehen.

Zum Beispiel: bei DIP ist 5V mehr üblich, bei SMD 3.3V.
Was, wenn wegen dieser Spannungsdifferenz irgendwas mit der seriellen 
Kommunikation ist?

Dann: eines ist Breadboard, eines ist fertige Platine - das sind ganz 
andere Konfigurationen. Was auch immer deshalb dann an Nebeneffekten 
geschieht.

Was ist mit Takt / Quartz - derselbe? Einer intern, einer extern? Die 
Baudrate könnte einfach beim SMD schnell auseinanderlaufen.

Und so weiter.

: Bearbeitet durch User
von Peter (Gast)


Lesenswert?

Fotos kann ich morgen versuchen zu machen. Der DIP Atmega läuft intern 
auf 8MHz oder 16 extern, der SMD mit 8 intern oder 8 extern. Beide mit 
9600 Baud. Wahlweise 5V oder 3,3V. Das macht jedoch keinen Unterschied.

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.