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.