www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Verständnisproblem zu Zeitangaben im Quellcode


Autor: Dominik K. (zergi)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich hab ein Verständnisproblem zu Zeitangaben im C Code.

Ich programmiere mit AVR-Studio und beschreibe den µC auf dem STK500.
Hab etwa ein halbes dutzend ATTiny13, 23 & 25 ausprobiert.
Gemessen habe ich mit einem USB-Speicheroskar und Analogoskar, in beiden 
fällen identische Ergebnise.


Im Quellcode steht:
#define send1()    leds_on();    _delay_us(13.15);    leds_off(); 
_delay_us(13.15);

Das sollte eine Frequenz von 38khz ergeben.


Was das Osziloskop anzeigt findet man im Anhang.
Positive für 107us.
Negative für 112us.
Frequenz 4,6khz.

Nun versteh ich nicht wo der Fehler ist! Muss ich den Takt 
berücksichtigen und die Zeitangaben per hand Korrigieren? Wäre sowas 
nicht Aufgabe des Kompilors? So kenne ich das zumindestens von anderen 
Programmiersprachen.
Hab schon mal die Optimierungseinstellungen von AVR Studio 
durchprobiert, das hat den Wert zwar minimal (Nachkommastelle) 
verändernt, brachte aber keine Verbesserung.

Oder liegt diese Ungenauigkeit an Laufzeiten?
Oder hab ich mich einfach verrechnet?


Was ich auch nicht verstehe ist dass das negative Signal länger als das 
Positive ist, und das sogar wenn ich die beiden Signale tausche.
Das spricht ja eigentlich dafür das es nicht an der Laufzeit liegt.


mfg
Zergi

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CKDIV8 Fuse ausschalten.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Hast du die CKDIV8-Fuse deaktiviert?

MfG Spess

Autor: Dominik K. (zergi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ne, die war nicht deaktiviert.
Bis gerade hatte ich angenommen dass das setzen von F_CPU 
ausschlaggebend wäre.

Hatte daher auch den CPU Takt auf 8MHZ gesetzt und hatte 8x schnellere 
Zeitwerte.




Das verstehe ich jetzt aber gar nicht.

Warum habe ich unterschliedliche Zeiten wenn ich den Takt selber auf 
8MHZ setze, als wenn CKDIV8 (durch Deaktivierung) es macht?


Edit: Die Frequenz liegt dann bei 28,8khz.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Bis gerade hatte ich angenommen dass das setzen von F_CPU
>ausschlaggebend wäre.

Das interessiert nur den Compiler. Den Controller musst du schon selbst 
auf die richtige Frequenz stellen.

MfG Spess

Autor: Dominik K. (zergi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Huhu,


also angenommen der Kompilor denkt der µC rechnet richtig und übergibt 
irgendeine Zahl an den µC.
Der rechnet aber nur mit 1/8 Leistung. Müsste die Frequenz dann nicht 8x 
höher sein?

Das wäre ja dann (ungefähr) das was mit das Osziloskop anzeigt wenn ich 
keinen F_CPU Wert angebe.

Aber wenn ich einen Takt angebe liegt die Frequenz ca. 25% unter dem 
Wert den der µc überhaupt nicht kennt.



F_CPU: NIX
Frequenz soll: 38khz
Frequenz ist: 4,5khz

F_CPU: 8kk
Frequenz soll: 38khz
Frequenz ist: 28khz


Ist zwar schön das ich jetzt weiß wie ich den Fehler wegbekomme, aber 
rein rechnerisch versteh ich es nicht.


mfg
Dominik

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dominik K. schrieb:

> also angenommen der Kompilor denkt der µC rechnet richtig und übergibt
> irgendeine Zahl an den µC.
> Der rechnet aber nur mit 1/8 Leistung. Müsste die Frequenz dann nicht 8x
> höher sein?

Wenn der Prozessor seine Warteschleifen nur mit 1/8 der erwarteten 
Geschwindigkeit dreht, warum sollte das dadurch erzeugte Signal dann das 
8-fache der erwarteten Geschwindigkeit haben?

> Das wäre ja dann (ungefähr) das was mit das Osziloskop anzeigt wenn ich
> keinen F_CPU Wert angebe.

Wenn du keine F_CPU angibst, müßte der Compiler eigentlich mit einem 
Fehler abbrechen.

> Aber wenn ich einen Takt angebe liegt die Frequenz ca. 25% unter dem
> Wert den der µc überhaupt nicht kennt.

Verstehe nicht, was du meinst. Was für ein "Wert den der µC überhaupt 
nicht kennt"?

> F_CPU: NIX
> Frequenz soll: 38khz
> Frequenz ist: 4,5khz

Das ist etwas mehr als Faktor 8.

> F_CPU: 8kk
> Frequenz soll: 38khz
> Frequenz ist: 28khz
>
>
> Ist zwar schön das ich jetzt weiß wie ich den Fehler wegbekomme, aber
> rein rechnerisch versteh ich es nicht.

Deine Funktionen leds_on() und leds_off() brauchen auch Zeit.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lies Dir doch erstmal im Datenblatt "6. System Clock and Clock Options" 
durch.
Dann weißt Du, wie Du welchen Takt Du einstellen kannst (Fuse Bits 
setzen).
Und den mußt Du dann natürlich auch Deinem Compiler bekannt geben.

Die AVR-GCC Lib nimmt bei fehlender Angabe 1MHz an (gibt zwar ne Warnung 
aus, daß sie das tut) und das ist eben oftmals falsch.

Besonders beim ATtiny13, der ist default auf 1,2MHz.

Und der interen RC-Oszillator ist natürlich nicht quarzstabil.


Peter

Autor: Ralph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frequenz Erzeugung über Warteschleifen funktioniert NIEMALS genau.

Dafür gibt es in jedem µC hardware TIMER.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Die AVR-GCC Lib nimmt bei fehlender Angabe 1MHz an

Wozu soll das denn gut sein? Zur Verwirrung?

Autor: Dominik K. (zergi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Muss der µC aber nicht, wenn er mit 1 MHZ rechnet obwohl der Compiler 
von 8MHZ ausgeht um das 8fache daneben liegen?
Das ist das was ich nicht verstehe.


38khz und 28khz ist aber nicht wirklich Faktor 8.
Oder zählt diese Abweichung jetzt schon unter "ungenau"?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dominik K. schrieb:
> Muss der µC aber nicht, wenn er mit 1 MHZ rechnet obwohl der Compiler
> von 8MHZ ausgeht um das 8fache daneben liegen?

Ja.

> Das ist das was ich nicht verstehe.

Wie und wo hast du das F_CPU denn angegeben?

> 38khz und 28khz ist aber nicht wirklich Faktor 8.

Allerdings.

> Oder zählt diese Abweichung jetzt schon unter "ungenau"?

Für einen Faktor von 1 wäre diese Abweichung plausibel.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast doch sicher noch eine Schleife drin und das Send steht in der 
Schleife. Damit kommen bei 1 MHz mind. 4 us pro Schleife für den 
Rücksprung hinzu (einfaches RJMP). Diese Zeit addiert sich zu dem Delay 
dazu.

Deine ersten Messungen sind ziemlich gut 107 us => 112 us sind fast die 
4 us. Und ich denke dein AVR lief am Anfang mit 1 Mhz Werkseinstellung.

Nach der Umstellung auf 8 MHz musst du an den Rücksprung und an den Code 
innerhalb der led_on/led_off Funktionen denken. Die knapsen auch 
Laufzeit ab.

Um das zu justieren, könntest du mal ein Toggeln versuchen

DDRB = (1<<PINB1);
while(1)
{
   PINB = (1<<PINB1); // 1 schreiben toggelt PORTB1 auf modernen AVR
                      // Anzahl Takte nachsehen
   _delay_us(12.65);  // - Feintuning für Rücksprung,,, - s.o.
}

Das ist aber müßig. Setze eine PWM auf, die kann per Hardware einen Pin 
(OC1A oder OC1B...) locker mit 38 kHz toggeln. Das gibt dir die 
Trägerfrequenz der LED. Dann schaltest du die LED plus Vorwiderstand 
zwischen diesen Pin und einen anderen O-Pin als geschaltete Stromsenke. 
HIGH an diesem Pin: LED aus, LOW an diesem PIN: LED an. Das moduliert 
das Datentelegramm auf die Trägerfrequenz.

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:
>    PINB = (1<<PINB1); // 1 schreiben toggelt PORTB1 auf modernen AVR
Was, wie??

PORTB ^= (1<<PB1);
Das suchst du.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Was, wie??

"Bei den neueren AVR (wie z. B. ATtiny13, ATtiny2313, ATtiny24/44/84, 
ATtiny25/45/85, ATmega48/88/168, usw.) kann man als Ausgang 
konfigurierte Pins toggeln (PORTx zwischen 0 und 1 „umschalten“), indem 
man eine 1 an die entsprechende Bit Position des PINx Register 
schreibt."
http://www.mikrocontroller.net/articles/AVR-Tutori...

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Aufklärung!
Klingt fast wie ein Maskenfehler, der als Feature verkauft wird.

Autor: Tabellator (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael H. schrieb:
> Klingt fast wie ein Maskenfehler, der als Feature verkauft wird.

Aber ein sinnvolles Feature.

PORTB ^= ...

braucht mehrere Takte, lesen von PortB, XOR, schreiben von PortB. Und 
kann dummerweise von einem IRQ unterbrochen werden. Wenn der IRQ jetzt 
auch was an PORTB verändern wollte, geht seine Änderung gleich nach dem 
RETI wieder verloren.
Beim Togglen über den den PINB write kann das nicht passieren.

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tabellator schrieb:
> PORTB ^= ...
> braucht mehrere Takte, lesen von PortB, XOR, schreiben von PortB. Und
Nö, ist ein Befehl aus dem Instruktionssatz.

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

Bewertung
0 lesenswert
nicht lesenswert
Michael H. schrieb:
> Tabellator schrieb:
>> PORTB ^= ...
>> braucht mehrere Takte, lesen von PortB, XOR, schreiben von PortB. Und
> Nö, ist ein Befehl aus dem Instruktionssatz.

Toggeln?

Bit Setzen und Löschen sind drinn, aber toggeln IMHO nicht.

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.