Forum: Mikrocontroller und Digitale Elektronik UART Studienarbeit dringend :D


von UART Studienarbeit (Gast)


Angehängte Dateien:

Lesenswert?

Guten Tag liebe Community,

das ist das erste mal dass ich hier etwas poste, ich hoffe ich mach das 
richtig. Ich sitze gerade an meiner Studienarbeit und hab ein Problem 
...
Ich sende mit einem ATmega2560 über UART an einen ATmega32A. Gesendet 
wird mit 8n2. Durch eine LED die ich aktiviere sobald der 32A in den 
Interrupt springt seh ich dass er etwas empfängt. Aber er empfängt 
einfach nicht was ich schicke.

Daten vom ATmega2560 per UART mit Terminal ausgelesen (ASCII):

r108yg109yb42yr107yg108yb41yr106yg107yb40yr105yg106yb39yr104yg105yb38yr1 
03yg


Code vom 32A der diesen Daten auswerten soll:

........................................................................ 
.
########################################################################


#include <avr/io.h>
#include <inttypes.h>
#include <avr/delay.h>
#include <avr/interrupt.h>



#define F_CPU 8000000UL
#define BAUD        115200UL
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)
#define intervall10 "set intervall 10"
#define streamon "set stream 1"
#define streamoff "set stream 0"




void timer2_init()      //PWM Rot
{
  TCCR2 |= (1 << COM21)|(1 << WGM20)|(1 << CS22);
  OCR2 = 230;
}

void timer1_init()             //PWM Grün, Blau
{
  TCCR1A |= (1 << COM1A1)|(1 << COM1B1) |(1<<WGM10);
  TCCR1B |= (1 << CS11)|(1 << CS10);
  TCNT1 = 0;
  OCR1A = 230;
  OCR1B = 230;

}




// USART initialisieren
void uart_init(void){

  UBRRH = (unsigned char)(UBRR_BAUD >> 8);
  UBRRL = UBRR_BAUD;

  UCSRA = (1 << UDRE);                    //Puffer-leer bit setzen

  UCSRB |= (1<<RXEN)|(1<<RXCIE);                      //Senden 
aktivieren
  UCSRC |= (1<<UCSZ1)|(1<<UCSZ0)|(1<<USBS);          //Anzahl Datenbits 
und Stopbits wählen
  do
  {
    UDR;
  }
  while (UCSRA & (1 << RXC));
}


#define UART_MAXSTRLEN 100
char uart_string[UART_MAXSTRLEN + 1] = "";
volatile uint8_t uart_str_complete = 0;
volatile uint8_t uart_str_count = 0;

int Gruen;              //Farbwert gelb 0-255
int Blau;              //Farbwert blau 0-255
int Rot;               //Farbwert rot 0-255
int testcounter = 0;

int main(void)
{


  // USART + timer initialisieren
  uart_init();
  timer1_init();
  timer2_init();
  DDRA |= 0xFFF;
  DDRD |= (1<<PD6);
  DDRD |= (1<<PD4);  //OC1B
  DDRD |= (1<<PD5);  //OC1A
  DDRD |= (1<<PD7);  //OC2

  sei();

  do{

    if(uart_str_complete == 1){
      if(uart_string[0] == 'r'){

        memmove(uart_string, uart_string+1, strlen(uart_string));
        Rot = atoi(uart_string);
        OCR2 = Rot;
        if(Rot > 50){
          PORTA |= (1<<PA4);
        }
        else{
          PORTA &= ~(1<<PA4);
        }
      }

      if(uart_string[0] == 'g'){
        memmove(uart_string, uart_string+1, strlen(uart_string));
        Gruen = atoi(uart_string);
        OCR1A = Gruen;
        if(Gruen > 50){
          PORTA |= (1<<PA5);
        }
        else{
          PORTA &= ~(1<<PA5);
        }
      }

      if(uart_string[0] == 'b'){
        memmove(uart_string, uart_string+1, strlen(uart_string));
        Blau = atoi(uart_string);
        OCR1B = Blau;
        if(Blau > 50){
          PORTA |= (1<<PA6);
        }
        else{
          PORTA &= ~(1<<PA6);
        }
      }

      if(uart_string[0] == 'c'){

        if(uart_string[1] == '1'){
          PORTA |= (1<<PA7);
        }
        else{
          PORTA &= ~ (1<<PA7);
        }
      }

      if(uart_string[0] == 'O'){
        if(uart_string[1] == '1'){
          PORTA |= (1<<PA2);
          PORTA |= (1<<PA3);
        }
        else{
          PORTA &= ~ (1<<PA2);
          PORTA &= ~ (1<<PA3);
        }
      }
      uart_str_complete = 0;
    }


  } while (1);


}


ISR(USART_RXC_vect) // Interrupt
{
  unsigned char nextChar;
  nextChar = UDR;
  if( uart_str_complete == 0 )
  {
    if((nextChar != 'y'))
    {
      uart_string[uart_str_count] = nextChar;
      uart_str_count++;
      uart_string[uart_str_count] = '\0';
    }
    else
    {
      uart_string[uart_str_count] = '\0';
      uart_str_count = 0;
      uart_str_complete = 1;
    }
  }
}




.......................................................................
#####################################################################

Leider klappt das mit der formatierung nicht so ganz hier im kleinen 
Fenster, viel verschoben ist ja nicht.
Mein Problem ist.... ich sehe im Terminal dass ich die Daten richtig 
schicke. Aber mein Interrupt erkennt das 'y' einfach nicht. Ich saß nun 
schon 12 Stunden an diesem Probelm und finde einfach den Fehler nicht.
Ich hoffe hier im Forum kann mir jemand helfen.
Vielen Dank im voraus!!!!

MfG Martin

von Jim M. (turboj)


Lesenswert?

Quarz dran? An die AVR Fuses gedacht, da ist ein Teiler durch 8 
drin?

von UART Studienarbeit (Gast)


Lesenswert?

Wow danke für die schnelle Antwort. Ja die Fuse is auf 8Mhz eingestellt.
beeinflusst der teiler vom timer auch den Takt den der Uart benutzt?

von UART Studienarbeit (Gast)


Lesenswert?

Oszi habe ich mir sogar extra eins ausgeliehen und hier. Aber ich muss 
zugeben ich habe keine Ahnung wie man so etwas erkennt.

Noch zur Info ... der ATmega32A läuft auf einem STK500 momentan

von Julian Baugatz (Gast)


Lesenswert?

Sprich den Mega32 doch auch mal über ein Terminal an und schick ihm 
deine Zeichenketten. Zur Fehlersuche kann er dann ein Echo zurück 
schicken und noch ein Hinweis, in welcher Schleife er gerade ist.

von UART Studienarbeit (Gast)


Lesenswert?

Gute Idee daran hatte ich noch nicht gedacht, werde ich versuchen.Danke

von Einer K. (Gast)


Lesenswert?

UART Studienarbeit schrieb:
> Oszi habe ich mir sogar extra eins ausgeliehen und hier. Aber ich muss
> zugeben ich habe keine Ahnung wie man so etwas erkennt.

Viele "UUUUUU" senden.
Und Timing messen.

Moderne haben eingebaute Werkzeuge, bei älteren kann auch ein Lineal und 
Taschenrechner helfen.

von Thomas E. (thomase)


Lesenswert?

UART Studienarbeit schrieb:
> Oszi habe ich mir sogar extra eins ausgeliehen und hier. Aber ich muss
> zugeben ich habe keine Ahnung wie man so etwas erkennt.

Um die Baudrate mit dem Oszi zu "messen", sendest du fortlaufend 0x55 
oder 0xAA mit einem Stopbit. Damit erhältst du eine Rechteckspannung an 
Tx von 57,6KHz bzw. 28,8KHz.

von UART Studienarbeit (Gast)


Lesenswert?

Wenn ich es durch ein echo nicht herausfinde werde ich das mit dem oszi 
probieren. Vielen Dank für die ganzen Antworten. Ich bin völlig baff wie 
schnell man hier Hilfe bekommt!

von H.Joachim S. (crazyhorse)


Lesenswert?

8MHz und 115200Baud ist nicht möglich für nen AVR.
Und deshalb glaub ich dir auch nicht, dass du das mit nem Terminal 
korrekt empfangen konntest. Selbst im double-speed-mode sind das fast 4% 
Fehler.
Wenn du allerdings auf beiden Seiten mit demselben Fehler arbeitest, 
funktioniert es schon, aber dann eben nicht mit Standardbaudraten 
(Terminal).

von UART Studienarbeit (Gast)


Lesenswert?

der ATmega2560 sitzt mit einem externen 7,3Mhz Quarz auf einer kleinen 
Platine. die Platine hab ich von einem Prof bekommen um damit zu 
arbeiten. Ich habe ebenfalls ein Programm von ihm bekommen und habe 
seine UART-init übernommen.

von UART Studienarbeit (Gast)


Lesenswert?

Mhm ich muss zugeben das war nie mein Lieblingsfach... daher bin ich bei 
dem ganzen Thema noch nicht so bewandert, ich versuche mein Bestes.

Thema Echo:

ISR(USART_RXC_vect) // Interrupt
{
  unsigned char nextChar;
  nextChar = UDR;
  if( uart_str_complete == 0 )
  {

    if((nextChar != 'y'))
    {
      uart_string[uart_str_count] = nextChar;
      uart_str_count++;
      uart_string[uart_str_count] = '\0';

      while (!(UCSRA & (1<<UDRE)));
      UDR = nextChar;
    }
    else
    {
      uart_string[uart_str_count] = '\0';
      uart_str_count = 0;
      uart_str_complete = 1;
    }
  }
}



Ich weiss nicht ob ich das so einfach machen darf... also ein echo 
direkt im interrupt für jedes einzelne char.
Sobald ich dem mega32 einen Befehl sende bekommen ich dieses Zeichen 
zurück das Null-Zeichen zurück <\0>.

von Einer K. (Gast)


Lesenswert?

UART Studienarbeit schrieb:
> #define F_CPU 8000000UL

UART Studienarbeit schrieb:
> 7,3Mhz Quarz

Fällt dir was auf?

von UART Studienarbeit (Gast)


Lesenswert?

der code den ich geschickt habe is vom mega32 ... der läuft mit dem 
internen 8Mhz. der 2560 läuft mit dem 7,3Mhz Quarz

von H.Joachim S. (crazyhorse)


Lesenswert?

Dann haben wir es doch :-)

von UART Studienarbeit (Gast)


Lesenswert?

Entschuldigt meine Rechtschreibung, ich versuche immer so schnell es 
geht zu Antworten bevor jemand von Ihnen schlafen geht. Da hacke ich 
einfach auf meine Tastatur ein.

von UART Studienarbeit (Gast)


Lesenswert?

wir haben es?
:D

von Thomas (kosmos)


Lesenswert?

Du könntest es auch ohne Hardware UART lösen was etwas mehr 
Programmieraufwand bedeuten würde, aber letztendlich viel 
unproblematischer im Taktverhalten ist. Nicht das du später irgend einen 
Vorführeffekt hast.

Das Byte einfach bitweise mit einem Taktsignal über einen 2ten Pin 
rausschieben. Das Taktsignal löst beim Empänger einen Interrupt aus und 
er schiebt das Bit in ein Byte rein.

Durch die Taktleitung hat man keinerlei Probleme wenn die Takte der µC 
nicht synchron sind und einander weglaufen, da jedes Bit neu 
synchronisiert wird.

von UART Studienarbeit (Gast)


Lesenswert?

also ich kann den mega32 nicht mit dem internen 8Mhz und 115200baud 
laufen lassen?

von Einer K. (Gast)


Lesenswert?

UART Studienarbeit schrieb:
> wir haben es?
> :D

Ja, wir haben alle Klarheiten beseitigt!

von Julian Baugatz (Gast)


Lesenswert?

UART Studienarbeit schrieb:
> Ich weiss nicht ob ich das so einfach machen darf... also ein echo
> direkt im interrupt für jedes einzelne char.

sollte funktionieren, die while() davor brauchst du eigentlich nicht

vielleicht setzt du zum Testen die Baudrate herunter, wenns funzt, 
kannst du sie ja wieder hochsetzen

von UART Studienarbeit (Gast)


Lesenswert?

Ah ok, an eine Software-UART hatte ich noch nicht gedacht. Ich hatte 
nicht so grosse Probleme erwartet

von Einer K. (Gast)


Lesenswert?

UART Studienarbeit schrieb:
> also ich kann den mega32 nicht mit dem internen 8Mhz und
> 115200baud
> laufen lassen?


Und nochmal:
Schaue dir das Timing an.
Von beiden!
Vergleiche!
Und dann findest du deine eigene Antwort.

Oder Rechne es aus. Das bringt das gleiche Ergebnis, wenn du es richtig 
machst.
Teiler, Fuses, ist ja alles offen.

von UART Studienarbeit (Gast)


Lesenswert?

Ok ich werde es versuchen.
Nur noch eins was mit gerade klar wird. der jetztige mega32 ist nur ein 
testµC. Ich bekomme in einer woche meine Finale Platine. Und dann wird 
der mega32 ebenfalls mit einem externen 7,3Mhz Quarz betrieben.
Wenn das nun wirklich am Timing liegt sollte sich das doch eigentlich 
erledigen wenn ich den mega32 mit dem selben Quarz laufen lasse wie der 
2560.
oder?

von Einer K. (Gast)


Lesenswert?


von H.Joachim S. (crazyhorse)


Lesenswert?

UART Studienarbeit schrieb:
> sollte sich das doch eigentlich
> erledigen wenn ich den mega32 mit dem selben Quarz laufen lasse wie der
> 2560.

Ja.

von Émile Baudot (Gast)


Lesenswert?

UART Studienarbeit schrieb:
> Wenn das nun wirklich am Timing liegt sollte sich das doch eigentlich
> erledigen wenn ich den mega32 mit dem selben Quarz laufen lasse wie der
> 2560.
> oder?

Ja

von UART Studienarbeit (Gast)


Lesenswert?

Super dann hat sich der Thread erledigt, danke Emile.Und vielen Dank an 
alle hier :) bin echt begeistert von dem forum!!!

von Émile Baudot (Gast)


Lesenswert?

... bevor du eine Woche wartest, kannst du natürlich auch mit einer 
geringeren Baudrate arbeiten, z.B. 38400, da beträgt der Baudratenfehler 
nur 0,2% bei 8MHz, beim 7.3728MHz-Quarz ist der Fehler 0%.

von Ich (Gast)


Lesenswert?

UART Studienarbeit schrieb:
> bin echt begeistert von dem forum!!!

Wenn da nicht immer die Freitags Trolle wären :-) Ah Ah Ah 00:16h es ist 
schon wieder Freitag ....
Gute Nacht :-)

von Émile Baudot (Gast)


Lesenswert?

Émile Baudot schrieb:
> ... bevor du eine Woche wartest, kannst du natürlich auch mit
> einer
> geringeren Baudrate arbeiten, z.B. 38400, da beträgt der Baudratenfehler
> nur 0,2% bei 8MHz, beim 7.3728MHz-Quarz ist der Fehler 0%.

Nee, sorry, vergiss es, du nimmst ja den internen RC-Oszillator, hab ich 
gerade erst gesehen. Der ist wahrscheinlich zu ungenau. Das mit der 
niedrigeren BR wird auch nur dann funktionieren, wenn du an den mega32 
einen ext. Quarz dranklemmst. Vllt nochmal in ein paar Schubladen 
wühlen...

von UART Studienarbeit (Gast)


Lesenswert?

Ok, Danke :)

von UART Studienarbeit (Gast)


Lesenswert?

Guten Abend zusammen,

und vielen Dank an alle die mir hier geholfen haben. Ich wollte den 
Thread natürlich noch auflösen und aufklären wo mein Fehler lag. Die 
Platine die ich von der Hochschule gestellt bekommen habe, auf der sich 
der mega2560 befindet, hat einen RS485 Baustein mit dem die UART nach 
aussen geführt wird. Das STK500 auf dem der mega32A installiert war 
kommuniziert jedoch mittels RS232. Daher konnte eine Kommunikation 
garnicht zustande kommen.

Trotzdem nochmals vielen Dank an alle die sich hier die Mühe gemacht 
haben und versuchten mit zu helfen!!!!!

Mit freundlichen Grüssen Martin

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.