¿Cuál es la manera más rápida de hacer una división en C para microcontroladores de 8 bits?

StackOverflow https://stackoverflow.com/questions/2744925

  •  02-10-2019
  •  | 
  •  

Pregunta

Estoy trabajando en el firmware de un dispositivo que utiliza un MCU de 8 bits (8051 arquitectura). Estoy usando SDCC (pequeño dispositivo compilador de C). Tengo una función que utilizo para ajustar la velocidad de un motor paso a paso que mi circuito está conduciendo. La velocidad se ajusta mediante la carga de un valor deseado en el registro de recarga para un temporizador. Tengo una variable, MotorSpeed ??que está en el rango de 0 a 1200, que representa impulsos por segundo al motor. Mi función para convertir MotorSpeed ??al valor de 16 bits de recarga correcta se muestra a continuación. Sé que las operaciones de punto flotante son bastante lento y me pregunto si hay una manera más rápida de hacer esto ...

void SetSpeed()
{
    float t = MotorSpeed;
    unsigned int j = 0;
    t = 1/t ;
    t = t / 0.000001;
    j = MaxInt - t;
    TMR3RL = j;      // Set reload register for desired freq
    return;
}
¿Fue útil?

Solución

Si he entendido bien lo que está pasando Desea calcular la expresión

MaxInt - 1000000/MotorSpeed

donde MotorSpeed ??es una forma números del 0 al 1200 y representa el número de impulsos por segundo.

Si Sus soportes compilador flotante aritmética de punto que debe soportar número entero división. ¿Por qué no tratar de eso. Si la velocidad es> 15 no hay ningún problema, pero para velocidades en el rango de 0 a 15 el resultado es negativo. Esto significa que es simplemente imposible para generar pulsos con una frecuencia inferior a 16 Hz, si el contador es de 16 bits de ancho y se incrementa a una velocidad de 1 MHz. ¿Tiene un pre-escalador adicional que permite reducir la frecuencia de incrementos? (No sé 8051).

Otros consejos

La forma clásica es utilizar de punto fijo, mediante la ampliación antes de dividir, y haciéndolo todo como entero.

j = (MotorSpeed * 65536) / 1200;

Esto todavía requiere división real (por 1200), pero al menos es todo número entero. El escalado debe ser muy rápido, ya que es posible implementar el uso de un turno de trabajo.

punto de desenrollado está razón sobre fijo.

Me escribió una biblioteca para SDCC fijo en el 8051 que utiliza números de 32 bits. Basta con determinar qué precisión se desea en sus fracciones y aplicar el cambio adecuado a los valores.

Por ejemplo, la biblioteca de mi punto fijo utiliza 2 bytes para el espacio fraccionada.

Así que cada número x se representa como x * 65535. Puede usar la normalidad Además larga firmado y subraction.

Para la multiplicación y división que necesita para adaptar el equivalente. simple multiplicación daría (x * 65535) * (y * 65535). Sólo romper y el factor cabo el desplazamiento para cada parte de los números y añadir todo.

Sólo romper su número de punto fijo en bytes o 16 bits enteros y trabajar en ellos en pedazos.

Tome un vistazo a este artículo en embedded.com .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top