mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART Studienarbeit dringend :D


Autor: UART Studienarbeit (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Jim Meba (turboj)
Datum:

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

Autor: UART Studienarbeit (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: UART Studienarbeit (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Julian Baugatz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: UART Studienarbeit (Gast)
Datum:

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

Autor: Arduino Fanboy (ufuf)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: UART Studienarbeit (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: H.Joachim Seifert (crazyhorse)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: UART Studienarbeit (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: UART Studienarbeit (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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>.

Autor: Arduino Fanboy (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UART Studienarbeit schrieb:
> #define F_CPU 8000000UL

UART Studienarbeit schrieb:
> 7,3Mhz Quarz

Fällt dir was auf?

Autor: UART Studienarbeit (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: H.Joachim Seifert (crazyhorse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann haben wir es doch :-)

Autor: UART Studienarbeit (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: UART Studienarbeit (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wir haben es?
:D

Autor: Thomas O. (kosmos)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: UART Studienarbeit (Gast)
Datum:

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

Autor: Arduino Fanboy (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UART Studienarbeit schrieb:
> wir haben es?
> :D

Ja, wir haben alle Klarheiten beseitigt!

Autor: Julian Baugatz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: UART Studienarbeit (Gast)
Datum:

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

Autor: Arduino Fanboy (ufuf)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: UART Studienarbeit (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Arduino Fanboy (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: H.Joachim Seifert (crazyhorse)
Datum:

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

Ja.

Autor: Émile Baudot (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: UART Studienarbeit (Gast)
Datum:

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

Autor: Émile Baudot (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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%.

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Émile Baudot (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: UART Studienarbeit (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, Danke :)

Autor: UART Studienarbeit (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.