Forum: Mikrocontroller und Digitale Elektronik Wie findet man möglichst genau die Frequenz des internen RC-Oszilators heraus ?


von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Hallo zusammen,

was stimmt an meinem Assemblerprogramm für den ATtiny26 nicht, da ich 
bei beiden Versionen 6 Takte verwende, aber die Frequenz die ich messe 
im Verhältnis 2 zu 1 steht.

Ich habe schon einiges zum internen RC-Oszilator gelesen
( OSCCAL-Register usw. ), aber irgendwie habe ich keine Idee wie ich die 
wirkliche Frequenz des internen RC-Oszilators einfach ermitteln kann.

Ein funktionierender Assemblercode wäre natürlich das Beste.

Ich will halt herausfinden wie sich eine Änderung des Wertes im
OSCCAL-Register auswirkt, um den RC-Oszi möglichst genau auf 1Mhz zu 
trimmen.

Um es noch mal klarer zu machen :

Das durch ändern des OSCCAL-Wertes sich die Frequenz ändert kann ich 
feststellen. Aber wie ich dann auf die tatsächliche Frequenz des 
RC-Oszilators schliessen kann, das ist mir noch nicht klar.

Es ist sicher wieder eine einfache Sache, deshalb findet man auch nicht 
die passende Routine, da dies für die meisten Programmierer wohl zu 
einfach ist.

Bernd_Stein

von 123 (Gast)


Lesenswert?

Aus dem Takt leiten sich die Timertakte ab, die Formeln stehen im 
Datenblatt. Programmier einen Timer, messe den Output und errechne 
daraus den internen Takt.

von MaWin (Gast)


Lesenswert?

> Das durch ändern des OSCCAL-Wertes sich die Frequenz ändert
> kann ich feststellen.

Klar.

Die Fraquenz ändert sich auch durch leichte Schwankungen der 
Versorgungsspannung, durch die Umgebungstemperatur, durch die Höhe des 
Rauschens auf der Versorgungsspannung durch einstreuungen eines 
Rundfunksenders, durtch die Anzahl der auf high geschalteten Ausgänge,

was ist jetzt das Besondere daß sich diese Frequenz auch ändert wenn man 
an dem Register rumspielt ?


Ein RC-Oszillator ist schlichht und einfach ungeeignet wenn es um GENAUE 
Frequenzen geht, dafür wurden Quartze erfunden, was hast du daran nicht 
verstanden ?

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

123 schrieb:
> Aus dem Takt leiten sich die Timertakte ab, die Formeln stehen im
> Datenblatt. Programmier einen Timer, messe den Output und errechne
> daraus den internen Takt.
>
Ach mist - da hab ich doch was vergessen !!!

Genau da liegt schon mal das Problem, ich bin nicht in der Lage an Hand 
der Takte der jeweiligen Befehle auf die Frequenz des RC-Oszilators zu 
schliessen.

Hier nachträglich mein Programm :
1
;                       ATtiny26 im Auslieferungszustand
2
;
3
4
;.list
5
.include "tn26def.inc"      ;Label Zuweisungen
6
7
;Konstanten Zuweisungen
8
;.equ    =   ;
9
10
;µC Pinbelegung
11
.equ led_ws     = PORTB6    ;LED Weiss
12
13
;Einige Befehle arbeiten nur ab r16 aufwärts
14
.def a              = r16   ;Allgemeines Arbeitsregister A ( GPR_A )
15
.def b              = r17   ;Allgemeines Arbeitsregister B ( GPR_B )
16
.def c              = r18   ;Allgemeines Arbeitsregister C ( GPR_C )
17
18
;Prgrammspeicher festlegen
19
.CSEG       ;Code Segment ( Programmspeicher )
20
.ORG $0000  ;Programm beginnt bei Adresse 0
21
22
23
;Interuppt Vektoren
24
    rjmp RESET          ;Reset handler
25
    reti                ;rjmp EXT_INT0     ;IRQ0 handler
26
    reti                ;rjmp PIN_CHANGE  ;Pin change handler
27
    reti                ;rjmp TIM1_CMP1A   ;Timer1 compare match 1A
28
    reti                ;rjmp TIM1_CMP1B   ;Timer1 compare match 1B
29
    reti                ;rjmp TIM1_OVF     ;Timer1 overflow handler
30
    reti                ;rjmp TIM0_OVF       ;Timer0 overflow handler (Programmlaufanzeige)
31
    reti                ;rjmp USI_STRT     ;USI Start handler
32
    reti                ;rjmp USI_OVF     ;USI Overflow handler
33
    reti                ;rjmp EE_RDY     ;EEPROM Ready handler
34
    reti                ;rjmp ANA_COMP     ;Analog Comparator handler
35
    reti                ;rjmp ADCIRQ    ;ADC Conversion Handler
36
37
;-----------------------------------------------------------------------------
38
;Programmstart nach einem Reset ( Initialisierungen )
39
;-----------------------------------------------------------------------------
40
RESET:
41
42
;Stack initialisieren
43
    ldi  r16,RAMEND         ;Setze den Stack-Pointer...
44
    out  SP,r16             ;...an das SRAM-Ende.
45
46
;RC-Oszilator kalibriren
47
.set w_osccal   = $c1
48
    ldi  a,w_osccal
49
    out  OSCCAL,a
50
51
;Ports initialisieren
52
    ldi  A,0b01000000       ;Ein,- oder Ausgang fuer...
53
    out  DDRB,A             ;...diesen Port bestimmen
54
55
;-----------------------------------------------------------------------------
56
;Hauptprogrammschleife ( HPS )
57
;-----------------------------------------------------------------------------
58
hps:
59
;ca. 81kHz
60
;    sbi  PORTB,led_ws       ;
61
;    cbi  PORTB,led_ws       ;6 Takte
62
;    rjmp hps                ;
63
64
65
;ca. 161kHz
66
    ldi  c,1<<led_ws        ;
67
    in   b,PORTB            ;
68
    eor  b,c                ;6 Takte
69
    out  PORTB,b            ;
70
    rjmp hps                ;
71
72
.exit

Bernd_Stein

von Piete (Gast)


Lesenswert?

Bernd Stein schrieb:
> 123 schrieb:
>> Aus dem Takt leiten sich die Timertakte ab, die Formeln stehen im
>> Datenblatt. Programmier einen Timer, messe den Output und errechne
>> daraus den internen Takt.
>>
> Ach mist - da hab ich doch was vergessen !!!
>
> Genau da liegt schon mal das Problem, ich bin nicht in der Lage an Hand
> der Takte der jeweiligen Befehle auf die Frequenz des RC-Oszilators zu
> schliessen.


123 meinte sicher einen Timer konfigurieren und über die OCR Register 
die OC output lines steuern. Dort dann die Frequenz messen und auf die 
interne zurückschließen. Da braucht man keine Takte im Programm zu 
zählen.

von 123 (Gast)


Lesenswert?

Piete schrieb:
> 123 meinte sicher einen Timer konfigurieren und ...
Genau.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Piete schrieb:
>
> 123 meinte sicher einen Timer konfigurieren und über die OCR Register
> die OC output lines steuern. Dort dann die Frequenz messen und auf die
> interne zurückschließen. Da braucht man keine Takte im Programm zu
> zählen.
>
Ohne Takte im Programm zählen zu müssen habe ich auch schon hinter mir.
1
;                       ATtiny26 im Auslieferungszustand
2
;
3
;.list
4
.include "tn26def.inc"      ;Label Zuweisungen
5
6
;Konstanten Zuweisungen
7
.equ w_osccal   = $Dc
8
9
;µC Pinbelegung
10
.equ led_ws     = PORTB6    ;LED Weiss
11
12
;Einige Befehle arbeiten nur ab r16 aufwärts
13
.def a              = r16   ;Allgemeines Arbeitsregister A ( GPR_A )
14
.def b              = r17   ;Allgemeines Arbeitsregister B ( GPR_B )
15
.def c              = r18   ;Allgemeines Arbeitsregister C ( GPR_C )
16
17
;Prgrammspeicher festlegen
18
.CSEG       ;Code Segment ( Programmspeicher )
19
.ORG $0000  ;Programm beginnt bei Adresse 0
20
21
;Interuppt Vektoren
22
    rjmp RESET          ;Reset handler
23
    reti                ;rjmp EXT_INT0      ;IRQ0 handler
24
    reti                ;rjmp PIN_CHANGE    ;Pin change handler
25
    reti                ;rjmp TIM1_CMP1A    ;Timer1 compare match 1A
26
    reti                ;rjmp TIM1_CMP1B    ;Timer1 compare match 1B
27
    reti                ;rjmp TIM1_OVF      ;Timer1 overflow handler
28
    rjmp TIM0_OVF       ;Timer0 overflow handler 
29
    reti                ;rjmp USI_STRT      ;USI Start handler
30
    reti                ;rjmp USI_OVF       ;USI Overflow handler
31
    reti                ;rjmp EE_RDY        ;EEPROM Ready handler
32
    reti                ;rjmp ANA_COMP      ;Analog Comparator handler
33
    reti                ;rjmp ADCIRQ        ;ADC Conversion Handler
34
35
;-----------------------------------------------------------------------------
36
;Programmstart nach einem Reset ( Initialisierungen )
37
;-----------------------------------------------------------------------------
38
RESET:
39
40
;Stack initialisieren
41
    ldi  r16,RAMEND         ;Setze den Stack-Pointer...
42
    out  SP,r16             ;...an das SRAM-Ende.
43
44
;Timer0 intialisieren 
45
    in   a,TCCR0            ;Timer/Counter0 Control Register laden...
46
    ori  a,1<<CS00          ;...und Timertakt = Systemtakt/ 1...
47
    out  TCCR0,a            ;...Timertakt = 1MHz => 1µs einstellen...
48
    in   a,TIMSK            ;Timer/Counter0 Maskenregister laden und...
49
    ori  a,1<<TOIE0         ;...Timer/Counter0 Overflow Interrupt... 
50
    out  TIMSK,a            ;...enablen (TOIE0)
51
52
;Calibrationsbyte anpassen
53
    ldi  a,w_osccal
54
    out  OSCCAL,a
55
56
;Ports initialisieren
57
    sbi  DDRB,led_ws        ;LED_Weiß Portpin als Ausgang
58
59
60
    sei                     ;Globale Interruptfreigabe I-Bit (Bit7) im...
61
                            ;...SREG (Status Register) setzen.
62
63
;-----------------------------------------------------------------------------
64
;Hauptprogrammschleife ( HPS )
65
;-----------------------------------------------------------------------------
66
hps:
67
    rjmp hps
68
69
;******************************************************************************
70
;Anfang der Interruptserviceprogramme ( ISR )
71
;******************************************************************************
72
;
73
;******************************************************************************
74
;Timer0 Overflow Interuppt ist aufgetreten. Portpin toggeln
75
;******************************************************************************
76
TIM0_OVF: 
77
    ldi  c,1<<led_ws
78
    in   b,PORTB
79
    eor  b,c
80
    out  PORTB,b
81
    reti                    ;Ruecksprung aus der TIM0_OVF ISR
82
83
84
.exit

Bernd_Stein

von Karl H. (kbuchegg)


Lesenswert?

Bernd Stein schrieb:

> Ohne Takte im Programm zählen zu müssen habe ich auch schon hinter mir.

Und?
Wo liegt jetzt das Problem?

Frequenzzähler an den Toggle-Pin, die Frequenz gemessen, das mal 128 
ergibt die µC-Taktfrequenz.

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

Mann kann auch die Befehlstakte auszählen.

Siehe Datasheet Befehlsübersicht.

Namaste

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Bernd Stein schrieb:
>
>> Ohne Takte im Programm zählen zu müssen habe ich auch schon hinter mir.
>
> Und?
> Wo liegt jetzt das Problem?
>
Ich weiß es ja ebend nicht. Das Programm erzeugt eine Frequenz
von ca. 2,3kHz.
>
> Frequenzzähler an den Toggle-Pin, die Frequenz gemessen, das mal 128
> ergibt die µC-Taktfrequenz.
>
Würde dann ca. 291kHz ergeben. Aber das passt ja vorn und hinten nicht.

Wie kommst Du auf 128 ?

Verstehst Du jetzt mein Problem ?

Bernd_Stein

von Karl H. (kbuchegg)


Lesenswert?

Bernd Stein schrieb:
> Karl Heinz Buchegger schrieb:
>> Bernd Stein schrieb:
>>
>>> Ohne Takte im Programm zählen zu müssen habe ich auch schon hinter mir.
>>
>> Und?
>> Wo liegt jetzt das Problem?
>>
> Ich weiß es ja ebend nicht. Das Programm erzeugt eine Frequenz
> von ca. 2,3kHz.

Vermessen?

> Wie kommst Du auf 128 ?

Weil die ISR alle 256 µC-Takte aufgerufen wird. Bei jedem Aufruf 
wechselt der Pin die Polarität. D.h. 2 Aufrufe sind für 1 'komplette' 
Schwingung notwendig.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
>> Wie kommst Du auf 128 ?
>
> Weil die ISR alle 256 µC-Takte aufgerufen wird. Bei jedem Aufruf
> wechselt der Pin die Polarität. D.h. 2 Aufrufe sind für 1 'komplette'
> Schwingung notwendig.

Dann wäre ich für den Faktor 512.

Schäm dich, Karl Heinz!

=)

von Karl H. (kbuchegg)


Lesenswert?

Magnus Müller schrieb:

> Dann wäre ich für den Faktor 512.
>
> Schäm dich, Karl Heinz!

Bin schon in der Ecke :-)

von R. M. (rmax)


Lesenswert?

Und mit einem Faktor von 512 kommt man bei den gemessenen 2,3kHz auf 
einen internen Takt von knapp 1,2MHz, was mir bei jungfräulicher CLKDIV 
Fuse durchaus plausibel erscheint.

von Christian B. (casandro)


Lesenswert?

Der Grund warum man die Frequenz genau bestimmen will ist übrigen 
relativ einfach. Will man nur eine serielle Schnittstelle betreiben, 
kann es ausreichend und billiger sein, den internen RC-Oszillator 
einfach für ein zwei Temperaturen abzugleichen und dann dazwischen 
einzustellen.

Nicht jeder braucht einen Quarz.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

R. Max schrieb:
> Und mit einem Faktor von 512 kommt man bei den gemessenen 2,3kHz auf
> einen internen Takt von knapp 1,2MHz, was mir bei jungfräulicher CLKDIV
> Fuse durchaus plausibel erscheint.
>
Ja, das macht Sinn und kommt hin.

DANKE an alle die hier mitgewirkt haben und mir somit theoretisch und 
praktisch weitergeholfen haben.

Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Christian Berger schrieb:
> Der Grund warum man die Frequenz genau bestimmen will ist übrigen
> relativ einfach. Will man nur eine serielle Schnittstelle betreiben,
> kann es ausreichend und billiger sein, den internen RC-Oszillator
> einfach für ein zwei Temperaturen abzugleichen und dann dazwischen
> einzustellen.
>
> Nicht jeder braucht einen Quarz.
>
Das sehen die Meisten anders.

Zeig doch mal Dein Programm das das kann.

Um einige Unstimmigkeiten diesbezüglich aus dem Weg zu räumen.


In den meisten Threads ist dies nämlich ein Problem, das nur sinnvoll 
mit einem Quarz gelöst werden kann. Das heißt ohne Quarz zu großer 
Ressourcen verbrauch für diese unbefriedigende Lösung mittels internen 
RC-Oszilator.

Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Bernd Stein schrieb:
>...
>
1
> ...
2
> hps:
3
> ;ca. 161kHz
4
> ;    sbi  PORTB,led_ws       ;2 Takte 
5
> ;    cbi  PORTB,led_ws       ;2 Takte
6
> ;    rjmp hps                ;2 Takte
7
>                              ;Entspricht 6 Takte. 2T High, 4T Low 
8
>                              ;1MHz / 6 = 166,67kHz
9
> ;ca. 81kHz
10
>     ldi  c,1<<led_ws        ;1 Takt
11
>     in   b,PORTB            ;1 Takt
12
>     eor  b,c                ;1 Takt
13
>     out  PORTB,b            ;1 Takt
14
>     rjmp hps                ;2 Takte
15
>                             ;Entspricht halber Periode. *2=ganze Periode
16
>                             ;1Mhz / 12 = 83,33kHz
17
> .exit
18
>
>
Hannes Lux hatte mich unter anderem darauf hingewiesen,
das die Überschriften der beiden Programmteile vertauscht sind
( 81kHz bzw. 161kHz ).

Jetzt ist es richtig

Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Hier mal was einfaches, um bei einen ATtiny13 den internen Takt zu 
ermitteln:
1
 sbi  DDRB,PB2  ;Portpin B2 als Ausgang und auf Low setzen.
2
_TOGGLE:
3
 sbi  PINB,PB2  ;2 Takte, Portpin B2 Toggeln
4
 rjmp _TOGGLE   ;2 Takte
5
6
.EXIT  ;Assemblieren beenden

Nun misst man die Frequenz an diesem Portpin und multipliziert diese mit 
acht. Alle vier Takte, wird der Portpin invertiert, so das die Periode 
acht Takte lang ist. Ein Takt entspicht somit, 8x der gemessenen 
Frequenz, welche die CPU-Taktfrequenz ist.

Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

Mann, Mann, Mann immer diese unnötigen Probleme.

Jetzt hab ich endlich den den AtMega88PA ( von Reichelt ) mit einem 
20MHz-Quarz am laufen und dann muss ich feststellen, das er nur 16MHz 
macht.

Den Quarz mit einer einfachen 74HC00 Testschaltung geprüft, der macht 
seine 20MHz auch wenn das Signal scheisse aussieht.

Macht euer AtMega88PA auch diesen scheiss ?

Beitrag "AtMega88PA mit 20MHz Quarz"


Bernd_Stein

von S. Landolt (Gast)


Lesenswert?

Dass aus einem 20 MHz-Quarz, wie und womit auch immer, 16 MHz 
herauskommen sollen, ist nur sehr schwer vorstellbar.
  Also die Standardfragen: Wie sehen die Fuses des ATmega88PA aus, wie 
wird die Frequenz gemessen, also ohne Programm direkt per CLKO-Pin oder 
per Programm mit "Pin-wackeln"?

von Sempfdazugeber (Gast)


Lesenswert?

Das ist doch wieder ohne den obligatorischen 10:1-Tastkopf gemessen.

Kein Wunder das das Signal da Scheise aussieht.

von Zweitsempft (Gast)


Lesenswert?

Bernd S. schrieb:
> Macht euer AtMega88PA auch diesen scheiss ?

Sempfdazugeber schrieb:
> Kein Wunder das das Signal da Scheise aussieht.

Ausserdem ist die Kurvenform für die Frequenzgenauigkeit nicht
relevant. Auch bekommt man vom Hersteller des Prozessors
keine Garantie für irgendeine genaue Kurvenform.

Typische Anfänger-Korinthenkackerei ...

von Zweitsempft (Gast)


Lesenswert?

Bernd S. schrieb:
> Mann, Mann, Mann immer diese unnötigen Probleme.

Wenn man die Frequenz genau messen will misst man nicht an den
Quarz-Pins direkt sondern benutzt einen Pin des Controllers
um einen Frequenz auszugeben die sich aus dem Takt des
Controllers ableitet. Damit vermeidet man eine Belastung des
Quarzes durch eine externe zusätzliche Last, also dem Tastkopf.

Wenn man wirklich ganz genau messen will dann nicht mit einem
DSO sondern mit einem Frequenzzähler. Ein DSO ist dafür nur
ein Schätzeisen (siehe auch Anzahl der Nachkommastellen).

von HildeK (Gast)


Lesenswert?

Zweitsempft schrieb:
> Wenn man die Frequenz genau messen will misst man nicht an den
> Quarz-Pins direkt sondern benutzt einen Pin des Controllers
> um einen Frequenz auszugeben die sich aus dem Takt des
> Controllers ableitet.

Genau.
Und setzt die Fuse CKOUT und misst am PB0, der dann zum CLKO wird.
Kein Programm, nichts! Dort kommt genau die Oszillatorfrequenz heraus.

von c-hater (Gast)


Lesenswert?

Bernd S. schrieb:

> In den meisten Threads ist dies nämlich ein Problem, das nur sinnvoll
> mit einem Quarz gelöst werden kann.

Nein. Es ist nur AM EINFACHSTEN mit einem Quarz zu lösen.

> Das heißt ohne Quarz zu großer
> Ressourcen verbrauch für diese unbefriedigende Lösung mittels internen
> RC-Oszilator.

Unsinn. Man muss einmal pro Exemplar die Offset der 
Takt/Temperatur-Kennlinie ermitteln, also "Kalibrieren" bei 
Inbetriebnahme. Für die Restlebenszeit genügt es dann, alle paar 
Sekunden mal die Temperatur messen und OSCCAL entsprechend der Kennlinie 
nachzujustieren. Das verbraucht so gut wie keine Rechenzeit und ist bei 
allen AVR8 mit internem Temperatursensor kinderleicht umzusetzen.

Ernsthaft stören tut das nur bei Anwendungen, die den ADC an den Grenzen 
seiner Leistungsfähigkeit betreiben. Da kann der eine eingeschobene 
Zyklus zur Temperaturmessung schon recht störend sein. Für alle anderen 
Anwendungen: Kinderkram, man muss einfach nur halbwegs programmieren 
können.

Genau die Abwesenheit dieser Fähigkeit scheint dein eigentliches Problem 
zu sein...

von tim (Gast)


Lesenswert?

Bernd S. schrieb:
> Wie findet man möglichst genau die Frequenz des internen RC-Oszilators heraus ?

Weltempfänger mit Digitalanzeige und KW-Bereich, f-Offset vorher an 
einem Zeitzeichensender ermitteln.

von tim (Gast)


Lesenswert?

tim schrieb:
> Bernd S. schrieb:
>> Wie findet man möglichst genau die Frequenz des internen RC-Oszilators heraus ?
>
> Weltempfänger mit Digitalanzeige und KW-Bereich, f-Offset vorher an
> einem Zeitzeichensender ermitteln.

Noch bequemer geht das mit einem RTL-SDR-Stick für 7 Euro von ebay und 
der kostenlosen Software SDR# (auch SDRsharp genannt).
Allerdings muss man für Frequenzen unter 25MHz noch einen Upconverter 
mit einem NE602 bauen (ist aber nicht schwer).

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)



Lesenswert?

S. Landolt schrieb:
> Also die Standardfragen: Wie sehen die Fuses des ATmega88PA aus, wie
> wird die Frequenz gemessen, also ohne Programm direkt per CLKO-Pin oder
> per Programm mit "Pin-wackeln"?
>
Bitte hier kurz ein Blick drauf werfen, da sieht man alles zu den 
FUSE-Einstellungen.

Beitrag "AtMega88PA mit 20MHz Quarz"

Mit dem Oszilloskop. Siehe Foto ..NOK.

Ja, mit "Pin-wackeln". Der 3-Zeiler weiter oben hier im Thread. Die ist 
für mich die sicherste Methode um wirklich die Takterate der Befehle 
bestimmen zu können. Habe jedoch einen Programmierfehler gemacht : " 
rjmp  pc-2 ".

rjmp  pc-1 ist richtig.

Ist also alles in Ordnung mit den AtMega88PA's von Reichelt. Nur mit mir 
nicht ;-)

Die anderen "Fotos" sind zusätzlich mit programmierter CLKO-Fuse 
aufgenommen.
Wenn beide Signale ( XTAL1 & CLKO ) "gemessen" werden, kommt leider Mist 
heraus.


Bernd_Stein

von Joachim B. (jar)


Lesenswert?

Bernd S. schrieb:
> Ein funktionierender Assemblercode wäre natürlich das Beste.

kennst du nicht den Beitrag die genaue Sekunde?

https://www.mikrocontroller.net/articles/AVR_-_Die_genaue_Sekunde_/_RTC

von HildeK (Gast)


Lesenswert?

Bei dem Oszillogramm "20MHz_AtMega88PA_CLKO.jpg" müsstest du auch noch 
deine Messanordnung optimieren.
Eigentlich bei allen ...

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

HildeK schrieb:
> Bei dem Oszillogramm "20MHz_AtMega88PA_CLKO.jpg" müsstest du auch noch
> deine Messanordnung optimieren.
> Eigentlich bei allen ...
>
Ist halt Breadboard-Style.

Aber meinst du das verändert die gemessene Frequenz ?

Dann zeig mal deine "Fotos" mit AtMega88PA bei 20MHz.


Joachim B. schrieb:
> kennst du nicht den Beitrag die genaue Sekunde?
>
> https://www.mikrocontroller.net/articles/AVR_-_Die_genaue_Sekunde_/_RTC
>
Hatte mir das mal vor Jahren angeschaut. Jetzt ist es mir erstens zuviel 
zu lesen, zweitens nur Beispiele in C, das ich überhaupt nicht kann.


Bernd_Stein

: Bearbeitet durch User
von Zweitsempft (Gast)


Lesenswert?

HildeK schrieb:
> Bei dem Oszillogramm "20MHz_AtMega88PA_CLKO.jpg" müsstest du auch noch
> deine Messanordnung optimieren.
> Eigentlich bei allen ...

Sehr wohl richtig. Der richtige Umgang mit Messmitteln scheint
noch nicht sehr weit entwickelt zu sein.

Sozusagen (höflicherweise) noch Luft nach oben.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Angehängte Dateien:

Lesenswert?

Hier mal ein C-Beispiel, dass auf einem ATmega 2560 Arduino-Board läuft 
( 16 MHz Quarz ).
Es wird der CTC-Mode 4 des Timer3 ohne Vorteilung benutzt.
Die gemessene Frequenz am PE3-Pin bzw. OC3A bzw. D05, ist mal 2 zu 
nehmen, dann weiß man die CPU-Frequenz.
1
void setup() {
2
  TCCR3A |=  0b01<< COM3A0; // OC3A-Pin Toggeln
3
  TCCR3A &= ~0b11<< WGM30;  // CTC-MODE 4
4
  OCR3A   = 0;              // Hoechste Frequenz
5
  DDRE   |= 1<< PE3;        // OC3A als Compare Match A Ausgang
6
  TCCR3B |=  0b01<< WGM32;  // CTC-MODE 4
7
  TCCR3B |=  0b001<< CS30;  // Vorteiler = 1 und Timer3 starten
8
  TCCR3B &= ~0b110<< CS30;  // Vorteiler = 1 und Timer3 starten
9
}
10
11
void loop() {
12
  // put your main code here, to run repeatedly:
13
14
}
Ob dass Aussehen des Rechtecksignals dem Boardlayout geschuldet ist, 
weiß ich nicht.


Bernd_Stein

: Bearbeitet durch User
von Adam P. (adamap)


Lesenswert?

Bernd S. schrieb:
> Ob dass Aussehen des Rechtecksignals dem Boardlayout geschuldet ist,
> weiß ich nicht.

1) Den alten Beitrag zu kommentieren hätte nicht sein müssen.

2) Ja, ab einer bestimmten Frequenz sieht ein Rechtecksignal so aus, bei 
guter Auflösung. Das Board-Layout und Messvorrichtung spielt natürlich 
auch eine große Rolle dabei.

3) Einige ATmega haben die Option den Takt auf Port B2 (glaub ich) 
ausgeben zu lassen, dann brauchst kein Timer.

4) Wenn dir der Takt so wichtig ist, dass du ihn wissen möchtest, nutze 
einen externen?! Der Interne läuft so wie er halt läuft, +- halt.

5) Du kannst dir auch das *.lss File anschauen und dann die ASM Befehle 
raussuchen die in der Abfolge von einem Pin-Toggle zuständig wären, dann 
im Datenblatt die Takt Zyklen je Befehl raussuchen, summieren, Frequenz 
berechnen... Falls Langeweile besteht.

;)

von Veit D. (devil-elec)


Lesenswert?

Bernd S. schrieb:
>
1
> void setup() {
2
>   TCCR3A |=  0b01<< COM3A0; // OC3A-Pin Toggeln
3
>   TCCR3A &= ~0b11<< WGM30;  // CTC-MODE 4
4
>   OCR3A   = 0;              // Hoechste Frequenz
5
>   DDRE   |= 1<< PE3;        // OC3A als Compare Match A Ausgang
6
>   TCCR3B |=  0b01<< WGM32;  // CTC-MODE 4
7
>   TCCR3B |=  0b001<< CS30;  // Vorteiler = 1 und Timer3 starten
8
>   TCCR3B &= ~0b110<< CS30;  // Vorteiler = 1 und Timer3 starten
9
> }
10
>

Das ist mehr wie Grauenvoll. Bitte nicht nachmachen.

von Norbert (der_norbert)


Lesenswert?

Veit D. schrieb:
> Bitte nicht nachmachen.

Für diejenigen welche es dennoch möchten, bitte unbedingt vorher über 
operator prededence nachlesen.

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Norbert schrieb:
> operator prededence
https://www.urbandictionary.com/define.php?term=Prededence

Aber auch ich würde diese Zeilen auf 4 verkürzen und einfach den 
kompletten Registerwert mit jeweils 1 Zugriff reinschreiben.

Bernd S. schrieb:
> Ob dass Aussehen des Rechtecksignals dem Boardlayout geschuldet ist
Es ist mit hoher Wahrscheinlichkeit auch der Messanordnung geschuldet.

> Die gemessene Frequenz
Was meinst du, wie möglichst genau dein Oszi die Frequenz messen kann?

Bernd S. schrieb:
> um den RC-Oszi möglichst genau auf 1Mhz zu trimmen.
Schon dieser Ansatz ist unsinnig, wie man leicht erkennt, wenn man sich 
mal die Abhängigkeit von Versorgung und Temperatur sowie die 
Langzeitkonstanz des RC-Oszillators anschaut.

Und um den RC-Oszi möglichst genau zu trimmen gibst du am besten eine 
stabile externe Frequenz auf einen Pin und gleichst deinen Oszillator 
ber Software auf diese Frequenz ab.

Fazit: wenn du eine verlässliche Taktfrequenz brauchst, dann schließe 
einen externen Oszillator an. Die sind so winzig (3x2mm) und so billig 
(<50Cent), dass es erst bei sehr großen Stückzahlen was bringt, über 
eine Kalibrierung des RC-Oszillators nachzudenken. Und wenn man das tut, 
braucht man übrigens nicht "möglichst genau" kalibrieren, sondern es 
reicht aus, das "hinreichend genau" zu tun. Denn "möglichst 
genau/viel/weit/hoch/..." ist fast automatisch auch "möglichst teuer".

von Norbert (der_norbert)


Lesenswert?

Lothar M. schrieb:
>> operator prededence
> https://www.urbandictionary.com/define.php?term=Prededence

Gratulation, du hast einen Tipp-Feuler gefunden. ;-)

von Klaus H. (hildek)


Lesenswert?

Auch wenn es ein zweimal aufgewärmter, uralter Thread ist: warum 
schreiben hier alle ein Programm um die Taktfrequenz zu messen?
Ich setze in dem Fall die CKOUT-Fuse und dann kommt an einem Pin die 
Taktfrequenz heraus. Zumindest beim Tinyx5 weiß ich das sicher.
Und beim 2560 habe ich gerade nachgeschaut: dort auch, auf Port E, Bit 
7.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Beim hiesigen Tiny26 gibt es allerdings keine alternative Pinfunktion 
CLKO und auch keine zugehörige CKOUT Fuse mehr...

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Veit D. schrieb:
> Das ist mehr wie Grauenvoll. Bitte nicht nachmachen.
>
Was genau meinst Du ?
Habe das hierher ab ca. Minute 13 gucken:

https://www.youtube.com/watch?v=TMI0dmm7hv4

Klaus H. schrieb:
> ... warum
> schreiben hier alle ein Programm um die Taktfrequenz zu messen?
> Ich setze in dem Fall die CKOUT-Fuse und dann kommt an einem Pin die
> Taktfrequenz heraus...
>
An den FUSES zu manipulieren kann in die Hose gehen und ich glaube die 
Arduino-IDE kann dies gar nicht.

Bernd_Stein

von Norbert (der_norbert)


Lesenswert?

Du möchtest maskieren und gezielt bits auf ›0‹ setzen.
Das ist gut.
Schau dir mal an was:
1
uint8_t x = ~ 3 << 3;
ergibt.

Schau dir dann an was:
1
uint8_t x = ~(3 << 3);
ergibt.

Nimm das was eher deiner Intention entspricht.

von Klaus H. (hildek)


Lesenswert?

Lothar M. schrieb:
> Beim hiesigen Tiny26 gibt es allerdings keine alternative Pinfunktion
> CLKO und auch keine zugehörige CKOUT Fuse mehr...

Ja richtig. Das war der vor fast 12 Jahren angefragte Typ. Jetzt 
kürzlich ging es um den Mega2560.
Es gibt noch einige andere Dinge, die bei dem Tiny26 fehlen (z.B. WDI, 
PCINT-Maske), deshalb nehme ich lieber die neueren Varianten 
Tiny261/461/861, die pinkompatibel sind.

Bernd S. schrieb:
> An den FUSES zu manipulieren kann in die Hose gehen und ich glaube die
> Arduino-IDE kann dies gar nicht.

Nun, über die Arduinodinge weiß ich nichts. Aber die Fuse aktivieren ist 
mit einer brauchbaren IDE nicht wirklich ein Problem.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Klaus H. schrieb:
> Nun, über die Arduinodinge weiß ich nichts. Aber die Fuse aktivieren ist
> mit einer brauchbaren IDE nicht wirklich ein Problem.

Die Arduino IDE nutzt AVRdude.
Damit ist das Fuse setzen nicht das Problem.
Nur dass die IDE kein direktes UI dafür bietet, außer über die Boards 
Menüs.

Klarer:
Fuses setzen funktioniert über das anpassen der boards.local.txt oder 
boards.txt Dateien. Und anschließend über das "Bootloader brennen", 
selbst wenn kein Bootloader mit im Boot ist.

Bernd S. schrieb:
> An den FUSES zu manipulieren kann in die Hose gehen
Ja! (wenn man einen Bock schießt)
Aber ohne gehts auch nicht (immer)

Bernd S. schrieb:
> und ich glaube die
> Arduino-IDE kann dies gar nicht.
Dafür macht sie das aber ganz prächtig!

von Bernd G. (Gast)


Lesenswert?

Mit dem Spektrumanalysator auf den Versorgungspin gehen. Abblock-C 
ausnahmsweise mal sehr klein oder ganz weglassen.

von Joachim B. (jar)


Lesenswert?

Arduino F. schrieb:
> Fuses setzen funktioniert über das anpassen der boards.local.txt oder
> boards.txt Dateien. Und anschließend über das "Bootloader brennen",
> selbst wenn kein Bootloader mit im Boot ist

welcher Bootloader?

Der alte fette der 2k flash kostet?

Wenn ich bedenke das der Optiboot das mit nur 512 Byte schafft und somit 
1,5k vom knappen flash (328p) freischaufelt

von Daniel C. (dan1el)


Lesenswert?

Bernd S. schrieb:

> Das durch ändern des OSCCAL-Wertes sich die Frequenz ändert kann ich
> feststellen. Aber wie ich dann auf die tatsächliche Frequenz des

Ein dünnes Kabel ein oder zwei mal um den Aufbau wickeln und dann über 
einen 50-Ohm-Metallschicht- oder Kohlewiderstand an einen Spectrum 
Analyzer oder ein SDR an den 50-Ohm-Eingang anschließen.
Dann sollte sich die Taktfrequenz direkt im Spektrum ablesen lassen.

Ein RTL-SDR-Stick oder ein MSI2500-MSI001-Klon kosten ca. 10 bis 20€ bei 
der Bucht und sind für solche Messungen äußerst praktisch (Achtung, der 
RTL-SDR-Stick benötigt eventuell noch einen Down-Konverter für 
niedrigere Frequenzen, von da her würde ich den MSI2500-MSI001 
bevorzugen).

Nach meiner Erfahrung ist die Frequenz von internen RC-Oszillatoren 
ziemlich temperaturabhängig.

Ein ATMEGA hat einen CLKO-Pin (Clock-Out). Wenn man ihn in den Fuses 
aktiviert, kann man dort die Schwingfrequenz direkt als TTL-Pegel 
gewinnen (falls mal ein Umstieg auf einen anderen Controller-Typ 
ansteht).

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Joachim B. schrieb:
> welcher Bootloader?

Warum schreibe ich:
Arduino F. schrieb:
> selbst wenn kein Bootloader mit im Boot ist.
?

Damit du das ignorierst?
Ach du hast das noch nicht einmal ignoriert.
Aber dafür null Komma gar nicht verstanden.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Joachim B. schrieb:
> welcher Bootloader?
>
> Der alte fette der 2k flash kostet?
>
> Wenn ich bedenke das der Optiboot das mit nur 512 Byte schafft und somit
> 1,5k vom knappen flash (328p) freischaufelt
>

https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/arduino-bootloader-brennen


Bernd_Stein

: Bearbeitet durch User
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.