Forum: Mikrocontroller und Digitale Elektronik Frequenz errechnen


von Thomas H. (datatom)


Lesenswert?

Hallo zusammen,

ich habe ein RN-MEGA2560 Mikrocontroller und möchte einen Takt für einen 
Schrittmotor von 400 Hz erzeugen. Der Quarz hat einen Wert von 16000000, 
der Prescaler liegt bei 256 und ich verwende einen 16-Bit Timer den ich 
auf einen Timerwert von 65380 einstelle. Als Ergebnis erhalte ich einen 
Wert von 400,6410256 Hz.

Kann mir bitte jemand mitteilen, ob das Ergebnis falsch oder richtig 
ist.

Vielen Dank für die Hilfe.

von Hmm (Gast)


Lesenswert?

Nein. Ist nicht richtig.

von Vielleicht (Gast)


Lesenswert?

Ja. Ist richtig.

von g457 (Gast)


Lesenswert?

Wenn mich mein Schätzeisen nicht trügt müsste die Frequenz bei 1 liegen 
und nicht bei 400.

von OderDochNicht (Gast)


Lesenswert?

Hmm schrieb:
> Nein. Ist nicht richtig.Beitrag melden Bearbeiten Löschen

Dafür

von hdd (Gast)


Lesenswert?

Müsste stimmen.
Aber wenn du schon einen 16Bit Timer hast, könntest du ja auch einen 
kleineren Prescaler wählen und die 400Hz deutlich besser erreichen, z.B. 
ganz ohne Prescaler und Vorbelegung mit 25.536 oder andere 
Kombinationen...

von ... (Gast)


Lesenswert?

g457 schrieb:
> müsste die Frequenz bei 1 liegen

Bei einem Quarz mit einer Genauigkeit von mindestens 1E-4 müßte die 
Frequenz doch genauer zu bestimmen sein.

von Spess53 (Gast)


Lesenswert?

Hi

Für so etwas benutzt man den CTC-Mode.

Wenn du zu Fuss den Pin Togglen willst muss das für 400 Hz alle 77 
Timertakte erfolgen. Bei dir sind es 155.

MfG Spess

von Rolf Magnus (Gast)


Lesenswert?

Die Antwort hängt davon ab, was du damit meinst:

Thomas Holländer schrieb:
> einen 16-Bit Timer den ich auf einen Timerwert von 65380 einstelle

Wenn du den Timer im CTC-Modus betreibst und diesen Wert als CTC-Wert 
einstellst, ist es falsch. Wenn du den eher ungeschickteren Weg nimmst, 
wirklich den Zählwert des Timers mit dem obigen Wert quasi vorzubelegen, 
ist die Timer-Wartezeit grob 1/400 Sekunde, was so jetzt auch erstmal 
noch nichts mit einem Takt von 400 Hz zu tun hat.

von Thomas H. (datatom)


Lesenswert?

Ja, nein, ich bin verwirrt;-)

Gibt es denn irgendwo ein gutes Tutorial?

von Andreas B. (bitverdreher)


Lesenswert?


von Chris (Gast)


Lesenswert?


von Chris (Gast)


Lesenswert?


von Thomas H. (datatom)


Lesenswert?

Vielen Dank für die Infos.

Ich habe meine Formel überprüft. sie ist richtig:-)

Jetzt habe ich auch noch von einer Bekannten ein Oszilloskop erhalten. 
Mal schauen ob ich damit klar komme, sonst melde ich mich noch einmal.

von Vielleicht (Gast)


Lesenswert?

Thomas Holländer schrieb:
> Ich habe meine Formel überprüft. sie ist richtig:-)

Denk aber dran, daß die Frequenz, mit dem der Timer seinen TOP Wert 
erreicht, nicht gleich der Frequenz des Signals für den Stepper sein 
muß.

von Thomas H. (datatom)


Lesenswert?

Was meinst du damit?

Ich habe folgende Schrittmotorsteuerung:

http://de.nanotec.com/schrittmotor_steuerungen_smc11.html

und zwar den SMC11, der standartmäßig auf 1/8 Schritt steht.

Als Schrittmotor habe ich:

SPG1518M0504-102

http://de.nanotec.com/schrittmotor_lowcost.html

Die Eingangsspannung für die Schrittmotorensteuerung beträgt 12 V.

von Vielleicht (Gast)


Lesenswert?

Vielleicht schrieb:
> Denk aber dran, daß die Frequenz, mit dem der Timer seinen TOP Wert
> erreicht, nicht gleich der Frequenz des Signals für den Stepper sein
> muß.

Thomas Holländer schrieb:
> Was meinst du damit?

ca. 400Hz ist die Frequenz die du ausgerechnet hast. Du schreibst aber 
nicht, wie du daraus ein Signal auf dem µC Pin machst. per ISR, per Pin 
toggle, per PWM, per sonstigem Programm und wie sieht das aus ??? Und 
weiter vom Pin geht es durch einen Treiber zum Stepper. All das kann 
Einfluß auf den Steppertakt haben. Da die Infos nicht vorliegen, können 
wir nicht wissen, ob die 400Hz auch am Stepper ankommen.

von Thomas H. (datatom)


Lesenswert?

Hier mal das Bascom-Programm:
1
' Stepper Testprogram
2
3
$prog , 255 , &B11011001,
4
$regfile = "m2560def.dat"
5
$hwstack = 82                                               '80
6
$framesize = 68                                             ' 64
7
$swstack = 68                                               '44
8
9
10
$crystal = 16000000                                         'Quarzfrequenz
11
$baud = 19200
12
13
14
Config Pind.5 = Output
15
Led Alias Portd.5
16
17
Config Pinc.0 = Output                                      ' Stiftleiste JP 2; Pin 3; PC0
18
Stepper1_reset Alias Portc.0
19
20
Config Pinc.1 = Output                                      ' Stiftleiste JP 2; Pin 4; PC1
21
Stepper1_direction Alias Portc.1
22
23
Config Pinc.2 = Output                                      ' Stiftleiste JP 2, Pin 5; PC2
24
Stepper1_enable Alias Pinc.2
25
26
Config Pinc.3 = Output                                      ' Stiftleiste JP 2, Pin 6; PC3
27
Stepper1_step Alias Pinc.3
28
29
Echo Off
30
31
Led = 0                                                     ' LED einschalten
32
33
34
Stepper1_direction = 0                                      
35
Stepper1_enable = 0                                        
36
37
38
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
39
Config Timer1 = Timer , Prescale = 64                     
40
Enable Timer1
41
On Timer1 Timer_irq
42
Enable Interrupts
43
Timer1 = 64911
44
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
45
46
  Do
47
      Toggle Led
48
      Waitms 500
49
  Loop
50
51
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
52
End
53
54
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
55
Timer_irq:
56
Timer1 = 64911
57
Stepper1_step = 0 : Waitus 1 : Stepper1_step = 1            
58
Return

Das Signal wird über Pin 6 an die Schrittmotorsteuerung weiter gegeben. 
Von da aus gehts zum Schrittmotor.

Ich hoffe die Angaben reichen jetzt:-)

von Spess53 (Gast)


Lesenswert?

Hi

>Timer1 = 64911
>Stepper1_step = 0 : Waitus 1 : Stepper1_step = 1

Handbuch nicht gelesen:

Pulsbreite > 2 μs.

MfG Spess

von Thomas H. (datatom)


Lesenswert?

Also so:

Timer1 = 64911
Stepper1_step = 0 : Waitus 3 : Stepper1_step = 1 : Waitus 3

Damit ist die Pulspause und Pulsbreits > 2 µs.

Oder?

von Spess53 (Gast)


Lesenswert?

Hi

>Also so:

>Timer1 = 64911
>Stepper1_step = 0 : Waitus 3 : Stepper1_step = 1

>oder?

Das Timer-Vorladen bleibt trotzdem Müll. Selbst BASCOM kennt CTC.

MfG Spess

von Thomas H. (datatom)


Lesenswert?

1. Gibt es zu CTC ein Tutorial?
2. Welche Nachteile hat meine Variante?

von Simon K. (simon) Benutzerseite


Lesenswert?

Thomas Holländer schrieb:
> 1. Gibt es zu CTC ein Tutorial?

Brauch man denn für alles heute ein Tutorial?

von Vielleicht (Gast)


Lesenswert?

Thomas Holländer schrieb:
> 2. Welche Nachteile hat meine Variante?

Die ISR kann man sich sparen. Die low Zeit des Signals stellst du über 
die Krücke WAITMS und das auch noch im Interrupt ein.
1
COMPARE1A = 2499
2
CONFIG TIMER1 = TIMER , COMPARE A = TOGGLE , CLEAR TIMER = 1 , PRESCALE = 8

Damit kann man den CTC mode einstellen. Der Timer läuft bis zum 
COMPARE1A Wert und fängt dann wieder bei 0 an. Bei dieser Einstellung 
und dem 16MHz Systemtakt tut er das mit 800Hz. Durch das "COMPARE A = 
TOGGLE", schaltet er den OC1A Pin des µC immer um und du erhältst ein 
400Hz Rechteck mit 50% Tastverhältnis.

Damit bist du allerdings auf den OC1A Pin des µC festgelegt und 
müßtest die Verkabelung entsprechend anpassen. (Dieser CONFIG TIMER 
Befehl konfiguriert sogar den OC1A Pin auf OUTPUT - muß also nicht 
explizit als Output eingestellt werden.

Zugegebenermaßen ist der CONFIG TIMER BASCOM Befehl nicht gut 
dokumentiert und ich bin hinter die Funktion nur mit Datenblatt des µC 
und Simulator gekommen.

Es gibt je nach Anforderung viele Möglichkeiten das Signal zu erzeugen. 
Komplett kann man das nur dem Datenblatt entnehmen.

von Thomas H. (datatom)


Lesenswert?

Ich nehme jetzt den "normalen" Timer und habe folgendes Programm 
erstellt, womit ich erfolgreich einen Schrittmotor drehen lassen kann.
1
' Stepper Testprogram
2
3
$prog , 255 , &B11011001,
4
$regfile = "m2560def.dat"
5
$hwstack = 82                                               '80
6
$framesize = 68                                             ' 64
7
$swstack = 68                                               '44
8
9
10
$crystal = 16000000                                         'Quarzfrequenz
11
$baud = 19200
12
13
14
Config Pind.5 = Output
15
Led Alias Portd.5
16
17
Config Pinc.0 = Output                                      ' Stiftleiste JP 2; Pin 3; PC0
18
Stepper1_reset Alias Portc.0
19
20
Config Pinc.1 = Output                                      ' Stiftleiste JP 2; Pin 4; PC1
21
Stepper1_direction Alias Portc.1
22
23
Config Pinc.2 = Output                                      ' Stiftleiste JP 2, Pin 5; PC2
24
Stepper1_enable Alias Pinc.2
25
26
Config Pinc.3 = Output                                      ' Stiftleiste JP 2, Pin 6; PC3
27
Stepper1_step Alias Pinc.3
28
29
Config Pinb.7 = Output
30
Takt Alias Pinb.7
31
32
Dim I1 As Integer
33
Dim Takt_hz As Long
34
35
Echo Off
36
37
Led = 0                                                     ' LED einschalten
38
39
40
Do
41
   Toggle Led
42
   Waitms 75
43
   I1 = I1 + 1
44
Loop Until I1 = 20
45
46
Wait 5
47
48
Stepper1_direction = 0                                      ' Stepper1_direction = off (0 Volt); Stiftleiste JP 2; Pin 4; PC1
49
Stepper1_enable = 0                                         ' Stepper1_enable    = off (0 Volt); Stiftleiste JP 2, Pin 5; PC2
50
51
Takt_hz = 64147
52
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
53
54
On Timer1 Timer_irq
55
Enable Timer1
56
Config Timer1 = Timer , Prescale = 64                       ' Stiftleiste JP 1; Pin 26
57
Enable Interrupts
58
' Timer1 = 60536                                              ' 50 Hz     64147
59
Timer1 = Takt_hz
60
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
61
62
  Do
63
      Toggle Led
64
      Wait 5
65
      Takt_hz = 63036                                       ' 100 Hz
66
67
      Toggle Led
68
      Wait 5
69
      Takt_hz = 63869                                       ' 150 Hz
70
71
      Toggle Led
72
      Wait 5
73
      Takt_hz = 64286                                       ' 200 Hz
74
75
      Toggle Led
76
      Wait 5
77
      Takt_hz = 64536                                       ' 250 Hz
78
79
      Toggle Led
80
      Wait 5
81
      Takt_hz = 64703                                       ' 300 Hz
82
83
  Loop
84
85
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
86
End
87
88
'Dies ist der Programmteil, der in dem von ihnen gewählten
89
'Intervall aufgerufen wird
90
Timer_irq:
91
Timer1 = Takt_hz
92
93
Stepper1_step = 0 : Waitus 3 : Stepper1_step = 1 : Waitus 3 ' Stiftleiste JP 2, Pin 6
94
95
Return

Laut meinen Berechnungen steigert sich alle 5 Sekunden die Frequenz um 
50 Hz, beginnend ab 50 Hz. Das funktioniert auch, allerdings zeigt mein 
Frequenzmessgerät andere Hz-Werte an:

Errechnet Timer1:         Messgerät:

 50 Hz                     50 Hz
100 Hz                     75 Hz
150 Hz                    100 Hz
200 Hz                    125 Hz
250 Hz                    150 Hz
300 Hz                    175 Hz

Wie kommt es zu den Unterschieden? Geht des Messgerät 
(http://www.conrad.de/ce/de/product/124403/VOLTCRAFT-VC170-Digital-Multimeter-VC100-Serie-4000-Counts-CAT-III-250-V/1101010&ref=list)
falsch oder habe ich mich bei den Timerwerten verrechnet?

Vielen Dank für die Hilfe.

von Karl H. (kbuchegg)


Lesenswert?

Wie hast du sie denn errechnet?

: Wiederhergestellt durch User
von Thomas H. (datatom)


Lesenswert?

Die Berechnung erfolgte nach folgender Formel:
Ich hoffe die Formel stimmt.

von Troll (Gast)


Lesenswert?

Simon K. schrieb:
> Brauch man denn für alles heute ein Tutorial?

Zu jedem Mist ein Tutorial ist wohl etwas übertrieben. Ein vernünftiger 
Quellcodegenerierungsassistent sollte es auch tun ;-)

Früher (tm) musste man sich durch Tabellen und Erläuterungen im 
Datenblatt durchwühlen :-(

von Karl H. (kbuchegg)


Lesenswert?

Thomas Holländer schrieb:
> Die Berechnung erfolgte nach folgender Formel:

Die Formel hab ich jetzt nicht kontrolliert. Ich hab deine Werte 
nachgerechnet und sie scheinen zu stimmen.

Trotzdem ist der ganze Ansatz verquert.
Nimm den CTC Modus und Toggle in der ISR den Pin. Dann brauchst du auch 
solche Hacks mit der Wartezeit in der ISR nicht um einen Puls zu formen.

Dein Messgerät ist sicherlich nicht 'zu ungenau'. 200Hz muss jeder 
Frequenzmesser problemlos messen können und ausserdem sind die 
gemessenen Werte zu schön im 25Hz Raster, als das das Zufall sein 
könnte.

Was ich mir höchtens vorstellen könnte ist, dass dein Messgerät mit den 
3 µs Pulsen nicht glücklich ist.

Daher. mach es richtig. In der Timer ISR den Pin Toggeln, so dass es 
immer 2 Aufrufe braucht, um 1 komplette 'Schwingung' fertig zu stellen.

Und anstatt dem #*&$@ Timer vorladen, nimmst du den CTC Modus und gut 
ists. Dann braucht man auch nicht mehr so bescheuert von 65535 aus 
runterrechnen, sondern weist einfach dem OCR1A Register den neuen Wert 
zu und schon 'tickt' der Timer mit der neuen Frequenz. Genau dafür hat 
ATmel den CTC Modus eingebaut .... damit man ihn benutzt, wenn er 
angebracht ist. Und deine Anwendung ist ein Paradebeispiel für 
'angebracht sein'. Wenn nicht hier, wo sollte der CTC sonst angebracht 
sein?

von Karl H. (kbuchegg)


Lesenswert?

Troll schrieb:
> Simon K. schrieb:
>> Brauch man denn für alles heute ein Tutorial?
>
> Zu jedem Mist ein Tutorial ist wohl etwas übertrieben. Ein vernünftiger
> Quellcodegenerierungsassistent sollte es auch tun ;-)
>
> Früher (tm) musste man sich durch Tabellen und Erläuterungen im
> Datenblatt durchwühlen :-(

Das ist auch heute noch vernünftig anstelle des Assistenten. Die 3 
Einstellungen raussuchen dauert keine 2 Minuten. Gegenüber dem Rest der 
Entwicklungszeit sind das Peanuts, die komplett untergehen.

von Thomas H. (datatom)


Lesenswert?

Den CTC-Modus hat auch schon ein anderer user erwähnt. Ich bräuchte mal 
ein Beispiel in Bascom oder ein Tutorial wo es erklärt wird.

von Karl H. (kbuchegg)


Lesenswert?

Es ist wirklich ganz einfach.
Du konfigurierst den Timer auf CTC

Config Timer1 = Timer , Prescale = 64, Clear_Timer = 1

und hängst eine ISR an den Compare Match vom OC1A

On OC1A ToggleStep


und in der ISR Funktion toggelst du einfach den Pin

ToggleStep:
  Toggle Stepper1_step
  return


Jetzt weist du an OCR1A einfach einen Wert zu.
  OCR1A = 2000

der Timer zählt dann von 0 bis 2000 und wenn die 2000 erreicht sind, 
passieren 2 Dinge
* der Timer beginnt wieder bei 0 zu zählen
* da es sich hier um einen Compare Match handelt (also eine 
Übereinstimmung
  des Zählregisters mit dem OCR1A Register), wird die zugehörige ISR
  aufgerufen.

Bumm. Nicht mehr lange rumrechnen. Wenn du 258 Timer Schritte brauchst, 
dann schreibst du auch 257 (258-1) in das OCR1A Register
Kein Timer Vorladen mehr. Der Timer beginnt ganz von alleine wieder bei 
0 zu zählen.

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.