www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega16 über UART an Terminal


Autor: TeaKay (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!!

Ich bin totaler neu Anfänger im Bereich µC. Arbeite momentan mit dem 
STK500 und einem ATmega16 an einer UART-Verbindung, programmieren tu ich 
das ganze mit AVR-Studio. Habe das folgende Programm aus dem Tutorial 
AVR-GCC verwendet.
#include <avr/io.h>

#ifndef F_CPU
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
#define F_CPU 4000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! 
#endif
 
#define BAUD 9600L          // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
 
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille 
 
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif

int main(void)
{
    UCSRB |= (1<<TXEN);                // UART TX einschalten
    UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1 
 
    UBRRH = UBRR_VAL >> 8;
    UBRRL = UBRR_VAL & 0xFF;
while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
    {
    }
 
    UDR = 'x';                    /* schreibt das Zeichen x auf die Schnittstelle */
}

Als erstes bekomme ich beim compilieren im Studio bei folgender 
Anweisung
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif
eine Fehlermeldung "../main.c:16:4: error: #error Systematischer Fehler 
der Baudrate grösser 1% und damit zu hoch!". Weiss jemand, was dies 
bedeutet??? Ist meine Baudrate evtl. zu hoch?? Wenn ich es über die 
Formel UBRR_VAL berechne komme ich auf -1,5.

Habe diese if-Definition mit dem #error mal deaktiviert um dann das 
Programm zu testen. Allerdings ohne Erfolg, es wurde keine Zeichen im 
Hyperterminal angezeigt.

Wäre echt super, wenn mir jemand weiterhelfen könnte, wo mein Problem 
ist. Spiele schon seit mehreren Tagen daran herum.

Grüße
Thomas

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

Bewertung
0 lesenswert
nicht lesenswert
Wahrscheinlich hast du im AVR-Studio die Taktrate eingestellt und dort
das angehängte L vergessen.
Dadurch wird die ganze Berechnung unsigned gemacht und ein negativer
Wert wird als riesig grosser Wert berechnet.

Wenn nach deiner Rechnerei -1.5% rauskommt, ist das in Ordnung.

Aber: Stimmt die angegebene Taktfrequenz mit der realen Taktfrequenz
überein?
Hast du einen Quarz im System?

Autor: Thomas K. (teakay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

danke erstmal für die schnelle Antwort.

Karl heinz Buchegger wrote:
> Wahrscheinlich hast du im AVR-Studio die Taktrate eingestellt und dort
> das angehängte L vergessen.
Habe da nochmal nachgeschaut und festgestellt, dass in den 
Projekteinstellungen bei Custom Options ein DF_CPU=4000000L drin steht. 
Habe dies mal abgeändert in F_CPU=4000000L. Ich denke mal dies hattest 
du ja gemeint oder???
> Dadurch wird die ganze Berechnung unsigned gemacht und ein negativer
> Wert wird als riesig grosser Wert berechnet.
>
> Wenn nach deiner Rechnerei -1.5% rauskommt, ist das in Ordnung.
Bekomme aber nach meiner Rechnerei bei letzter Formel:
heraus.
> Aber: Stimmt die angegebene Taktfrequenz mit der realen Taktfrequenz
> überein?
> Hast du einen Quarz im System?
Ja habe einen Quarz gesteckt mit 4MHz. Scheint auch zu funktionieren. 
Wie kann ich die angegebenen Taktfrequenz denn mit der realen 
vergleichen???

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

Bewertung
0 lesenswert
nicht lesenswert
Thomas Kratz wrote:

> Ja habe einen Quarz gesteckt mit 4MHz. Scheint auch zu funktionieren.
> Wie kann ich die angegebenen Taktfrequenz denn mit der realen
> vergleichen???

Du kannst zb so ein Testprogramm benutzen:
#include <avr/io.h>
#include <util/delay.h>

#ifndef F_CPU
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
#define F_CPU 4000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! 
#endif

int main()
{
  uint8_t i;

  DDRB = 0xFF;

  while( 1 ) {
    PORTB = 0xFF;

    for( i = 0; i < 100; ++i )
      _delay_ms( 10 );

    PORTB = 0x00;

    for( i = 0; i < 100; ++i )
      _delay_ms( 10 );
  }
}

Das benutzt Warteschleifen um eine bestimmte Zeit zu warten.
In dem Fall: 1 Sekunde.
Die Warteschleifen hängen aber vom tatsächlichen, realen
Systemtakt ab.

Blinken ein paar Led am Port B jeweils 1 Sekunde (1 Sekunde an,
1 Sekunde aus), dann ist der 4 Mhz Quarz aktiv und arbeitet auch
richtig. Ist der Quarz nicht aktiv, dann arbeitet dein AVR
immer noch mit der Standard Vorgabe des internen RC-Oszillators
bei ca. 1Mhz. Dann ist die LED jeweils 4 Sekunden an und 4 Sekunden
aus.

Den Unterschied kann man mit freiem Auge gut sehen.
Also: Ist die Led ca 1. Sekunde an/aus? (es kommt da jetzt nicht
auf ein paar Zehntelsekunden an) oder sind es mehr so 4 Sekunden.

Autor: Thomas K. (teakay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm,

irgendwie blinkt da bei mir gar nix. Scheint mein Quarz nicht zu 
funktionieren. Was kann ich da nun machen??

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

Bewertung
0 lesenswert
nicht lesenswert
Thomas Kratz wrote:
> Hmm,
>
> irgendwie blinkt da bei mir gar nix.

Schlecht

> Scheint mein Quarz nicht zu
> funktionieren.

Wenn sich gar nichts tut, ist die Vermutung eher, dass das
Brennen des Programmes in den AVR schief gegangen ist.
Oder dein STK500 ist nicht richtig verkabelt.

Hast du schon andere Programme laufen lassen?


PS: Hast du ev. an den Fusebits rumgespielt?
Nicht dass du den Prozessor irrtümlich auf 'externen Takt'
anstelle von 'externen Quarz' gesetzt hast.

Autor: Thomas K. (teakay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Wenn sich gar nichts tut, ist die Vermutung eher, dass das
> Brennen des Programmes in den AVR schief gegangen ist.
> Oder dein STK500 ist nicht richtig verkabelt.
Also verkabelt ist alles richtig, denn meine LEDs leuchten alle, nur 
dass sie nicht blinken.
> Hast du schon andere Programme laufen lassen?
Ja habe gerade eines getestet. Dieses
#include <avr/io.h>          // (1)
 
int main (void) {            // (2)
 
   DDRB  = 0xff;             // (3)
   PORTB = 0x03;             // (4)
 
   while(1) {                // (5a)
     /* "leere" Schleife*/;  // (5b)
   }                         // (5c)
 
   /* wird nie erreicht */
   return 0;                 // (6)
}
>
> PS: Hast du ev. an den Fusebits rumgespielt?
> Nicht dass du den Prozessor irrtümlich auf 'externen Takt'
> anstelle von 'externen Quarz' gesetzt hast.
Ja habe ich, ich habe es glaub ich gestern ausversehen mal auf externen 
Takt, aber habe dies dann wieder auf "ext. crystal/resonator high 
frequ.;start up time 16k ck + 64ms; [CKSEL=1111 SUT=11]" eingestellt. 
Ist dies denn so richtig bei einem 4MHz Quarz??

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

Bewertung
0 lesenswert
nicht lesenswert
Hmm. Ich seh aber keinen Grund warum der Blinkcode ....


Ah! Hast du den Optimizer im AVR-Studio eingeschaltet?
_delay_ms funktioniert nur mit eingeschaltetem Optimizer
richtig.

Autor: Thomas K. (teakay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe gerade nochmal ein wenig rumgetestet und nun geht es. Den 
Code-Optimizer habe ich auf 0s eingestellt gehabt.

Trotzdem danke für deine Hilfe erstmal. Werde nun noch mal schnell die 
UART testen und hoffen es funzt dann.

Gruß
Thomas

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In Deinem Programm hat mindestens die Endlosschleife in main gefehlt.

Autor: Thomas K. (teakay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In welchem meinst du denn Michael??

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

Bewertung
0 lesenswert
nicht lesenswert
> In welchem meinst du denn Michael??

In deinem ersten UART Programm.

Wenn du es noch mal probierst, ändere es so um:

  ....

  while( 1 ) {
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
    {
    }
 
    UDR = 'x'; 
  }
}

dann sendet der UART dauernd und die hardwaremässige Fehlersuche
wird einfacher.

Autor: Thomas K. (teakay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah danke für den Tipp, aber nun funktioniert es endlich. Habe irgendwo 
nen kleinen Bock drin gehabt bei meinen Einstellungen.

Gruß
Thomas

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.