Hallo Zusammen,
ich bin gerade dabei mit Hilfe des uControllers C167 eine
Geschwindigkeitsregelung fuer einen DC-Reihenschlussmotor aufzubauen.
Die Nut in der Wellenkupplung wird mit einem Sensor abgetastet. Dieses
Sensorsignal wird dann aufbereitet (wie weiss ich auch nicht genau, weil
die entsprechende Elektronik schon vorhanden ist).
Ich greife einen sauberen 3,8 Volt Puls ab. Der Puls wird immer dann
erzeugt wenn die Nut ueber den Sensorkopf faehrt, also genau einmal pro
Umdrehung.
Dieses Signal wandle ich mit einem Optokoppler TLP250 so um, dass es
sich auf das Spannungsniveau meines uControllers bezieht.
Diese Pulse fuehre ich in Pin 3.2 (CAPIN).
Hier beginnt die eigentliche Geschwindigkeitserfassung:
Ich benutze den Hilfstimer T5 (von GPT2). Der Timer befindet sich ganz
normal im Timer Mode und wird mit
getriggert.
Das CAPREL Register ist im "Capture" mode. Es ist so eingestellt, dass
bei steigender Flanke an P3.2 der Inhalt von T5 in CAPREL uebernommen
wird und T5 geloescht wird.
Jetzt kann CAPREL ausgelesen werden (passiert in Interrupt Service
Routine):
Weiterhin frage ich ab ob es einen Timerueberlauf gibt, fuer diesen Fall
wird die Geschwindigkeit gleich null gesetzt und das Naechste Ergebniss
nicht beruecksichtigt.
Funktioniert im stationaeren Zustand ganz gut, aber zu meinem Problem:
Wenn ich den Motor schnell beschleunige, erhalte ich einen sehr hohen
Wert fuer die Geschwindigkeit, T5 wird bei sehr sehr kleinen Werten
gecaptured.
Also selbst wenn der Motor mit vielleicht 500 U/Min laeuft werden mir
uber 10.000 U/Min angezeigt.
Allerdings ist das nur solange er schnell beschleunigt, zum Beispiel mit
Stromregelung und vorgegebenem Stroll Sollwert (1.4A), wenn ich die
Versorgungsspannung stark erhoehe (so auf 70V)
Ich weiss echt nicht mehr weiter, fuer jegliche Anregungen bin ich sehr
dankbar.
Der Code ist angehaengt
1 | /* ----- Hier wird der Stromistwert erfasst ----------------------------- */
|
2 | void ad_int (void) interrupt 0x3F
|
3 | {
|
4 |
|
5 | ADST = 1; /* Conversion start */
|
6 | while(ADBSY) {}; /* wait of end of conversion */
|
7 | current_temp = ADDAT & 0x03FF; /*read result of conversion */
|
8 | current = (24*current + current_temp)/25;
|
9 |
|
10 |
|
11 | if(current > current_desired ) {
|
12 | P7 = 0x0000;
|
13 | //LED15 = 1;
|
14 | }
|
15 |
|
16 | if(current < current_desired ) {
|
17 | P7 = 0x0002;
|
18 | //LED15 = 0;
|
19 |
|
20 | }
|
21 |
|
22 | PWMIR = 0; /* delete interrupt request from PWM */
|
23 |
|
24 | }
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 | /* ----- Interrupt from CAPCOM T0: Erfassen des Geschwindigkeitswertes -------------------------------- */
|
31 | void speedcontrol (void) interrupt 0x10
|
32 | {
|
33 |
|
34 |
|
35 | // Check if Overrun set
|
36 |
|
37 | if(overrun == 1) {
|
38 | speed = 0;
|
39 | overrun = 0;
|
40 | }
|
41 | else if(CAPREL == 0)
|
42 | {}
|
43 | else if(CAPREL < 147)
|
44 | speed = 10000;
|
45 | else {
|
46 | speed = 11718750 / CAPREL; /* set speed 0 ... 10000 */
|
47 | }
|
48 |
|
49 | CC0IR = 0;
|
50 |
|
51 | }
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 | /* ----- Interrupt from T5 (Overrun): speed very low --------------------------------*/
|
59 | void overr (void) interrupt 0x25
|
60 | {
|
61 | overrun = 1;
|
62 |
|
63 | T5IR = 0;
|
64 | }
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 | /******************************************************************************/
|
72 | /* main program */
|
73 | /******************************************************************************/
|
74 |
|
75 | void main (void)
|
76 | {
|
77 |
|
78 | DP71 = 1; /* Define PWM-Output as Push-/Pull-
|
79 | Output, Latch-contents after Reset 0 */
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 | PM0 = 1; /* PWM-Channel 0 Center Aligned Mode */
|
86 | PP0 = 2000; /* Load period register */
|
87 | PIE0 = 1; /* Interrupt enable */
|
88 | PWMIC = 0x005A; /* interrupt Level 6 Group 2 */
|
89 |
|
90 |
|
91 | CCM0 = 0x0006; /* CAPCOM T0 in Compare mode 2 */
|
92 | T0REL = 6241; /* overrun every 1ms */
|
93 | CC0 = 0xFFFF;
|
94 | T01CON = 0x0040; /* CAPCOM T0 run, f_T0 = f_CPU/8 */
|
95 | CC0IC = 0x0061; /* interrupt Level 8 Group 1 */
|
96 |
|
97 |
|
98 | T5CON = 0xD005; /* T5 CAPREL in Capture-mode
|
99 | f_T5 = f_CPU / 128, T5 timer mode
|
100 | T5 counts up, CAPIN (P3.2) triggers
|
101 | at raising edge */
|
102 |
|
103 |
|
104 | T5IC = 0x0067; /* T5 overrun Interrupt, Level 9, Group3 */
|
105 |
|
106 |
|
107 | IEN = 1; /* enable global interrupt */
|
108 |
|
109 | PWMCON0 = PWMCON0 | 0x0003; /* Start of PWM-Timer 0 and 1 */
|
110 |
|
111 |
|
112 | ADCON = 0x0000; /* init AD-Converter in Auto Scan
|
113 | Continuous Mode for Channel 0 */
|
114 |
|
115 | T5R = 1; /* start Timer5 */
|
116 |
|
117 |
|
118 |
|
119 |
|
120 | while(1)
|
121 | {}
|
122 |
|
123 | }
|