Uart Atmega 8

Gast #411152
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
}
Gast #411154
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
Gast #411155
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.
Gast #411156
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
Gast #411158
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.
Gast #411159
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
Moderator Persönliche Seite #411160
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren