Forum: Compiler & IDEs Uart Atmega 8


von Christoph (Gast)


Lesenswert?

hallo,
ich schaff es einfach nicht das Senden mit Uart zum laufen zu bringen.
Es gab ein Testprogramm des Boardherstellers, welches ich aber nicht
einsehen kann. Das funktioniert, also muss es an meinem C-Code liegen.
Mit meinem Code werden zwar zahlen übertragen, aber bei sämtlichen
anderen Zeichen kommen bei mir nur Punkte ("......")an.
Was kann ich besser machen an dem Code hier?
Danke für jede Hilfe!!

#define    F_CPU 3686400   // Taktferquenz des myAVR-Boards
#include   <avr\io.h>      // AVR Register und Konstantendefinitionen

#define UART_BAUD_RATE 9600 // 9600 BAUD
#define USARTSPEED F_CPU/(UART_BAUD_RATE*16L)-1
#define LOW(x)  ((x) & 0xFF)
#define HIGH(x)  (((x) >> 8) & 0xFF)
//----------------------------------------------------------------------

void UART_senden()
{
   while ((UCSRA & (1<<UDRE))) /*warten bis senden möglich */
      UDR = 'a';
}

void init_UART ()
{
   UBRRH= HIGH(USARTSPEED);
   UBRRL= LOW(USARTSPEED);
   UCSRB = (1<<RXEN)|(1<<TXEN);
   UCSRC|=(1<<URSEL)|(3<<UCSZ0);
}

main ()
{
   init_UART();
   do
   {
      // Schleifenanfang Mainloop
      UART_senden();
   }
   while (true);         // Schleifenende Mainloop
}

von Thilo (Gast)


Lesenswert?

Probier's mal bei UART_senden mit

while ( !( UCSRA & (1<<UDRE)));

vielleicht klappt's dann!

von Peter (Gast)


Lesenswert?

Stören Dich die Warnings beim Compilieren nicht!

F_CPU müsste schon via makefile definiert sein

void UART_senden(void)  // void in die Klammer!
{
   while ((UCSRA & (1<<UDRE))); // Der BUG: Semikolon fehlt
   UDR = 'a';                   // sonst wird 'a' ins UDR
                                // geschrieben, bis senden möglich ist
}

void init_UART(void) // void in die Klammer!
{
   UBRRH= HIGH(USARTSPEED);
   UBRRL= LOW(USARTSPEED);
   UCSRB = (1<<RXEN)|(1<<TXEN);
   UCSRC|=(1<<URSEL)|(3<<UCSZ0);
}

int main(void)  // int vor main; void in die Klammer
{
   init_UART();
   do
   {
      // Schleifenanfang Mainloop
      UART_senden();
   }
   while (1);         // Schleifenende Mainloop
}


Gruss Peter

von Christoph (Gast)


Lesenswert?

Danke schon mal an euch.
Ich hatte die while schleife falsch verstanden. Das ist jetzt klar.
Hab jetzt eure Verbesserung umgesetzt

while (!(UCSRA & (1<<UDRE)));

Leider hat es das Problem nicht gelöst. Immer noch keine Zeichen und
Zahlen werden unregelmäßig mal gesendet, mal wieder nicht :-(
Ich denke aber es liegt dann an der init.

von Peter (Gast)


Lesenswert?

Für UART-Betrieb sollte die Baudrate mindestens auf 1%-1.5% genau sein,
dies erreicht der inerne RC-Oszillator oft nicht! (Bloss wenn er
aureichend gut kalibriert wird)

Stimmt die Baudrate bzw. F_CPU exact?
Verwendest Du den internen RC-Oszi? Wie gut kalibriert?
Brauchst Du nen externen Oszi oder Quarz?
Ist dieser dann auch mit den entsprechenden Fuses selektiert?

Gruss Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

3,6864 MHz klingt nicht wie interner RC-Oszillator (auch wenn
man den 4-MHz-Oszillator darauf trimmen kann).  Da er irgendwelche
Zeichen zuweilen sieht, gehe ich mal davon aus, dass es ihm auch
bereits gelungen ist, den externen Quarz zumindest einzuschalten.

von Christoph (Gast)


Lesenswert?

Den externen Quarz hab ich aktiviert. Wie oben gesagt funktioniert ja
auch ein Testprogramm, was ich aber nicht einsehen kann. Ich weiß
allerdings nicht ob ich alles richtig gemacht habe beim stzen der
Register für die 8bit Wortbreite, keine Parität, asychron, stopbit, und
txen bit. hab mir die Register gestern noch mal angeschaut und was
korrigiert weil die bei meinem myavr board anders waren, als im
tutorial. Leider klappt es immer noch nicht.

von Christoph (Gast)


Lesenswert?

Falls jmd von euch auch atmega8 programmiert, könntet ihr mir mal kurz
posten welche Register ich setzen muss.
Letzter Stand bei mir ist:

UBRRH= HIGH(USARTSPEED);
   UBRRL= LOW(USARTSPEED);
   UCSRB|= (1<<TXEN);
   UCSRC|=(1<<UCSZ1)|(1<<UCSZ0);      //8bit

für keine Parität,stopbit, und asxchron müssen die entsprechenden
Register glaub ich nicht gesetzt werden

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

UBRRH muss man meistens nicht setzen, da es für alle
,,gewöhnlichen'' Verhältnisse von Baudrate zu Taktfrequenz
0 ist.  (Nur für sehr niedrige Baudraten bei maximalem Takt
wird das größer als 0.)

UCSRC muss man auch nicht setzen, da die Voreinstellung 8N1 ist
und damit der gängigen Praxis entspricht.

Vorsicht ist bei den AVRs geboten, bei denen sich UBRRH und
UCSRC eine Adresse teilen: dort kann das ,,unbedarfte'' Setzen
dieser Register einiges durcheinander bringen.

Ansonsten genügt es für einfachten gepollten Sendebetrieb
wirklich, das TXEN zu setzen und UBRRL.

von Christoph (Gast)


Lesenswert?

Es läuft!!!

Es lag an den Registern. Ganz vielen Dank Jörg und auch den anderen!!!

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.