1 | '------------------------------------------------------------------------------
|
2 | 'name : PID Drehzahlregelung
|
3 | 'copyright : (c) 2009 by Türk Mario
|
4 | 'purpose : Drehzahlregelung von DC-Motoren
|
5 | '
|
6 | 'micro : Mega8
|
7 | '------------------------------------------------------------------------------
|
8 | $regfile = "m8def.dat"
|
9 | $crystal = 8000000
|
10 | $hwstack = 32
|
11 | $swstack = 8
|
12 | $framesize = 24
|
13 | $baud = 38400
|
14 |
|
15 | Config Pinb.0 = Output 'LED
|
16 | Config Pinb.3 = Output 'PWM
|
17 | Config Pinc.0 = Output 'Richtung
|
18 | Config Pinc.1 = Output 'Richtung
|
19 | Config Pind.2 = Input
|
20 | Portd.2 = 1 'Pullup einschalten
|
21 | Config Portd.0 = Input 'Uart Eingang
|
22 | Portd.0 = 1
|
23 |
|
24 | Dim E As Single
|
25 | Dim Esum As Single
|
26 | Dim Ealt As Single
|
27 | Dim Kp As Single
|
28 | Dim Ki As Single
|
29 | Dim Kd As Single
|
30 | Dim Ta As Single
|
31 | Dim Proportionalteil As Single
|
32 | Dim Integralteil As Single
|
33 | Dim Differentialteil As Single
|
34 | Dim Cv As Single
|
35 | Dim Gv As Single
|
36 |
|
37 | Dim Flanken As Integer 'Gezählte Flanken
|
38 | Dim Flankenperturn As Integer 'Anzahl der Flanken pro Umdrehung
|
39 | Dim Umdrehungen As Single
|
40 | Dim Solldrehzahl As Single
|
41 | Dim Maxdrehzahl As Single
|
42 |
|
43 | Dim Befehl As String * 9
|
44 | Dim Bcount As Integer
|
45 | Dim Ar(5) As String * 5
|
46 |
|
47 | Kp = 30
|
48 | Ki = 8
|
49 | Kd = 0.2
|
50 | Ta = 0.04
|
51 | Solldrehzahl = 20
|
52 | Maxdrehzahl = 80
|
53 | Flankenperturn = 30
|
54 |
|
55 | E = 0
|
56 | Esum = 0
|
57 | Ealt = 0
|
58 |
|
59 | Config Int0 = Falling 'Fallende Flanke löst den Interupt aus
|
60 | Enable Interrupts
|
61 | Enable Int0
|
62 | On Int0 Encoder_zaehlen 'Encoder_zaehlen wird im Falle des Interrupts ausgelöst
|
63 |
|
64 |
|
65 | Config Timer1 = Timer , Prescale = 256 'Timer1 führt alle 40ms die Regelung durch
|
66 | On Timer1 Regler
|
67 | Timer1 = 64285 ' 65535 - (8000000/256/Ta) Ta = 25
|
68 | Enable Timer1
|
69 | Start Timer1
|
70 | 'Timer 2 ist für die Motor PWM zuständig
|
71 | Config Timer2 = Pwm , Compare Pwm = Clear Up , Pwm = On , Prescale = 64
|
72 | Ocr2 = 30
|
73 | 'Richtung Vorgeben:
|
74 | Portc.0 = 1
|
75 | Portc.1 = 0
|
76 | 'Motor PWM Starten
|
77 | Enable Timer2
|
78 | Start Timer2
|
79 | $sim
|
80 |
|
81 | Do 'Hauptprogramm
|
82 |
|
83 | Input "" , Befehl
|
84 | Bcount = Split(befehl , Ar(1) , ": ")
|
85 | If Ar(1) = "Kp" Then 'Einstell- und Infomöglichkeiten
|
86 | Kp = Val(ar(2))
|
87 | End If
|
88 | If Ar(1) = "Ki" Then
|
89 | Ki = Val(ar(2))
|
90 | End If
|
91 | If Ar(1) = "Kd" Then
|
92 | Kd = Val(ar(2) )
|
93 | End If
|
94 | If Ar(1) = "soll" Then
|
95 | Solldrehzahl = Val(ar(2))
|
96 | End If
|
97 | If Ar(1) = "max" Then
|
98 | Maxdrehzahl = Val(ar(2))
|
99 | End If
|
100 | If Ar(1) = "rps" Then
|
101 | Print Umdrehungen
|
102 | End If
|
103 | If Ar(1) = "pid" Then
|
104 | Print "Kp=" ; Kp
|
105 | Print "Ki=" ; Ki
|
106 | Print "Kd=" ; Kd
|
107 | End If
|
108 | If Ar(1) = "pwm" Then
|
109 | Print Ocr2
|
110 | End If
|
111 | Loop
|
112 |
|
113 | Encoder_zaehlen: 'Hier werden alle Flanken gezählt
|
114 | Incr Flanken
|
115 | Return
|
116 |
|
117 |
|
118 |
|
119 | Regler: 'Der PID Regler Algorithmus
|
120 | Timer1 = 64285
|
121 | Umdrehungen = Flanken / Ta 'Ermittlung der Umdrehungen pro Sekunde
|
122 | Umdrehungen = Umdrehungen / Flankenperturn
|
123 | Flanken = 0 'Flankenzähler auf null setzen
|
124 |
|
125 | E = Solldrehzahl - Umdrehungen 'Regelabweichung berechnen
|
126 | Esum = Esum + E 'Fehler aufsummieren
|
127 |
|
128 | Proportionalteil = Kp * E 'Proportionalglied berechnen
|
129 |
|
130 | Integralteil = Ki * Ta 'Integralglied berechnen
|
131 | Integralteil = Integralteil * Esum
|
132 |
|
133 | Differentialteil = E - Ealt 'Differentialglied berechnen
|
134 | Differentialteil = Differentialteil / Ta
|
135 | Differentialteil = Differentialteil * Kd
|
136 |
|
137 | Cv = Proportionalteil + Integralteil 'Alle Gliede zusammenfassen
|
138 | Cv = Cv + Differentialteil
|
139 |
|
140 | Gv = Maxdrehzahl / 255 'Übertragen auf PWM Duty Cycle
|
141 | Gv = Gv * Cv
|
142 |
|
143 | If Gv < 0 Then Gv = 0
|
144 | If Gv > 255 Then Gv = 255
|
145 | Ocr2 = Gv 'Motor PWM wird entsprechend angepasst
|
146 |
|
147 |
|
148 |
|
149 | Ealt = E 'Regelfehler merken für den nächsten Durchlauf
|
150 |
|
151 |
|
152 | Return
|