Divisione “spicciola” con decimali dopo la virgola in Hitec C su PIC Micro

pic16f877aMi 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
#include <pic.h>
 
__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’Hitech.

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.

Se questo articolo ti è piaciuto, condividilo su un social:
Se l'articolo ti è piaciuto o ti è stato utile, potresti dedicare un minuto a leggere questa pagina, dove ho elencato alcune cose che potrebbero farmi contento? Grazie :)