mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Probleme mit USART Recive


Autor: Thomas Prescher (gonzo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo...ich hab ein Problem beim empfangen von daten über USART bei
einem ATmega48. Der Controller läuft auf 4Mhz und Senden geht auch
prima. nur empfängt er nix. Hier meine initialisierung
/*Baudrate setzen */
  UBRR0H = (unsigned char)(ubrr>>8);
  UBRR0L = (unsigned char)(ubrr);

  /* Sender und Empfaenger anschalten */
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
  /* Frame format: 8data, 2stop bits */
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);

Und hier der Code zum empfangen:
unsigned char USART_Receive( void )
{
  while ( !(UCSR0A & (1<<RXC0)) );
  return UDR0;
}

Nur wenn ich dann die hier mache funktioniert es nicht;
  DDRB = 0xff;
  USART_Init(MYUBRR); /* UART initialisieren */
  while(1)
  {
      if (USART_Receive() == '1')
    {
      PORTB ^= (0<<PB0);
    }
    if (USART_Receive() == '0')
    {
    PORTB ^= (1<<PB0);
    }
  }

egal ob ich 1 oder 0 zu ttyS1 schicke es passiert nix. Das senden vom
µC zum PC geht jedoch.

Hat Jemand eine Idee woran das liegen könnte?

Thomas

Autor: Thomas Prescher (gonzo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach mist. hier heißt das ja [ C ] und nicht [code] verdammt. aber ich
kann den beitrag nicht mehr bearbeiten. SORRY

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> egal ob ich 1 oder 0 zu ttyS1 schicke es passiert nix

Nicht 'egal ob ich'

So wie das geschrieben ist, erwartet der AtMega48
genau die Sequenz '1' '0' '1' '0'
Genau in dieser Reihenfolge.

Das hier
>      PORTB ^= (0<<PB0);

macht gar nichts. 0 nach links geschoben (egal um
wieviele Positionen) ist immer noch 0. Und ein
Wert ge-xor-t mit 0, ändert nichts am Wert.

Autor: Thomas Prescher (gonzo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie kommst du auf 1010? Wenn ich das sende kommt auch nix,

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> wie kommst du auf 1010?

Weil ich dein Programm analysiert habe !

>  while(1)
>  {
>      if (USART_Receive() == '1')
>    {
>      PORTB ^= (0<<PB0);
>    }
>    if (USART_Receive() == '0')
>    {
>    PORTB ^= (1<<PB0);
>    }
>  }

Angenommen du schickst die Sequenz 0101
USART_Receive wartet jedesmal bis tatsaechlich ein Zeichen
empfangen wird.

  while( 1 )

soweit so gut.
    if( USART_Receive() == '1' )

der USART_Receive empfängt das Zeichen (hier solltest
du unbedingt mal das empfangene Zeichen zu Kontrollzwecken
einfach mal wieder ausgeben. Sowas hilft ungemein bei der
Fehlersuche!). Wie auch immer: '0' ist nicht '1', also
passiert nichts.
Das Programm läuft weiter und kommt in den nächsten if:

    if( USART_Receive() == '0' )
USART_Receive() wartet wieder auf das nächste Zeichen, das ist ein
'1'. '1' ist aber nicht gleich '0', also passiert wieder nichts.
Die while Schleife fängt von vorne an:

    if( USART_Receive() == '1' )
USART_Receive() wartet auf das nächste Zeichen, das ist laut unserer
Eingabe Vereinbarung ein '0'. '0' ist nicht gleich '1', also
passiert nichts.
Weiter gehts:

    if( USART_Receive() == '0' )
Als nächstes kommt wieder ein '1'. -> Nichts passiert
und die while Schleife beginnt wieder von vorne.
Mit der Eingabesequenz: 0101 wird also kein einzige der if-
Bedingungen als true angesehen, weil jedesmal das falsche Zeichen
zum falschen Zeitpunkt daherkommt.

Machs so:

   unsigned char Received;

   while( 1 ) {
     Received = USART_Receive();

     USART_Send( Received );   // ganz wichgtig zur Kontrolle
                               // ob Dein Programm auch wirklich
                               // das empfängt was du glaubst

     if( Received == '0' )
       PORTB &= ~( 1 << PB0 );

     else if( Received == '1' )
       PORTB |= ( 1 << PB0 );
   }

1) USART_Received wird nur noch 1 mal pro Schleifen-Durchlauf
   aufgerufen. Das empfangene Zeichen steht danach allen
   if-Abfragen zur Verfügung

2) Und das ist schon fast die wichtigere Änderung:
   Geh niemals davon aus, dass schon alles stimmen wird.
   Insbesondere: Geh niemals davon aus, dass Input in ein
   Programm auch tatsächlich so ausschaut wie du annimmst.
   Überprüfe es! In dem Fall heist überprüfen, dass man das
   empfangene Zeichen zur Kontrolle auch wieder ausgibt!
   Ganz zum Schluss, wenn alles fertig ist, entfernt man diese
   Kontrollausgaben wieder. Aber solange ein Programmteil in
   der Entwicklung ist, kannst du niemals genug Kontrollen
   im Programm haben.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenns dann immer noch nicht geht, dann liegt dein
Problem ganz woanders.
Ich tippe mal auf: Am PC ist Hardware Handshake (RTS/CTS)
aktiviert und der PC hat keine Freigabe zum Senden.

Autor: Thomas Prescher (gonzo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Cool. So funktioniert es super.

Vielen vielen Dank.

Thomas

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.