Drehzahlmessung eines bürstenlosen Gleichstrommotors mit Hallsensoren mit STM32

Ich habe Schwierigkeiten zu verstehen und eine Lösung zu finden, um die Drehzahl eines BLDC-Motors zu ermitteln. Hier sind die Spezifikationen:

  • 3 Phasen BLDC mit 3x Hallsensoren in 120 Grad, 2 Polpaar

Das folgende Bild zeigt die Situation:

BLDC-Hallsignal

Ich habe im Mikro einen Timer im XOR-Modus eingerichtet. Der PSC ist [19 - 1] und die Zählerperiode ist [10000 - 1], während der Zeitgebertakt 80 MHz beträgt.

Mein Motor hat eine maximale Drehzahl von 3000 U / min.

Der Timer ist im XOR-Modus eingerichtet und generiert bei jedem Übergang ein Ereignis. Gemäß dem STM32F407- Referenzhandbuch setzt in diesem Modus jeder Übergang das CCR-Register auf 0 zurück. Wenn ich dieses Register also sechsmal addiere, sollte ich eine vollständige "elektrische Drehung" oder eine halbe "physikalische Drehung" erhalten, da der Motor zweipolig ist Paare.

Meine Fragen:

A) Ich habe diese Zahlen für den Timer PSC und die Zählerperiode zufällig ausgewählt ... wie werden sich diese Zahlen auf meine Messung auswirken? Kann ich mit diesen Zahlen zB Drehzahlen von 1 bis 3000 U / min abdecken?

B)

Ich habe den folgenden Code in der XOR ISR ... ist dieser Code sinnvoll?

static uint32_t speed = 0;
static uint32_t time = 0;
static int isMeasuring = 0;

void XOR_ISR() {    
     uint8_t state = readHallStateFromGPIO();
    if(state == 0b101 && isMeasuring == 0) {
        time = 0;
        isMeasuring = 1;
        time += TIM4->CCR1;
    } else if(isMeasuring == 1 && state != 0b101) {
        time += TIM4->CCR1;
    } else if(isMeasuring == 1 && state == 0b101) {
        time += TIM4->CCR1;
        speed = time;
        isMeasuring = 0;
    }

Hier die Geschwindigkeit (angenommen, mein Code ist korrekt, sollte Timer-Werte für eine ganze Periode des Hallsensors addieren). Dann werde ich es in Drehzahl umwandeln, indem ich die Frequenz in Zeit umwandele und wegen der Polpaare mit 2 multipliziere.

Ist das richtig?

Ich verstehe nicht, warum Leute so häufig Fragen wie diese stellen, ohne zu sagen, was der Mikrocontroller ist . Bitte OP, es gibt Hunderte verschiedener STM32s mit vielen verschiedenen Peripheriegeräten und ARM-Kernen. Es gibt mindestens 10 verschiedene Produktfamilien (STM32F0, STM32F1, STM32F2, STM32F3, STM32F4, STM32F7, STM32H7, STM32L0, STM32L1, STM32L4)
@jms Ich denke nicht, dass der spezifische Chip hier relevant ist ... da die meisten STM32-Chips dieselbe Timer-Struktur haben und die Frage von OP unabhängig vom Mikrocontroller allgemein bekannt ist.
@ Sean87 Die Timer sind sicher ähnlich, aber es würde nicht schaden, wenn wir tatsächlich wüssten, ob es ein F1 oder L0 oder was auch immer ist. Was kostet es zu erzählen?
@jms Ich stimme dem Kostenfaktor zu :))
@jms Entschuldigung ... es ist das STM32F407-Evaluierungsboard
"In diesem Modus setzt jeder Übergang das CCR-Register auf 0 zurück" Huh, das klingt falsch. Was genau soll es mit dem CCR zu tun haben, wenn damit das Condition Code Register gemeint ist?

Antworten (1)

Ich habe den Code gelesen, und ich habe ein paar Kommentare oder Dinge, die helfen könnten (oder auch nicht).

Ihr Code: Das finde ich noch heraus. Laut dem Bild, das Sie hinzugefügt haben, wird der Zustand niemals sein 0b101? Versuchen Sie, die Zeit zwischen jedem XOR-Impuls zu messen? Ich stelle mir vor, dass dies void XOR_ISR()bei der Aufwärtsflanke jedes Impulses aufgerufen wird. Das sollte ziemlich einfach sein, zum Beispiel:

void XOR_ISR(){
    long time = TIM4->CCR1;
    int rpm = 10/time; // 60 * 1/(time*6)
}

Ich würde einen gleitenden Durchschnittsrechner hinzufügen, um die Messungen auch ein wenig zu glätten.

Obergrenze: Bei einer maximalen Drehzahl von 3000 U/min dreht sich das Rad 3000/60 = 50 Mal pro Sekunde. Da es insgesamt 6 Stangen auf dem Rad gibt, bedeutet dies, dass jedes 6. Mal ISReine volle Drehung genannt wird. Das heißt, es gibt einen Puls 50*6=300 Mal pro Sekunde. Oder alle 1,6 Millisekunden ein Impuls. Da Ihre Zeitschaltuhr mit 80 MHz läuft, zählt sie für jeden Impuls bis 66640. Dadurch erhalten Sie sehr genaue Messwerte bei hohen Geschwindigkeiten.

Untere Grenze: Es könnte jedoch die Messwerte für die niedrigere Geschwindigkeit etwas komplexer machen. Angenommen, das Rad dreht sich mit 10 U / min. Das ergibt 10/60*6=1 Impuls pro Sekunde. Das bedeutet, dass der Timer mit jedem Impuls bis 80 000 000 zählt. Wie @Harry sagte, passt dies nur in eine longVariable mit 5 Bits übrig.

Meine Gedanken: Das Betreiben Ihres Timers mit 80 MHz ist ein wenig übertrieben. Ich würde die Taktfrequenz etwas senken, um die Messung bei sehr niedrigen Drehzahlen etwas robuster zu machen. Aber es hängt alles davon ab, was die kleinste Drehzahl ist, die Sie messen möchten. 10 U/min? 1 U/min? 0,1 U/min? Sie müssen sicherstellen, dass Ihr Zähler nicht überläuft.

Die Genauigkeit: Der größtmögliche Messfehler liegt maximal um die Hälfte der Timer-Periode daneben. Dies ist 1/80 MHz/2 = 6,25 ns. Bei einer maximalen Drehzahl von 3000 U/min führt dies zu einem Fehler von 6,25 ns/1,6 ms = 0,00036 %. Dies ist ein Fehler von 0,11 RPM RPM. Dies ist für die meisten Anwendungen sehr gut.

Ich hoffe das hilft! Und wenn jemand ein Problem mit meiner Mathematik findet, sagt es mir bitte :)

Bearbeiten: Danke @Harry für die Korrektur meiner Late-Night-Mathematik.

log2(80000000) ist ungefähr 26,25, also kann eine lange 32-Bit-Zahl sie tatsächlich mit 5 Bits übrig halten.
Die meisten Controller haben 16-Bit-Zähler ... also würde "66640" überlaufen.