Domanda

Sto lavorando sul firmware di un dispositivo che utilizza un 8bit MCU (8051 architettura). Sto usando SDCC (Small Device C Compiler). Ho una funzione che uso per impostare la velocità di un motore passo-passo che il mio circuito sta guidando. La velocità viene impostata caricando un valore desiderato nel registro di ricaricamento di un timer. Ho una variabile, MotorSpeed ??che è nell'intervallo da 0 a 1200 che rappresenta impulsi al secondo al motore. La mia funzione per convertire MotorSpeed ??al valore a 16 bit di ricarica corretto è mostrato sotto. So che le operazioni in virgola flottante sono piuttosto lenti e mi chiedo se c'è un modo più veloce di fare questo ...

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;
}
È stato utile?

Soluzione

Se ho capito bene cosa sta succedendo Si vuole calcolare l'espressione

MaxInt - 1000000/MotorSpeed

dove MotorSpeed ??è una forma numero 0 1200 ed rappresenta il numero di impulsi al secondo.

Se il proprio compilatore aritmetica in virgola mobile deve supportare integer divisione. Perché non provare questo. Se la velocità è> 15 non c'è nessun problema, ma per velocità nel range da 0 a 15 il risultato è negativo. Ciò significa che è semplicemente impossibile generare impulsi con frequenza inferiore a 16 Hz, se il contatore è 16 bit ampia ed è incrementato al tasso di 1MHz. Avete un prescaler aggiuntivo che permette di ridurre la frequenza degli incrementi? (Non so 8051).

Altri suggerimenti

Il modo classico è quello di utilizzare virgola fissa, scalando prima divisione, e fare tutto come intero.

j = (MotorSpeed * 65536) / 1200;

Questo richiede ancora divisione reale (da 1200), ma almeno è tutto intero. La scala deve essere molto veloce, dal momento che è possibile implementare con un turno di lavoro.

punto di svolgimento ha ragione su fisso.

Ho scritto una libreria fisso per SDCC sul 8051 che utilizza 32 numeri di bit. Semplicemente determinare ciò che la precisione che volete nel vostro frazioni e applicare il passaggio appropriato ai valori.

Per esempio, la mia libreria punto fisso utilizza 2 byte per lo spazio frazionata.

Quindi, ogni numero x viene rappresentato come x * 65535. È possibile utilizzare il normale lunga addizione e subraction firmato.

Per la moltiplicazione e la divisione è necessario per regolare l'offset. Semplice moltiplicazione darebbe (x * 65535) * (y * 65535). Basta rompere e fattore di fuori l'offset per ogni parte dei numeri e aggiungere tutti in su.

Basta rompere il tuo numero di punto fisso in byte o 16 bit interi e lavorare su di essi in pezzi.

Date un'occhiata a questo articolo sul embedded.com .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top