Medición de velocidad de motor CC sin escobillas con sensores Hall con STM32

Tengo dificultades para entender y encontrar una solución para encontrar la velocidad de un motor BLDC. Aquí están las especificaciones:

  • BLDC trifásico con 3 sensores Hall en 120 grados, 2 pares de polos

La siguiente imagen muestra la situación:

Señal de pasillo BLDC

He configurado un temporizador en modo XOR en el micro. El PSC es [19 - 1] y el período del contador es [10000 - 1] mientras que el reloj del temporizador es de 80 MHz.

Mi motor tiene la velocidad máxima de 3000RPM.

El temporizador está configurado en modo XOR y con cada transición genera un evento. De acuerdo con el manual de referencia STM32F407 , en este modo cada transición restablece el registro CCR a 0. Significa que si sumo este registro 6 veces, debería obtener una "rotación eléctrica" ​​completa o la mitad de "rotación física" ya que el motor es de 2 polos pares

Mis preguntas:

A) Acabo de elegir esos números para el temporizador PSC y el período del contador al azar... ¿cómo afectarán estos números a mi medición? por ejemplo con esos numeros puedo cubrir velocidades de 1 a 3000 RPM?

B)

Tengo el siguiente código dentro del XOR ISR... ¿tiene sentido este código?

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;
    }

Aquí, la velocidad (supongamos que mi código es correcto, debería sumar los valores del temporizador para un período completo del sensor de pasillo). Luego lo convertiré a RPM convirtiendo la frecuencia en tiempo y lo multiplicaré por 2 debido a los pares de polos.

¿Es esto correcto?

No entiendo por qué la gente suele publicar preguntas como esta sin decir qué es el microcontrolador . OP, hay cientos de STM32 diferentes, con muchos conjuntos de periféricos y núcleos ARM diferentes. Hay al menos 10 familias de productos diferentes (STM32F0, STM32F1, STM32F2, STM32F3, STM32F4, STM32F7, STM32H7, STM32L0, STM32L1, STM32L4)
@jms No creo que el chip específico sea relevante aquí ... ya que la mayoría de los chips STM32 comparten la misma estructura de temporizador y la pregunta de OP es un conocimiento general, independientemente del microcontrolador.
@ Sean87 Los temporizadores son similares, pero no estaría de más si supiéramos si es F1 o L0 o lo que sea. ¿Qué cuesta contarlo?
@jms Estoy de acuerdo con el factor de costo :))
@jms lo siento... es la placa de evaluación STM32F407
"en este modo, cada transición restablece el registro CCR a 0" Huh, esto suena mal. ¿Qué se supone que debe hacer exactamente con el CCR, suponiendo que esto signifique el Registro de códigos de condición?

Respuestas (1)

Leí el código y tengo algunos comentarios o cosas que podrían ayudar (o no).

Su código: todavía estoy averiguando eso. De acuerdo con la imagen que agregó, ¿el estado nunca será 0b101? ¿Está tratando de medir el tiempo entre cada pulso XORed? Me imagino que void XOR_ISR()se llamará en el borde ascendente de cada pulso. Eso debería ser bastante sencillo, por ejemplo:

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

También agregaría una calculadora de promedio móvil para suavizar un poco las mediciones.

Límite superior: funcionando a un máximo de 3000 RPM, la rueda girará 3000/60 = 50 veces por segundo. Dado que hay un total de 6 polos en la rueda, significa que cada 6 veces ISRocurre una rotación completa. Esto significa que hay un pulso 50*6=300 veces por segundo. O un pulso cada 1,6 milisegundos. Al ver que su reloj temporizador funciona a 80 MHz, contará hasta 66640 por cada pulso. Esto le dará lecturas muy precisas a altas velocidades.

Límite inferior: sin embargo, podría hacer que las lecturas de velocidad más bajas sean un poco más complejas. Digamos que la rueda gira a 10 RPM. Eso da como resultado 10/60*6=1 pulso cada segundo. Esto significa que el temporizador contará hasta 80 000 000 con cada pulso. Como dijo @Harry, esto solo cabrá en una longvariable con 5 bits de sobra.

Mis pensamientos: ejecutar su temporizador a 80 MHz es un poco excesivo. Bajaría un poco la frecuencia del reloj para que la medición sea un poco más robusta a RPM muy bajas. Pero todo depende de cuál sea el RPM más pequeño que quieras medir. 10RPM? 1RPM? 0.1RPM? Deberá asegurarse de que su contador no se desborde.

La precisión: el error de medición más grande que podría tener será un máximo de la mitad del período del temporizador. Esto será 1/80 MHz/2 = 6,25 ns. A un RPM máximo de 3000 RPM, esto dará como resultado un error de 6,25 ns/1,6 ms = 0,00036 %. Este es un error de 0.11RPM RPM. Esto es muy bueno para la mayoría de las aplicaciones.

¡Espero que esto ayude! Y si alguien encuentra un problema con mis matemáticas, por favor dígame :)

Editar: Gracias @Harry por corregir mis matemáticas nocturnas.

log2(80000000) es aproximadamente 26,25, por lo que un número largo de 32 bits puede contenerlo con 5 bits de sobra.
La mayoría de los controladores tienen contadores de 16 bits... por lo que "66640" se desbordaría.