Hallo,
ich will eine lineare Rampe für einen Schrittmotor implementieren. Als
Endstufe verwende ich das Triple Beast, das über den LPT-Port-Eingang
die
Schritt- und Richtungssignale vom µC erhält. Die Application Note von
Atmel (AVR446) und diese Seite
http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time
habe ich mir dazu schon angesehen.
Mein Problem ist, dass die Berechnung des nächsten Reloadwertes für die
Beschleunigungsrampe nach dieser Formel
zu lange dauert, sodass ich keine genügend hohen Schrittfrequenzen
erzeugen kann. Benötigen würde ich maximal ca. 5 U/s also eine
Schrittfrequenz von 5kHz bei 1000 Mikroschritten pro Umdrehung. Die ISR
muss dazu aber leider mit 10kHz aufgerufen werden, da die Endstufe nur
auf steigende Flanken beim Schrittsignal reagiert und ich in der ISR den
Pin nur toggeln kann.
Die Berechnung dauert momentan laut Simulator ca. 120 µs.
Eine Tabelle mit den Reloadwerten möchte ich nicht verwenden, da später
auch die Beschleunigung variabel sein soll.
Ich programmiere mit Bascom. Bei der Berechnung des nächsten
Reloadwertes habe ich mich an den Beispielcode aus der AVR446 gehalten,
also diese Zeilen:
1 | new_step_delay = srd.step_delay - (((2 * (long)srd.step_delay) + rest)/
|
2 | (4 * srd.accel_count + 1));
|
3 |
|
4 | rest = ((2 * (long)srd.step_delay)+rest)%(4 * srd.accel_count + 1);
|
Hier mein Testprogramm, worin auch µC und dessen Taktfrequenz stehen:
1 | $regfile = "m328def.dat"
|
2 | $crystal = 11059200
|
3 |
|
4 | $hwstack = 64
|
5 | $swstack = 64
|
6 | $framesize = 64
|
7 |
|
8 | Dim C_n_alt As Word
|
9 | Dim C_n_neu As Word
|
10 | Dim Rest As Word
|
11 | Dim 4n_plus1 As Long
|
12 | Dim 2c_n_alt As Long
|
13 | Dim Reload_akt As Word
|
14 | Dim Restsumme As Long
|
15 | Dim N As Long
|
16 | Dim Motor_nr As Byte
|
17 |
|
18 | Dim Constant As Bit
|
19 |
|
20 | Config PORTD = Output
|
21 |
|
22 | Config Timer1 = Timer , Clear Timer = 1 , Prescale = 8
|
23 | Enable Timer1
|
24 | On Timer1 Clk
|
25 | Enable Interrupts
|
26 |
|
27 |
|
28 | Declare Sub Calculate_reload_akt
|
29 |
|
30 |
|
31 | 'Beschleunigung: 1 U/s², 1000 Mikroschritte pro Umdrehung(U)
|
32 | C_n_alt = 29552
|
33 | Reload_akt = 65536 - C_n_alt
|
34 | Timer1 = Reload_akt
|
35 | Rest = 0
|
36 | N = 0
|
37 | Constant = 0
|
38 |
|
39 | Do
|
40 |
|
41 | 'Bis ca. 4,5 U/s beschleunigen und dann Drehungszahl halten
|
42 | If Reload_akt > 65383 Then
|
43 | Constant = 1
|
44 | Reload_akt = 65383
|
45 | End If
|
46 |
|
47 | Loop
|
48 |
|
49 | 'Dauer(laut Simulator): ca. 0,12 ms
|
50 | Sub Calculate_reload_akt
|
51 | 2c_n_alt = 2 * C_n_alt
|
52 | 4n_plus1 = 4 * N
|
53 | 4n_plus1 = 4n_plus1 + 1
|
54 | 2c_n_alt = 2c_n_alt + Rest
|
55 | Restsumme = 2c_n_alt
|
56 | 2c_n_alt = 2c_n_alt / 4n_plus1
|
57 | C_n_neu = C_n_alt - 2c_n_alt
|
58 | Reload_akt = 65536 - C_n_neu
|
59 | Rest = Restsumme Mod 4n_plus1
|
60 | C_n_alt = C_n_neu
|
61 | End Sub
|
62 |
|
63 | Clk:
|
64 | If Constant = 0 Then
|
65 | Incr N
|
66 | Call Calculate_reload_akt
|
67 | End If
|
68 | Timer1 = Reload_akt
|
69 | Toggle Portd.motor_nr
|
70 |
|
71 | Return
|
Ich hoffe mir kann jemand weiterhelfen.