www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART Verzweifelung


Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen.

Ich nutze das STK500 mit AVR Studio und dem ATmega16 drauf. Den UART 
Port vom Controller habe ich direkt mit der Spare RS232 Schnittstelle 
des STK500 verbunden. Nun will ich einfach Zeichen senden über UART, 
aber das funktioniert einfach nicht! Es kommen immer andere Zeichen an! 
Habe auch schon verzweifelt im Forum nach einer Lösung gesucht, aber 
nichts gefunden, was mir da weiter hilft.
#include <avr/io.h>
#define FOSC 4000000// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1


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 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, 2stop bit */
  UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

int main( void )
{
  USART_Init ( MYUBRR );
  USART_Transmit(0x48);
  USART_Transmit(0x61);
  USART_Transmit(0x6C);
  USART_Transmit(0x6C);
  USART_Transmit(0x6F);
}

Einstellungen:
Frequency: 4000000
SUT_CKSEL: Int. RC Osc. 4 MHz; Start-up time 6 CK + 64ms
Fuses: High 0x99 Low 0xE3

Über UART kommen folgende Zeichen nun an: C8 E1 E1 EC EF

Was mache ich da genau falsch? Fehlt mir da irgendwo eine Einstellung im 
AVR Studio? Hoffe mir kann irgendwer sagen, was ich falsch machen, denn 
ich finde das Problem einfach nicht.

MFG
Matthias

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist der Fehler:

Matthias wrote:
> SUT_CKSEL: Int. RC Osc. 4 MHz;

Schließe einen Quarz an und die UART funktioniert.


Peter

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

als erstes ist mir in der Definition für die Baudrate ein Formelfehler 
aufgefallen, versuche mal:

#define MYUBRR (FOSC/(16*BAUD) - 1);

dann willst du als Format 8N2 verwenden.

Beim Atmega8 sieht dies so aus, sonst schau eben ins Datenblatt:

// Format: 8N2
UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0) | (1<<USBS);

Da du den Wert MYUBRR definiert hast, kannst dir die Übergaben sparen:

Beispiel:

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


int main( void )
{
  USART_Init ();
  USART_Transmit(0x48);
  USART_Transmit(0x61);
  USART_Transmit(0x6C);
  USART_Transmit(0x6C);
  USART_Transmit(0x6F);
}

So müsste es klappen.

Gruß Mike

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin nochmal, ich muss mich eben korrigieren, meinte natürlich mit der 
definition :

void USART_Init()
{
  /* 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, 2stop bit */
  UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

int main( void )
{
  USART_Init ();
  USART_Transmit(0x48);
  USART_Transmit(0x61);
  USART_Transmit(0x6C);
  USART_Transmit(0x6C);
  USART_Transmit(0x6F);
}

Autor: Robert Teufel (robertteufel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gaebe da noch eine Moeglichkeit die Sache anders zu testen, ist aber 
nur bei konstanter Temp und konstanter Spannung eine echte Option.
In mehreren Testlaeufen den Wert fuer FOSC um jeweils 1% zu aendern also 
40400000, dann 40800000, natuerlich auch in die andere Richtung 3960000 
usw. Wenn das Programm ansonsten richtig ist, dann wird der UART 
ploetzlich funktionieren. Die Tests weiter in dieselbe Richtung 
fortfuehren, bis er nicht mehr funktioniert. Den mittleren funktionial 
Wert nehmen, also z.B. 3920000. Soweit die Spannung sich nicht aendert 
(also keine Batterie!), sollte das dann funktionieren.

Es gibt einige interne Oscillatoren, die hinreichend genau sind fuer 
eine serielle Schnittstellen, der Osc des AVR gehoert nicht dazu ! :-(
Aehnliche Teile mit genauerem Osc waeren z.B. die Teile von Silabs oder 
die LPC900 von NXP. Beide sind mit einem schnellen 51-er core bestueckt.
Nur so zur Info.

Wie Peter also schon gesagt hat, ein externer Osc muss dran, mindestens 
wenn die Kommunikation ueber Spannung und Temperaturaenderungen 
zuverlaessig sein soll.

Robert Teufel
Partner in Silicon Valley gesucht?
Ich stehe gerne zur Verfuegung.
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
Meine ARM/Cortex Webseite: http://www.lpc2000.com

Autor: Matthias Ostermann (ostinator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mhm, dann werde ich mir wohl mal einen besorgen und anschließen bzw. 
kann ich die Frequenz nicht sogar vom STK500 holen?

Wenn ich übrigens MYUBRR nicht übergebe, dann führt das zu einer Warnung 
und das ganze funktioniert dann gar nicht mehr.

Zumindest brauche ich mich jetzt nicht mehr wundern, wieso der Code aus 
dem Datenblatt nicht funktioniert.

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

40400000
es gehen größere Sprünge zum Test bei üblichen PC-UARTS.
Mit 3600000, 3800000, 4000000, 4200000, 4400000 usw, habe ich bisher 
immer schnell die Mitte gefunden.
Mein einer Mega32 schwingt auf ca. 4,4MHz, der Mega16 auf 4,3MHz.
Nutze ich öfter, wenn ich zum Debug mal schnell meinen Debug-UART nutze.

Der gefundene Mittelwert bleibt im Zimmer auch "ewig" stabil genug.

@ Robert Teufel (robertteufel): 40 400 000
Wo hast Du den 40MHz AVR her??? ;-))

Gruß aus Berlin
Michael

Autor: Matthias Ostermann (ostinator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Happy
#define FOSC 4160000// Clock Speed

damit geht es :) Ist zwar keine saubere Lösung, aber zumindest weiß ich 
nun, dass mein Code nicht falsch ist.
Werde mir morgen dann mal einen Quarz besorgen.

DANKE!!!

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich micht richtig erinnere, haben die alten ATmega verschiedene 
Calibrationsbyte für die verschiedenen RC-Frequenzen.

Beim Reset wird aber nur der Wert für 1MHz automatisch geladen.

Wenn man unbedingt den RC verwenden will, muß man also den Programmer 
anweisen, daß er das Calibrationsbyte für 4MHz in den Flash oder EEPROM 
lädt und dann nach dem Reset dort auslesen und setzen.

Die aktuellen ATmega164P laufen immer mit 8MHz und können per Vorteiler 
runter gesetzt werden (default Vorteiler 8 = 1MHz).


Peter

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.