...

Note variabili intere

by user

on
Category: Documents
9

views

Report

Comments

Transcript

Note variabili intere
Note su elaborazione con uso di variabili intere
I sistemi embedded basati su microcontrollore prevedono spesso l'elaborazione di informazioni
provenienti dall'esterno, per esempio sensori.
Per i calcoli si potrebbero usare variabili in virgola mobile che semplificherebbero gli algoritmi di
elaborazione. Tuttavia, questo prevederebbe la necessità di caricare librerie matematiche con notevole
dispendio in termini di occupazione di memoria.
Soprattutto per i microcontrollori, si preferisce creare parti di codice ad hoc che, con uso di variabili
intere (naturalmente gestite dal processore), riescano ugualmente a fornire il risultato voluto.
Vediamo un esempio con cui meglio comprendere questo tipo di problematica.
Si ha uno strumento che fornisce il valore di frequenza di un segnale di ingresso nell'intervallo 1000 –
10000 Hz, con risoluzione di 1 Hz.
Dobbiamo presentare il valore del periodo del segnale di ingresso discutendo i problemi legati al
calcolo e alla risoluzione.
La risoluzione della misura iniziale è pari a 1/10000 = 10-4. Sarà dunque inutile presentare un risultato
che abbia una risoluzione superiore a questa.
In quest'ottica, il periodo potrà variare tra 0.1 ms e 1 ms. La risoluzione 10-4 significa che il risultato
potrà variare al minimo di 0.00001 ms = 0.01 us.
In realtà la risoluzione di 10-4 si ha alla frequenza maggiore, cioè al periodo minore. Per non perderla,
dovremo svolgere i calcoli in modo che il risultato faccia “vedere” gli 0.01 us. Come prova, se la
frequenza è 10 kHz, il periodo sarà 0.1 ms. Se invece si hanno 9999 Hz, il periodo è 0.10001 ms, cioè
dobbiamo poter vedere effettivamente il centesimo di us.
Si intuisce anche che alle frequenze minori questa “precisione” diventa eccessiva, ma se non vogliamo
perdere risoluzione proprio dove lo strumento risolve meglio, nel calcolo del periodo dobbiamo poter
valutale i 10 ns! (ma è solo un'elaborazione).
Sia f la locazione di memoria, a 32 bit, che contiene il valore di frequenza. Dobbiamo calcolare T = 1/f
e sappiamo già che la divisione darebbe risultato nullo trattandosi di divisione intera.
Per avere i 10 ns, bisognerà allora svolgere la divisione intera:
T' = 100000000 / f
in cui occorre, cioè, avere un numeratore 108 volte più grande.
Così, se f = 10000 si ottiene T' = 10000, se f = 9999 si ha T' = 10001 che, rispettivamente,
rappresentano 10000 × 10 ns = 0.1 ms e 10001 × 10 ns = 0.10001 ms, come volevamo.
Supponiamo di dover visualizzare il risultato sull'LCD. La parte di codice che dovremmo
implementare sarà del tipo:
// in f c'è il valore di frequenza
T = 100000000 / f ; // calcola il valore di T con la “precisione” di 10 ns
Write_ndigitsval( T/100000, 1) ; // visualizza la parte intera in ms
WriteChar('.');
Write_ndigitsval( T%100000, 1) ; // visualizza la parte decimale in ms
WriteChar('m'); WriteChar('s');
in modo che sull'LCD appaia il risultato nel formato “#.####ms”. Si noti che il fattore 100000 usato
per la visualizzazione deriva dal 108 usato in quanto l'unità è ms.
È ovvio che quando cerchiamo di adattare un calcolo con valori memorizzati come interi, la
dimensione del dividendo e del divisore non devono superare quella massima che il processore può
gestire.
Nel caso di processore a 32 bit, come ARM7TDMI, per l'esempio qui esaminato dobbiamo usare un
dividendo pari a 10 000 000, ampiamente inferiore al massimo di 4 000 000 000 circa consentito (232).
Fly UP