mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART Kommunikationsproblem


Autor: RichieRich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche zwei Mikrocontroller (Atmega32 mit 8 MHz und Atmega 169 an 
einem AVR Butterfly mit 32kHz RC oscillator) zu verbinden und nutze 
dabei ein einfaches Testprogramm.

Aber es funktioniert einfach nicht, auch wenn ich TX messe und dabei 
eine "1" sende, sehe ich keine digitale 1.

Vielleicht hatte jemand schon ein ähnliches Prolem und könnte mir da 
weiterhelfen, ich wäre sehr dankbar!



Transceiver Code:
#define FOSC 32000        // Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

#include <avr/io.h>
#include <util/delay.h>



void USART_Init(unsigned int ubrr)
{
  /* Set baud rate */
  UBRRH = (unsigned char)(ubrr >> 8);
  UBRRL = (unsigned char)ubrr;

  /* Enable receiver and transmitter */
  UCSRB = (1 << RXEN) | (1 << TXEN);

  /* Set frame format: 8data, 1stop bit */
  UCSRC = (3 << UCSZ0);
}


void USART_Transmit(unsigned char data)
{
  /* Wait for empty transmit buffer */
  while ( !( UCSRA & (1<<UDRE)) )
  ;
  /* Put data into buffer, sends the data */
  UDR = data;
}



void main(void)
{
  USART_Init(MYUBRR);

  while(1)
  {
    for(int i=0; i<10; ++i)
    {
      _delay_ms(100);
    }
      USART_Transmit("1");
  }
}




Receiver Code:
#include <avr\io.h>
#include <util/delay.h>

#define BAUDRATE 9600 
#define F_CPU 8000000


void uart_init()
{
    uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
 
    UBRRH = (uint8_t)(ubrr >> 8);
    UBRRL = (uint8_t)ubrr;
 
    // UART Receiver und Transmitter anschalten 
    // Data mode 8N1, asynchron 
    UCSRB = (1 << RXEN) | (1 << TXEN);
    UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
}


void USART_Transmit(unsigned char data)
{
  /* Wait for empty transmit buffer */
  while ( !( UCSRA & (1<<UDRE)) );

  /* Put data into buffer, sends the data */
  UDR = data;
}


unsigned char USART_Receive(void)
{
  /* Wait for data to be received */
  if( UCSRA & (1<<RXC) )
    return UDR;

  else
    return 0;
}



void main(void)
{
  uart_init();
  DDRD = (1 << PB5) | (1 << PB6);

  while(1) 
  {
    unsigned char data = USART_Receive();

    if(data)
    {
      PORTD ^= (1 << PB5) | (1 << PB6); // LED toggle
    }
  }
}


Thanks!

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define FOSC 32000        // Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

Du willst also in UBRR einen negativen Wert schreiben.
Das ist ja auch mal ein toller Trick.

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Word ist nie negativ. Teilen tut's immer.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... schrieb:
> Ein Word ist nie negativ. Teilen tut's immer.

Blödsinn. Ob ein Word negativ ist oder nicht, ist nur eine Frage wie man 
den Wert darin interpretiert. Und was meinst du eigentlich mit "Teilen 
tut's immer"?

Auf jeden Fall aber ergibt die Berechnung oben keinen UBRR Wert, der 
auch nur ansatzweise für 9600 Baud zu gebrauchen wäre. Mit einem 
Systemtakt von 32 kHz lassen sich 9600 Baud höchstens durch Zauberei 
erzeugen.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Wie kommst du eigentlich darauf, das der Butterfly mit 32kHz läuft. Das 
ist lediglich der Quartz für den RTC.

MfG Spess

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
auf jeden Fall wird das mit:

#define FOSC 32000        // Clock Speed

nichts.....

Autor: RichieRich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für den Hinweis mit dem UBRR Register!

Jetzt habe ich den internen Oszillator auf 6 MHz umgestellt mit der 
größten Einschwingzeit. Und sende alle 100ms eine "5" --> 101, aber 
irgendwie sieht das Signal trotzdem nicht wie gewünscht aus.

Könnte der USART defekt sein?

Autor: RichieRich (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
... falls jemand sich das Signal anschauen möchte, es ist im Anhang.

Autor: Andreas Vogt (tico)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RichieRich schrieb:
> Jetzt habe ich den internen Oszillator auf 6 MHz umgestellt mit der

Das glaube ich nicht.
Man kann den internen RC beim ATmega32 nämlich nur auf 1,2,4 oder 8 MHz 
einstellen.

Autor: RichieRich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ein ATMega169 an einem AVR Butterfly.

Autor: Christopher G. (cbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RichieRich schrieb:
> ...
> void USART_Transmit(unsigned char data) {
>  ...
> }
> ...
> void main(void) {
> ...
>       USART_Transmit("1");
> ...
> }
Denke zwar nicht, dass es daran liegt aber genau genommen ist 
USART_Transmit("1"); kein gültiger Aufruf für deine Funktion, 
USART_Transmit('1'); wäre hingegen korrekt.

Autor: RichieRich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ATmega169 ist der Sender und ATmega32 empfängt die Daten.

Autor: Amir B-a (sticky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht hilft dir die Checkliste weiter?
http://www.mikrocontroller.net/articles/AVR_Checkliste

Autor: Andreas Vogt (tico)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RichieRich schrieb:
> Das ist ein ATMega169 an einem AVR Butterfly.

Wenn Du das Butterfly nicht umgebaut hast, verwendet es entweder den 
externen 32,768kHz Quarz, oder den internen RC vom ATmega169, der mit 8 
MHz arbeitet und per Fuse auf 1 MHz geteilt werden kann.
Wo Du 6 MHz herhaben willst, ist mir schleierhaft.

Autor: RichieRich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Andreas Vogt: Ja es stimmt es arbeitet mit 8 MHz.

Ich habe jetz auch versucht anstatt "1", eine '1' zu senden, klappt 
trotzdem nicht. Fuse bits & Co. scheinen richtig zu sein, also keine 
Ahnung wo der Fehler sein könnte.

Übrigens ich habe gemerkt, dass im AVR Studio für AtMega169 device, 
rechts wo die Ganze Portübersicht ist USART0 bzw. UDR0 anstatt USART 
bzw. UDR verwendet wird. Einen UDR0 konnte ich auch im Datasheet nicht 
finden.
Dabei benutze ich die letzte Version von AVR Studio, ist es ein Programm 
bug?

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

Bewertung
0 lesenswert
nicht lesenswert
RichieRich schrieb:

> Ich habe jetz auch versucht anstatt "1", eine '1' zu senden, klappt
> trotzdem nicht. Fuse bits & Co. scheinen richtig zu sein, also keine
> Ahnung wo der Fehler sein könnte.

Dann fang an, systematisch an die Fehlersuche ranzugehen
Frage 1:
Wer verbockts. Der Sender oder der Empfänger?

Da man das keinem der Prozessoren ansehen kann, musst du mal einen der 
beiden durch einen anderen Computer austauschen von dem du 100% weißt, 
das er seine serielle Schnittstelle richtig bedient.

Tausche als mal den Empfänger gegen einen PC aus.

Der Sender soll "1" oder '1' an den PC senden (auf dem natürlich ein 
entsprechendes Terminal-Programm läuft). Taucht dort das Gewünschte auf? 
Wenn ja, dann wird wohl dein Sender richtig senden aber der Empfänger 
empfängt was Falsches.
Wenn nein ... jetzt sollte das Spielchen schon klar sein, wies weiter 
geht.

Autor: RichieRich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl heinz Buchegger: Leider habe ich keinen RS232 Kabel hier um es an 
dem PC auszuprobieren.

@Christopher G.: Du hattest Recht mit den Klammern. Durch einen Aufruf 
mit "1", kommt nur Mist raus. Dagegen wenn ich '1' sende, sieht es schon 
besser aus.

Aber ich habe jetzt einige Messungen durchgeführt, das Ergebnis sieht 
viel besser aus und dennoch, schein mir das Signal "unsauber" zu sein, 
ob es an der Genauigkeit des Oszis liegt ?!


Ein Problem war, dass in den Makros, die Taktfrequenz und die Baudrate 
nicht als unsigned long (UL) definiert, deshalb gab es einen Überlauf.

Im folgenden habe ich das Signal für '0', '1', '2', '3', '4' und '5' 
fotografiert. Die Baudrate liegt auf den Photos bei 9600 Bit/s --> 104,2 
us pro ein einzelnes Bit.

Aber trotzdem erkenne ich keine sauberen Start, Stopbits und Datenbits 
oder sieht es jemand anders?

Autor: RichieRich (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
USART_Transmit('0');

Autor: RichieRich (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
USART_Transmit('1');

Autor: RichieRich (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
USART_Transmit('2');

Autor: RichieRich (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
USART_Transmit('3');

Autor: RichieRich (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
USART_Transmit('4');

Autor: RichieRich (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
USART_Transmit('5');

Autor: RichieRich (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Und so soll es aussehen ...

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Bitmuster sehen vollkommen ok aus. Du misst anscheinend hinter dem 
Pegelwandler, daher ist es invertiert. Wo siehst du da einen 
entscheidenden Unterschied zu dem "so soll es aussehen"?

PS: Baudrate habe ich jetzt nicht kontrolliert, weil ich nicht sehe was 
da jetzt genau die Zeitbasis ist.

Autor: RichieRich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Zeitbasis ist 250 us.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RichieRich schrieb:
> Die Zeitbasis ist 250 us.

Also ca. 850 µs für 9 Bit = ca 10600 Baud.

Du wirst den internen Oszillator kalibrieren müssen, sonst wird das 
nichts.

Autor: RichieRich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja das mit der Kalibration habe ich mir auch gedacht, dass der interne 
Oszilllator wohl zu ungenau ist.

Vielen Dank für all die Hinweise, am Ende läufts zwar nicht wie 
gewünscht, dafür aber einiges auf dem Weg hin gelernt.

Autor: rene (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe eine Kalibration des Mega 169 Butterfly in 60 zeilen ASM.

http://www.ibrtses.com/embedded/avrosccal.html

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.