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
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.
> 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 ?
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
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.
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
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.
Mann kann auch die Befehlstakte auszählen. Siehe Datasheet Befehlsübersicht. Namaste
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
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.
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! =)
Magnus Müller schrieb: > Dann wäre ich für den Faktor 512. > > Schäm dich, Karl Heinz! Bin schon in der Ecke :-)
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.
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.
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
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
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
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
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
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"?
Das ist doch wieder ohne den obligatorischen 10:1-Tastkopf gemessen. Kein Wunder das das Signal da Scheise aussieht.
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 ...
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).
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.
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...
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.
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).
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
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
Bei dem Oszillogramm "20MHz_AtMega88PA_CLKO.jpg" müsstest du auch noch deine Messanordnung optimieren. Eigentlich bei allen ...
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
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.
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
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. ;)
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.
Veit D. schrieb: > Bitte nicht nachmachen. Für diejenigen welche es dennoch möchten, bitte unbedingt vorher über operator prededence nachlesen.
:
Bearbeitet durch User
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".
Lothar M. schrieb: >> operator prededence > https://www.urbandictionary.com/define.php?term=Prededence Gratulation, du hast einen Tipp-Feuler gefunden. ;-)
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.
Beim hiesigen Tiny26 gibt es allerdings keine alternative Pinfunktion CLKO und auch keine zugehörige CKOUT Fuse mehr...
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
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.
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.
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!
Mit dem Spektrumanalysator auf den Versorgungspin gehen. Abblock-C ausnahmsweise mal sehr klein oder ganz weglassen.
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
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).
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.