Hallo, ich baue im Moment einen BLDC-Regler mit einem ATmega88 (siehe auch meinen anderen Thread: Beitrag "Probleme mit 30°-Verschiebung bei BLDC-Ansteuerung"). Mein nächstes Ziel ist es, den Stillstand des Motors zu erkennen und dann einen Neuanlauf zu starten. Im Moment ist es wie folgt implementiert: Die 30° Phasenverzögerung zur phasenrichtigen Kommutierung, erzeuge ich mit dem TIMER1 des ATmega88. Läuft dieser über, so soll der Motor neugestartet werden. Problem: Wenn ich den Motor festhalte, fängt der Motor nur zu pfeifen an. Ich vermute mal, dass obwohl der Motor schon stillsteht, durch den Timer noch in den nächsten Kommutierschritt geschaltet wird, dass dann dadurch eine Spannung in den Wicklungen induziert wird, die den Analog-Komparator zum weiterschalten bewegt. Wird eine Stillstands-Detektion für gewöhnlich eingentlich implementiert? Wenn ja, wie macht man das für normalerweise? Schonmal Danke für eure Antworten!
Hier ein Code-Auszug: Relevanter Teil meiner Anlauf-Routine:
1 | ...
|
2 | |
3 | // Einstellung des Timers für Kommutier-Timing
|
4 | TIFR1 = TIFR1; // Flag loeschen |
5 | OCR1A = 0; |
6 | TCNT1 = 0; |
7 | |
8 | ACSR |= (1<<ACIE); // aktiviert Interrupt |
9 | |
10 | sei(); |
11 | |
12 | delay_ms(100); |
13 | |
14 | // Einstellung des Time-Outs
|
15 | TIFR1 |= (1<<ICF1); // Flag löschen |
16 | TIMSK1 |= (1<<ICIE1); |
17 | |
18 | motor_start = 0; |
19 | }
|
Teil der für das Kommutieren zuständig ist:
1 | void next_commutate_state (void) |
2 | {
|
3 | switch (rotor_state) |
4 | {
|
5 | case (0): |
6 | |
7 | AH_ON; |
8 | BL_OFF; |
9 | CL_ON; |
10 | |
11 | SENSE_B; |
12 | rotor_state = 1; |
13 | break; |
14 | |
15 | case (1): |
16 | |
17 | AH_OFF; |
18 | BH_ON; |
19 | CL_ON; |
20 | |
21 | SENSE_A; |
22 | rotor_state = 2; |
23 | break; |
24 | |
25 | case (2): |
26 | |
27 | AL_ON; |
28 | BH_ON; |
29 | CL_OFF; |
30 | |
31 | SENSE_C; |
32 | rotor_state = 3; |
33 | break; |
34 | |
35 | case (3): |
36 | |
37 | AL_ON; |
38 | BH_OFF; |
39 | CH_ON; |
40 | |
41 | SENSE_B; |
42 | rotor_state = 4; |
43 | break; |
44 | |
45 | case (4): |
46 | |
47 | AL_OFF; |
48 | BL_ON; |
49 | CH_ON; |
50 | |
51 | SENSE_A; |
52 | rotor_state = 5; |
53 | break; |
54 | |
55 | case (5): |
56 | |
57 | AH_ON; |
58 | BL_ON; |
59 | CH_OFF; |
60 | |
61 | SENSE_C; |
62 | rotor_state = 0; |
63 | break; |
64 | }
|
ISRs:
1 | |
2 | |
3 | // back EMF zero crossing detection
|
4 | ISR (ANALOG_COMP_vect) |
5 | {
|
6 | |
7 | OCR1A = TCNT1 >> 1; // entspricht 30° |
8 | |
9 | TIFR1 = TIFR1; // Flag löschen |
10 | TCNT1 = 0; |
11 | TIMSK1 |= (1<<OCIE1A); |
12 | |
13 | ACSR &= ~(1<<ACIE); |
14 | }
|
15 | |
16 | |
17 | // Bei Erreichen von OCR1A, kommutieren
|
18 | ISR (TIMER1_COMPA_vect) |
19 | {
|
20 | next_commutate_state(); |
21 | |
22 | TIMSK1 &= ~(1<<OCIE1A); |
23 | ACSR |= (1<<ACI); // Flag löschen |
24 | ACSR |= (1<<ACIE); |
25 | }
|
26 | |
27 | |
28 | // bei Erreichen von ICR1, Motor neustarten
|
29 | ISR (TIMER1_CAPT_vect) |
30 | {
|
31 | motor_start = 1; |
32 | }
|
Teil von main, in der Komponenten initialisiert werden
1 | // Hauptprogramm
|
2 | int main (void) |
3 | {
|
4 | // PWM
|
5 | TCCR0A |= (0<<COM0A1)|(0<<COM0A0)|(0<<COM0B1)|(0<<COM0B0)|(0<<WGM01)|(1<<WGM00); |
6 | TCCR0B |= (0<<WGM02)|(0<<CS02)|(0<<CS01)|(1<<CS00); |
7 | |
8 | TCCR2A |= (0<<COM2A1)|(0<<COM2A0)|(0<<COM2B0)|(0<<COM2B1)|(0<<WGM21)|(1<<WGM20); |
9 | TCCR2B |= (0<<WGM22)|(0<<CS22)|(0<<CS21)|(1<<CS20); |
10 | |
11 | // Analog Comparator
|
12 | ACSR |= (0<<ACD)|(0<<ACBG)|(1<<ACI)|(0<<ACIE)|(0<<ACIC)|(0<<ACIS1)|(0<<ACIS0); |
13 | ADCSRB |= (1<<ACME); // aktiviert Multiplexer |
14 | |
15 | |
16 | // Timer1 einstellen
|
17 | // normal mode; Prescaler auf 8 (Zählertaktdauer = 1us)
|
18 | TCCR1A = 0; |
19 | TCCR1B = (1<<WGM13)|(1<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10); |
20 | |
21 | ICR1 = 0x1000; // entspricht: 1 * 16^3 * 1us = 4,096ms |
22 | |
23 | ...
|
Schaltplan ist eigentlich zu dem von Mikrokopter identisch. Ein Fehler in der Hardware kann man eigentlich ausschließen. Geht ja alles soweit. Ich will ja nur eine Stillstands-Detektion hinzufügen.
Habs glaub ich gelöst... Wenn der Timer-Wert einen bestimmten Wert unterschreitet (und zwar kleiner als der Wert bei der schnellsten Drehzahl ist), dann lös ich einen Neustart aus. Werden für gewöhnlich eigentlich solche Schutzmaßnahmen implementiert (wenn ja, wie sieht das dann grob aus), oder mach ich mir nur einen zu großen Kopf? ;)
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.