UART Studienarbeit dringend :D

Gast #4721152
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
Angehängte Dateien:
Gast #4721178
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
Gast #4721179
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.
#4721206
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).
Gast #4721212
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.
Gast #4721217
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>.
#4721225
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.
Gast #4721232
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.
Gast #4721234
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?
Gast #4721265
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%.
Gast #4721286
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...
Gast #4733263
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren