www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART bei atmega8


Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte UART an einem atmega8 nutzen. Der folgende Code soll dabei 
alle einkommenen Zeichen zurücksenden. Ich nutze ein fertiges Board von 
"myavr", Quarz ist, ~3,68 MHz.

Leider funktioniert das ganze nicht und finde keinen Fehler im 
Quellcode:



#include  <avr\io.h>    // AVR Register und Konstantendefinitionen
#include   <util\delay.h>  // Bibliothek mit Warteroutinen
#include <stdint.h>
#define   F_CPU 3686400  // Taktfrequenz des myAVR-Boards


// Define baud rate

#define USART_BAUD 9600ul

#define USART_UBBR_VALUE ((F_CPU/(USART_BAUD<<4))-1)


void USART_vInit(void)

{

// Set baud rate

UBRRH = (uint8_t)(USART_UBBR_VALUE>>8);

UBRRL = (uint8_t)USART_UBBR_VALUE;


// Set frame format to 8 data bits, no parity, 1 stop bit

UCSRC = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);


// Enable receiver and transmitter

UCSRB = (1<<RXEN)|(1<<TXEN);

}


void USART_vSendByte(uint8_t u8Data)

{

// Wait if a byte is being transmitted

while((UCSRA&(1<<UDRE)) == 0);

// Transmit data

UDR = u8Data;

}


uint8_t USART_vReceiveByte()

{

// Wait until a byte has been received

while((UCSRA&(1<<RXC)) == 0);

// Return received data

return UDR;

}


int main(void)

{

uint8_t u8Data;


// Initialise USART

USART_vInit();


// Send string

USART_vSendByte('A');

// Repeat indefinitely

for(;;)

{

// Echo received characters

u8Data  = USART_vReceiveByte();

USART_vSendByte(u8Data);

}

}


Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim schrieb:


> UCSRC = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);

-> Datenblatt!

Autor: Andreas Guter (andreasguter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was soll man den mit so einer Meldung anfangen? Wenn man offenkundig die 
Antwort weiß, darf man sie auch sagen.

Autor: Stefan B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> UCSRC = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);

Was meint dein Datenblatt deines Atmega8 zu dem Bit URSEL in dieser 
Initialisierungsequenz?

Autor: Stefan B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Solch kurze Hinweise sollen das Durchlesen des Datenblatts fördern. Das 
Datenblatt muss die Bibel des µC-Programmierers werden.

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Guter schrieb:
> Was soll man den mit so einer Meldung anfangen?

Offenkundig ins Datenblatt schauen, was da zu dem Register steht...

Autor: Sebastian M. (noobuntu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:
> Was meint dein Datenblatt deines Atmega8 zu dem Bit URSEL in dieser
> Initialisierungsequenz?

• Bit 7 – URSEL: Register Select
This bit selects between accessing the UCSRC or the UBRRH Register. It 
is read as one whenreading UCSRC. The URSEL must be one when writing the 
UCSRC.

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe das Datenblatt nach URSEL durchsucht. Das Ergebnis findet sich 
im folgendem Screenshot:
http://img695.imageshack.us/img695/5830/bildschirmfotou.png

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und was kann ich jetzt mit der Information anfangen vor der Hintergrund, 
dass das Bit URSEL in meinem Code nicht vorkommt?

Autor: Grisu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim schrieb:
> Und was kann ich jetzt mit der Information anfangen vor der Hintergrund,
> dass das Bit URSEL in meinem Code nicht vorkommt?

IM DATENBLATT NACHLESEN, WAS DAS BIT URSEL MACHT!!!!!!!!!!!!!!!!! HASTES 
JETZT?

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim schrieb:
> Und was kann ich jetzt mit der Information anfangen vor der Hintergrund,
> dass das Bit URSEL in meinem Code nicht vorkommt?

seufz schau doch einfach, was beim USCRC-Register steht, wie es 
gesetzt wird...ist Lesen denn so schwer?

Autor: Sebastian M. (noobuntu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Tim,

das habe ich im Datenblatt auf Seite 152 gefunden:

The UBRRH Register shares the same I/O location as the UCSRC Register. 
Therefore some special consideration must be taken when accessing this 
I/O location.
When doing a write access of this I/O location, the high bit of the 
value written, the USART Register. Select (URSEL) bit, controls which 
one of the two registers that will be written. If URSEL is zero during a 
write operation, the UBRRH value will be updated. If URSEL is one, the 
UCSRC setting will be updated.
The following code examples show how to access the two registers.
/* Set UBRRH to 2 */
UBRRH = 0x02;
...
/* Set the USBS and the UCSZ1 bit to one, and */
/* the remaining bits to zero. */
UCSRC = (1<<URSEL)|(1<<USBS)|(1<<UCSZ1);
... 

Sprich wenn du in dein UCSRC Register schreiben willst, musst du erst 
das Bit URSEL auf 1 setzen. Sonst schreibst du in UBRRH (und veränderst 
dadurch deine Baudrate -> da bin ich mir jetzt nicht so sicher, als 
lyncht mich nicht sofort.)

Autor: Andreas Guter (andreasguter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probere mal folgendes

UCSRC = (1<<URSEL)|(1<<USBS)|(1<<UCSZ1);

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist es also so richtig?
#include  <avr\io.h>    // AVR Register und Konstantendefinitionen
#include   <util\delay.h>  // Bibliothek mit Warteroutinen
#include <stdint.h>
#define   F_CPU 3686400  // Taktfrequenz des myAVR-Boards


// Define baud rate

#define USART_BAUD 9600ul

#define USART_UBBR_VALUE ((F_CPU/(USART_BAUD<<4))-1)


void USART_vInit(void)

{

// Set baud rate

UBRRH = (uint8_t)(USART_UBBR_VALUE>>8);

UBRRL = (uint8_t)USART_UBBR_VALUE;


// Set frame format to 8 data bits, no parity, 1 stop bit





//Hier die Änderung:


UBRRH = 0x02;

UCSRC = (1<<URSEL)|(1<<USBS)|(1<<UCSZ1);


//Änderungende






// Enable receiver and transmitter

UCSRB = (1<<RXEN)|(1<<TXEN);

}


void USART_vSendByte(uint8_t u8Data)

{

// Wait if a byte is being transmitted

while((UCSRA&(1<<UDRE)) == 0);

// Transmit data

UDR = u8Data;

}


uint8_t USART_vReceiveByte()

{

// Wait until a byte has been received

while((UCSRA&(1<<RXC)) == 0);

// Return received data

return UDR;

}


int main(void)

{

uint8_t u8Data;


// Initialise USART

USART_vInit();


// Send string

USART_vSendByte('A');

// Repeat indefinitely

for(;;)

{

// Echo received characters

u8Data  = USART_vReceiveByte();

USART_vSendByte(u8Data);

}

}



Autor: Sebastian M. (noobuntu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Denke schon. Funktioniert es jetzt ?

Autor: Stefan B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht richtig.

// Set frame format to 8 data bits, no parity, 1 stop bit
UCSRC = (1<<URSEL)|(1<<USBS)|(1<<UCSZ1);

Du hast bei dieser Initialisierung nicht 8-Datenbits und nicht 1 
Stoppbit.

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso. Und warum nicht?
Wie muss es richtig heißen?

Autor: Stefan B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit solchen Fragen 1 Min. später ohne jegliche Initiative selbst im 
Datenblatt zu lesen machst du dich nicht beliebt.

// Set frame format to 8 data bits, no parity, 1 stop bit
UCSRC = (1<<URSEL)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);

Over and out.

Autor: Ben ___ (burning_silicon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
übrigens ist 8N1 oft die standardeinstellung, die der AVR von sich aus 
nach dem anlegen der betriebsspannung einnimmt. wenn man also nichts 
anderes braucht erübrigt sich eine änderung dieser werte.

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, leider funktioniert es weiterhin nicht:
#include  <avr\io.h>    // AVR Register und Konstantendefinitionen
#include   <util\delay.h>  // Bibliothek mit Warteroutinen
#include <stdint.h>
#define   F_CPU 3686400  // Taktfrequenz des myAVR-Boards


// Define baud rate

#define USART_BAUD 9600ul

#define USART_UBBR_VALUE ((F_CPU/(USART_BAUD<<4))-1)


void USART_vInit(void)

{

// Set baud rate

UBRRH = (uint8_t)(USART_UBBR_VALUE>>8);

UBRRL = (uint8_t)USART_UBBR_VALUE;


// Set frame format to 8 data bits, no parity, 1 stop bit





//Hier die Änderung:

UCSRC = (1<<URSEL)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);

//Änderungende






// Enable receiver and transmitter

UCSRB = (1<<RXEN)|(1<<TXEN);

}


void USART_vSendByte(uint8_t u8Data)

{

// Wait if a byte is being transmitted

while((UCSRA&(1<<UDRE)) == 0);

// Transmit data

UDR = u8Data;

}


uint8_t USART_vReceiveByte()

{

// Wait until a byte has been received

while((UCSRA&(1<<RXC)) == 0);

// Return received data

return UDR;

}


int main(void)

{

uint8_t u8Data;


// Initialise USART

USART_vInit();


// Send string

USART_vSendByte('A');

// Repeat indefinitely

for(;;)

{

// Echo received characters

u8Data  = USART_vReceiveByte();

USART_vSendByte(u8Data);

}

}



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

Bewertung
0 lesenswert
nicht lesenswert
Tim schrieb:
> Danke, leider funktioniert es weiterhin nicht:


Du sendest am Anfang ein einzelnes 'A'.
Siehst du das auf der anderen Seite?

Was ist wenn du den µC einfach mal ständig 'A' senden lässt? Kommen die 
auf der anderen Seite richtig an?

Und bitte: Zieh den Code doch nicht so in die Länge! Code wird nicht 
übersichtlicher, wenn man mehr Leerzeilen einfügt. Er zieht sich nur in 
die Länge und sonst gar nichts. Wenn du Übersicht haben willst, dann 
kümmere dich um die Einrückungen.

Autor: Andreas Guter (andreasguter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, es kommt rein gar nichts an. Weder die As, noch die 
Repeater-Funktion.
Ich mache das ganze übrigens mit hterm unter Windows Vista, da ich kein 
anderes Betriebssystem zu Verfügung habe.

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

Bewertung
0 lesenswert
nicht lesenswert
Andreas Guter schrieb:
> Nein, es kommt rein gar nichts an. Weder die As, noch die
> Repeater-Funktion.
> Ich mache das ganze übrigens mit hterm unter Windows Vista, da ich kein
> anderes Betriebssystem zu Verfügung habe.

Dann solltest du fürs erste den Repeater zur Seite legen und dich nur 
auf das Senden konzentrieren (eine Fehlerquelle weniger).

http://www.mikrocontroller.net/articles/AVR_Checkl...

Insebsondere könntest du mit dem vorletzten Punkt im Abschnitt "Sonstige 
Fehlerquellen bei UART/USART" anfangen und zunächst feststellen ob die 
Hardware-Kette vom µC zum PC in Ordnung ist, bzw. ob das Kabel korrekt 
ausgekreuzt ist. Diesen Test würde ich dir zur Sicherheit sowieso 
empfehlen. Solange dieser Test nicht einwandfrei klappt, hat es keinen 
Sinn nach anderen Ursachen zu fahnden.
Also: Mega8 aus dem Sockel raus. RX/TX im Sockel mit einem Stück Draht 
verbinden und im hTerm drauflosklimpern. Alles was du tippst, muss im 
hTerm auch aufscheinen. Gegentest machen: Drahtbrücke entfernen. Jetzt 
darf Getipptes im hTerm nicht mehr aufscheinen.

Autor: Stefan B. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Das Programm im Anhang ist dein neustes Programm leicht geändert für 
einen Test mit Attiny2313 @ 8 MHz. Dein Programm funktioniert. Ich 
vermute daher ein Hardwareproblem.

Prüfe dein RS232-Kabel.

Bei dem myAVR Board MK1 LPT endet TXD des Atmega auf Pin 3 des 
DB9-Anschlusses. 
http://shop.myavr.de/index.php?ws=download_file.ws... 
D.h. das Board ist beschaltet sich wie ein PC (DTE Data Terminal 
Equipment). Zur Verbindung zweiter DTEs also myAVR<->PC brauchst du ein 
sog. Nullmodemkabel mit gekreuzten Leitungen.

Bei dem myAVR Board MK2 USB, Version 2.1 ist das im Schaltplan nicht 
offensichtlich. Ich vermute aber, es ist genauso wie beim MK1 
implementiert.

Zusätzlich kannst du noch auf dem myAVR Board CTS/RTS per Jumper 
brücken. Wenn der PC auf Hardwareflusskontrolle eingestellt wäre, würde 
das helfen. Und wenn er nicht auf Hardwareflusskontrolle eingestellt 
ist, schadet es nicht.

Die Übertragungsstrecke (Buchsen, Kabel, MAX232) kannst du ausserdem so 
prüfen: Atmega8 in den Dauerreset versetzen (z.B. Drahtjumper RESET nach 
GND). RXD und TXD sind dann als Eingang geschaltet. Dann Drahtjumper 
zwischen RXD und TXD anbringen. Jedes vom PC aus gesendete Zeichen 
sollte jetzt als Echo zurückkommen. Die drei Buchsen für die Jumper 
sitzen unmittelbar am Atmega8.

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.