Forum: Mikrocontroller und Digitale Elektronik Problem mit UART zwischen zwei ATmega8


von Tommy (Gast)


Lesenswert?

Hallo,

folgendes Problem tritt bei mir auf:

Zwei ATmega8 sollen über UART Daten austauschen -  das kleine 
Testprogramm funktioniert, solange ich nur selten ( einmal pro Sekunde) 
Daten sende - senden ich häufig kommt  -  sobald ich kurz das Sendekabel 
aus und wieder eingesteckt habe nur noch Datenmüll an  -  beim langsamen 
Senden geht das problemlos  -  bitte gebt mir einen Tipp:

Es wird einfach eine Zahl gezählt und gesendet  -  beim Empfänger am 
PortC ausgegeben  -  Port B zeigt Paritätsfehler an....

Sender:
1
# include <stdint.h>
2
# include <avr/io.h>
3
4
uint8_t temp,temp1,temp2,temp3;
5
6
int main(void)
7
{
8
DDRB=0b11111111;
9
//PORTB=0b0000000;
10
UBRRH=(uint8_t)(4000000/(2000*16L-1))>>8;
11
UBRRL=(uint8_t) (4000000/(2000*16L-1));
12
UCSRB =(1<<TXEN);
13
UCSRC =(1<<URSEL)|(1<<USBS)|(1<<UPM1)|(1<<UPM0)|(1<<UCSZ1)|(1<<UCSZ0);
14
15
//sendet binär 0 bis 63
16
17
temp=1;
18
while(1){
19
temp=temp+1;
20
if (temp==63) temp=0;
21
while(!(UCSRA & (1<<UDRE)));
22
UDR=temp; // hier geht es prima  
23
24
//Warten .....
25
temp1=0;
26
while(temp1<254){
27
temp1++;temp2=0;// if((UCSRA & (1<<UDRE))) UDR=temp;  // hier geht es nicht mehr sinnvoll
28
      while(temp2<254){
29
    temp2++;temp3=0;
30
              while(temp3<3){
31
           temp3++;
32
       //
33
      
34
                            }
35
                    }
36
                 }
37
        }
38
}


Empänger:
1
 
2
# include <stdint.h>
3
# include <avr/io.h>
4
5
uint8_t temp;
6
7
int main(void)
8
{
9
DDRC=0b11111111;
10
DDRB=0b11111111;
11
12
13
UBRRH=(uint8_t)(4000000/(2000*16L-1))>>8;
14
UBRRL=(uint8_t) (4000000/(2000*16L-1));
15
UCSRB =(1<<RXEN);
16
UCSRC =(1<<URSEL)|(1<<USBS)|(1<<UPM1)|(1<<UPM0)|(1<<UCSZ1)|(1<<UCSZ0);
17
18
19
20
while(1){
21
while(!(UCSRA &(1<<RXC)) | (UCSRA &(1<<PE)) ){ if(UCSRA &(1<<PE)) {temp=UDR;PORTB=255;} else PORTB=0; }
22
PORTC=UDR;
23
}
24
}


DANKE!!!!

von Tommy (Gast)


Lesenswert?

es sieht so aus als würde der MC den anfang des bitpaketes nicht mehr 
finden  -  was mache ich falsch ????

von holger (Gast)


Lesenswert?

>was mache ich falsch ????

Du ziehst einfach den Stecker raus ? Lass ihn doch dran.
Oder mach eine Synchronisation mit irgendwelchen von dir
selbst gewählten Start/Stopbytes.

von Falk B. (falk)


Lesenswert?

@ Tommy (Gast)

>es sieht so aus als würde der MC den anfang des bitpaketes nicht mehr
>finden  -  was mache ich falsch ????

Hast du mal die Tutorials angeschaut?

AVR-Tutorial: UART

AVR Checkliste

MFG
Falk

von Tommy (Gast)


Lesenswert?

Letzlich soll die Strecke per Funk übertragen werden und da sollen 
Störungen vorkommen dürfen ....

von Tommy (Gast)


Lesenswert?

@ Falk  -  klar habe ich alles gelesen  -  nur es hilft ja nicht weiter 
-  es funktioniert ja prima  -  bis eine Störung kommt  -  dann wird der 
Anfang nicht mehr gefunden  -  außer man hat lange Pausen drin ...

Gruß

T.

von Tommy (Gast)


Lesenswert?

@holger

"Oder mach eine Synchronisation mit irgendwelchen von dir
selbst gewählten Start/Stopbytes."  -  es kommen ja keine definierten 
Bytes mehr rein ! -  also kann ich das ja auch nicht machen ...

von Falk B. (falk)


Lesenswert?

@ Tommy (Gast)

>-  es funktioniert ja prima  -  bis eine Störung kommt  -  dann wird der
>Anfang nicht mehr gefunden  -  außer man hat lange Pausen drin ...

Genauso ist es. Du musst dem UART schon Zeit geben sich neu zu 
synchronisieren. Dazu musst du in regelmässigen Abständen eben KEINE 
Daten senden, für mindestens die Zeit eines Zeichens (10Bit), besser 
zwei oder drei. Dann fängt sich der Empfänger wieder.

Etwa so.

while (1) {
X Zeichen senden
1..3 Zeichen Pause
}

MfG
Falk

P.S. Deine Formatierung ist grausam!

von Karl H. (kbuchegg)


Lesenswert?

Wenn Störungen vorkommen können, dann musst du immer wieder
Pausen in die Übertragung einlegen, um dem Empfänger Zeit
zu geben sich irgendwann wieder mal auf ein Startbit
synchronisieren zu können.

Schau dir das Prinzip der RS232 Übertragung an, dann wird
es klarer. Der Empfänger erkennt den Anfang eines Bytes,
das Startbit nur aus dem Grundzustand heraus. Er kann nicht
wissen, welche von vielen Absenkungen die regelmässig daher-
kommen nun ein Startbit sein soll. Also muss man ihm eine
Chance dazu geben. Den Idle Zustand über eine längere Zeit
beibehalten, damit der Empfänger die Chance hat, ein fehlerhaft
synchronisiertes Byte abzuschliessen und auf das nächste Startbit
zu warten, dass dann auch vom Sender kommt. Erst dann sind
beide wieder synchronisiert.

Im Chaos-Sende-programm da oben schau ich mir noch nicht
mal an, wie das Zeitverhalten sein könnte :-)

von Tommy (Gast)


Lesenswert?

Hi -  das hilft mir mal weiter  -  danke !

will einen billigen AM-Empfänger nutzten  -  aber das wird dann klar so 
nicht gehen --> FM


@ alle   - man lernt ja nur dadurch das anderen einem zeigen wie es 
besser geht  - daher würde mich freuen, wenn jemand die Schleifen so 
formatiert, dass es "ideal" ist

Gruß

T.

von Karl H. (kbuchegg)


Lesenswert?

Tommy wrote:
> Hi -  das hilft mir mal weiter  -  danke !
>
> will einen billigen AM-Empfänger nutzten  -  aber das wird dann klar so
> nicht gehen --> FM
>
>
> @ alle   - man lernt ja nur dadurch das anderen einem zeigen wie es
> besser geht  - daher würde mich freuen, wenn jemand die Schleifen so
> formatiert, dass es "ideal" ist

Das macht man prgmatisch:
  Bei jeder { wird in der nachfolgenden Zeile zb um 2 Zeichen
  eingerückt. Die zu diesem { gehörende  } wird dann wieder
  um 2 Zeichen ausgerückt.

Wenn die erste {, also die Funktionsklammer, am linken Rand ist,
dann muss sich mit all den Einrückungen und Ausrückungen ergeben,
dass die schliessende Funktions-} wieder am linken Rand ankommt.
Ansonsten hast du einen Fehler in der Struktur.

Vorteil: man sieht sofort, welche Teile gemeinsam in einer
Struktur (sei es Schleifen- oder Abfragestruktur sind)

Ein paar Leerzeichen an strategischen Stellen haben auch noch nie
geschadet, die Lesbarkeit aber schon oft drastisch erhöht. Man muss
dann nicht mehr lange in einer Zeile nach dem = suchen :-)

Vergleich mal deinen Kauderwelsch mit
1
int main(void)
2
{
3
4
  DDRB = 0b11111111;
5
//PORTB=0b0000000;
6
  UBRRH = (uint8_t)( 4000000 / (2000*16L-1) ) >> 8;
7
  UBRRL = (uint8_t)( 4000000 / (2000*16L-1) );
8
  UCSRB = (1<<TXEN);
9
  UCSRC = (1<<URSEL) | (1<<USBS) | (1<<UPM1) |
10
          (1<<UPM0) | (1<<UCSZ1) | (1<<UCSZ0);
11
12
//sendet binär 0 bis 63
13
14
  temp = 1;
15
  while( 1 ) {
16
17
    temp = temp+1;
18
    if( temp == 63 )
19
      temp = 0;
20
21
    while( !( UCSRA & (1<<UDRE)) )
22
      ;
23
24
    UDR = temp; // hier geht es prima  
25
26
    // Warten .....
27
28
    temp1 = 0;
29
    while( temp1 < 254 ) {
30
      temp1++;
31
32
      temp2 = 0;
33
      // if( (UCSRA & (1<<UDRE)) )
34
      //   UDR = temp;  // hier geht es nicht mehr sinnvoll
35
      while( temp2 < 254 ) {
36
        temp2++;
37
38
        temp3 = 0;
39
        while( temp3 < 3 ) {
40
          temp3++;
41
        }
42
      }
43
    }
44
  }
45
}

von Falk B. (falk)


Lesenswert?

@ Tommy (Gast)

>will einen billigen AM-Empfänger nutzten  -  aber das wird dann klar so
>nicht gehen --> FM

Unsinn, das hat damit gar nichts zu tun.

MFG
Falk

von Tommy (Gast)


Lesenswert?

Hey Danke !

von holger (Gast)


Lesenswert?

>will einen billigen AM-Empfänger nutzten  -  aber das wird dann klar so
>nicht gehen --> FM

Ach, das hast du vor.

>"Oder mach eine Synchronisation mit irgendwelchen von dir
>selbst gewählten Start/Stopbytes."  -  es kommen ja keine definierten
>Bytes mehr rein ! -  also kann ich das ja auch nicht machen ...

Wenn du bei der gestörten Kabelverbindung schon Probleme hast,
dann freu dich mal auf das was aus deinem Empfänger kommt
wenn kein Sendesignal da ist. Der rauscht eventuell wie verrückt.
Da bekommst du jede Menge undefinierter Bytes. Du wirst
nicht drumherum kommen mit einem Vorspann von ein paar
Bytes Sender und Empfänger zu synchronisieren. Noch ein Tip:
Lange Pausen zwischen den Bytes können dazu führen das der Empfänger
wieder rauscht. Und auch ein Dauerträger kann dazu führen das der
Empfänger rauscht ! Gleichspannungssignale wollen die billigen
Empfänger auch nicht haben.

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.