Mi si è presentato un “problema” forse stupido su un PIC della Microchip (Il 16F877A per la precisione): visualizzare sul buffer seriale il risultato di una divisione mostrando anche i decimali. Per programmare i PIC utilizzo l’Hitec-C (dal sito htsoft) e in C la divisione tra interi restituisce soltanto la parte intera del quoziente (esempio: 170 diviso 4 fa 42.5, ma effettuando la divisione in C il quoziente restituito è 42, ma a me serve anche il .5.
Mi sono messo quindi con carta e penna alla mano cercando di poter sfruttare in qualche modo anche l’operatore % che in C serve per restituire il resto di una divisione. Dopo vari tentativi sono giunto ad una piccola conclusione che mostro con un esempio pratico per far capire di cosa parlo:
170 : 4 = 42 (ometto il decimale)
il resto di questa divisione è 2, in C il resto di una divisione si ottiene con l’operazione:
170 % 4 = 2
come sfruttare questo per poter stampare a video il decimale? La parte decimale che manca a questa divisione è 0.5 che rappresenta in effetti il rapporto tra il resto (2) e il divisore (4). Per cui, per poter mostrare il .5 dopo il 42, faccio una semplicissima operazione (la stessa che si fa facendo le divisioni a mano…) : moltiplico dapprima il resto per 10 : 2*10 = 20, dopodichè divido questo per il divisore: 20 : 4 = 5. A questo punto stampo un punto dopo il 42 e quindi il 5… E a video mi appare 42.5 che è il risultato corretto per la divisione, completo dei decimali, ovviamente l’operazione si può ripetere per mostrare anche altri decimali. Il codice utilizzato (e funzionante) è il seguente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include #include __CONFIG (HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT); #include "usart.h" #include "usart.c" void main(void) { unsigned int dividendo=170; unsigned int divisore=4; unsigned int resto=0; usart_init(); // Inizializza la seriale printf("\rDividendo : %d\n",dividendo); printf("\rDivisore : %d\n",divisore); printf("\rDivisione normale : %d\n",dividendo/divisore); resto=dividendo%divisore; printf("\rResto : %d\n",resto); printf("\rDivisione completa: "); printf("%d",dividendo/divisore); if (resto>0) { printf("."); printf("%d",(resto*10)/divisore); } printf ("\n"); } |
La riga 1 include la libreria standard di I/O del C, la 2 le definizioni necessarie per il PIC, segue quindi la stringa di configurazione per il funzionamento del microcontrollore e l’inclusione delle librerie usart (che si trovano nella cartella esempi dell’installazione dell’Hitec-C.
Se non fosse chiaro, sto usando un pic16f877a, collegato sulla seriale tramite il classico adattatore basato sul MAX232 (in questo nostro articolo è presentata un’interfaccia TTL/RS232). Il risultato si può vedere utilizzando l’Hyperterminal con le giuste impostazioni di comunicazione seriale (da impostare nel file usart.h o da lasciare cosi come sono).
L’istruzione Printf non fa altro che stampare (sulla seriale in questo caso) le stringhe. Le sequenze di escape \r e \n sono rispettivamente il ritorno carrello (per stampare all’inizio della riga) e il ritorno a capo. Il %d è lo specificatore di formato per la stampa in una stringa dei numeri interi a base decimale. Il resto delle operazioni effettuate dovrebbe essere chiaro: se il resto della divisione è >0 allora stampo il punto decimale e quindi moltiplico il resto per 10 e lo divido per il divisore e ne stampo quindi il risultato per mostrare il decimale dopo la virgola.
Articoli che potrebbero interessarti
Se desiderate che settorezero continui a rimanere gratuito e fruibile da tutti, non copiate il nostro materiale e segnalateci se qualcuno lo fa

Questo sito e tutto il suo contenuto sono distribuiti sotto la licenza








#1 da MayTs il 6 febbraio 2011
unsigned int dividendo = 170;
unsgined int divisore = 4;
printf(“\rDividendo : %d\n”,dividendo);
printf(“\rDivisore : %d\n”,divisore);
printf(“\rDivisione normale : %f\n”,(float) dividendo/divisore);
#2 da Giovanni Bernardo il 7 febbraio 2011
L’utilizzo del float lo sai che occupa un sacco di cicli macchina? E poi mettiamo che vuoi visualizzare il decimale su un display lcd o 7 segmenti, col float come fai? Il senso di usare questo sistema è appunto quello di avere il decimale disponibile come cifra singola da poter usare facilmente con questi sistemi di visualizzazione. Con una printf il problema non c’è e mi rendo conto che questo era l’esempio meno adatto anche se più immediato.