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


von TeaKay (Gast)


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.
1
#include <avr/io.h>
2
3
#ifndef F_CPU
4
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
5
#define F_CPU 4000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! 
6
#endif
7
 
8
#define BAUD 9600L          // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
9
 
10
// Berechnungen
11
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
12
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
13
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille 
14
 
15
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
16
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
17
#endif
18
19
int main(void)
20
{
21
    UCSRB |= (1<<TXEN);                // UART TX einschalten
22
    UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1 
23
 
24
    UBRRH = UBRR_VAL >> 8;
25
    UBRRL = UBRR_VAL & 0xFF;
26
while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
27
    {
28
    }
29
 
30
    UDR = 'x';                    /* schreibt das Zeichen x auf die Schnittstelle */
31
}

Als erstes bekomme ich beim compilieren im Studio bei folgender 
Anweisung
1
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
2
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
3
#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

von Karl H. (kbuchegg)


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?

von Thomas K. (teakay)


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???

von Karl H. (kbuchegg)


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:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
#ifndef F_CPU
5
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
6
#define F_CPU 4000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! 
7
#endif
8
9
int main()
10
{
11
  uint8_t i;
12
13
  DDRB = 0xFF;
14
15
  while( 1 ) {
16
    PORTB = 0xFF;
17
18
    for( i = 0; i < 100; ++i )
19
      _delay_ms( 10 );
20
21
    PORTB = 0x00;
22
23
    for( i = 0; i < 100; ++i )
24
      _delay_ms( 10 );
25
  }
26
}

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.

von Thomas K. (teakay)


Lesenswert?

Hmm,

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

von Karl H. (kbuchegg)


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.

von Thomas K. (teakay)


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
1
#include <avr/io.h>          // (1)
2
 
3
int main (void) {            // (2)
4
 
5
   DDRB  = 0xff;             // (3)
6
   PORTB = 0x03;             // (4)
7
 
8
   while(1) {                // (5a)
9
     /* "leere" Schleife*/;  // (5b)
10
   }                         // (5c)
11
 
12
   /* wird nie erreicht */
13
   return 0;                 // (6)
14
}
>
> 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??

von Karl H. (kbuchegg)


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.

von Thomas K. (teakay)


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

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

In Deinem Programm hat mindestens die Endlosschleife in main gefehlt.

von Thomas K. (teakay)


Lesenswert?

In welchem meinst du denn Michael??

von Karl H. (kbuchegg)


Lesenswert?

> In welchem meinst du denn Michael??

In deinem ersten UART Programm.

Wenn du es noch mal probierst, ändere es so um:
1
  ....
2
3
  while( 1 ) {
4
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
5
    {
6
    }
7
 
8
    UDR = 'x'; 
9
  }
10
}

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

von Thomas K. (teakay)


Lesenswert?

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

Gruß
Thomas

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.