Forum: Mikrocontroller und Digitale Elektronik USART Problem mit ATmega328p auf Duemilanove


von Ralf K. (elgitanito)


Angehängte Dateien:

Lesenswert?

Hallo Forum,

Probleme bei der USART-Programmierung mit Atmel-Prozessoren wurden hier 
im Forum schon des Öfteren behandelt und ich habe wahrscheinlich schon 
jeden Beitrag gelesen, der damit zu tun hat. Leider konnte ich aber noch 
keine Lösung für mein Problem finden und wende mich deshalb an Euch.

Das Problem: Mit den unten angehängten C-Routinen sollen Zeichen 
empfangen und sofort zurück gesendet werden. Eigentlich hatte ich 
bereits ein komplexeres Programm geschrieben, mich dann aber, nach den 
Ideen, die ich hier zum Thema fand, zwecks Fehlersuche auf die Basics 
konzentriert.

Und: Im Prinzip funktioniert das soweit. Die zwei Bildanhänge zeigen 
Oszilloskop Scans der Sende (blau) und Empfangsleitung (rot).

Sende ich vom PC aus ein 'U', wird das korrekte Bitmuster übertragen, 
empfangen und zurück gesendet. Siehe Datei U_scan.gif. Eigentlich Grund 
zur Freude, da eigentlich alles stimmt. Auch die 9600 Baud lassen sich 
herausmessen.

Sende ich jedoch ein 'i', wird zwar korrekt gesendet, was jedoch 
zurückgesendet wird, stimmt nicht mehr. Das dritte Bit steht falsch. 
Siehe Datei i_scan.gif.

Anmerkung: Zur besseren Erkennung, ist das rote Signal anders aufgelöst, 
als das blaue. Die Spannungswerte stimmen aber.

Was könnte dafür die Erklärung sein? Hat es irgendwas mit der Taktung zu 
tun, also einem Hardware- oder Initialisierungsproblem, oder übersehe 
ich in der Software den alles entscheidenen Fehler?

Es wäre prima, wenn einer der Profis einmal einen Blick auf die Daten 
werfen könnte. Für jede Hilfe wäre ich sehr dankbar!!!

Viele Grüße,

Ralf


#define FOSC 1843200UL
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

#include <avr/io.h>


void USART_Init(unsigned int ubrr)
{
  // Operation mode: Asynchron, single speed, 8 data, 1 stop bit,
  UBRR0H = (unsigned char)(ubrr>>8);
  UBRR0L = (unsigned char)ubrr;
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
  UCSR0C = (3<<UCSZ00);
}


void USART_Send(unsigned char data)
{
  while(!(UCSR0A & (1 << UDRE0)));
  UDR0 = data;
}


unsigned char USART_Receive()
{
  while(!(UCSR0A & (1 << RXC0)));
  return UDR0;
}


int main()
{
  USART_Init(MYUBRR);
  unsigned char uc_byte;
  while(1)
  {
    uc_byte = USART_Receive();
    USART_Send(uc_byte);
  }
}

von Hubert G. (hubertg)


Lesenswert?

Hast du den Quarz getauscht? Original ist ein 16MHz drinnen.

von Ralf K. (elgitanito)


Lesenswert?

Hallo Hubert,

vielen herzlichen Dank für diesen Wink mit dem Zaunpfahl.
Ich hatte es ja geahnt, es konnte nur ein bescheuerter Denkfehler sein.

Das wars natürlich. Ich hatte mich in die Irre führen lassen und dachte 
mit dem Arduino-Board würde die Taktfrequenz im Auslieferungszustand bei 
8MHz liegen. Deshalb hatte ich auch mit maximal 8MHz getestet. Die 
zuletzt eingetragene Frequenz stammte noch aus Versuchen mit reduzierter 
Frequenz.

Wie dem auch sei: Mit FOSC 16000000UL wird richtig übetragen, auch 
zeitlich um ein Byte versetzt, statt wie vorher, nur um ein Bit.

Nochmals Danke und Grüße,

Ralf

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.