Allora... il compllemento a due è semplicissimo:
- Innanzitutto inverti ogni singolo bit
- secondo aggiungi uno (1 oppure 0x01 )al numero che hai trovato
- Fine
Per aiutarti ancora di più: Pubblico su questo portale (prima ancora che sul mio sito
) le librerie che mi sono scritto per gestire l'LM92.Spero possano aiutarti e magari aiutare anche qualcun altro...
il compilatore è C18, ma la parte di gestione dei numeri negativi è la stessa identica...
LM92.h
- Codice: Seleziona tutto
/********************************************************\
* Libreria LM92 *
* *
* FILE HEADER *
* *
* Attua comunicazione con 1 LM92 *
*Funzioni di conversione del dato per essere visualizzato*
* *
* RICHIEDE SEGMConv ( saa1064.h ) *
* *
* Autore: Crestus *
* Data: 23/11/10 *
* *
\********************************************************/
#include <p18cxxx.h>
#ifndef __LM92_H
#define __LM92_H
/***********************************************************\
* Inizializzazione Sensore di temperatura *
\***********************************************************/
void LMInit();
/***********************************************************\
* Lettura Sensore di temperatura *
* Utilizzo: temp2[2] vettore in cui memorizzare i *
* byte che contengono la temperatura *
\***********************************************************/
void LMRead(unsigned char temp2[]);
/***********************************************************\
* Conversione dato grezzo in dato visualizzabile *
* Utilizzo: -temp[2] byte temperatura da LMRead() *
* -visual[5] byte numeri da visualizzare *
* -*neg puntatore che indica se è negativo*
* -kelv scelta se visualizzare i kelvin *
\***********************************************************/
void TPConv ( unsigned char temp[], unsigned char visual[], unsigned char *neg, unsigned char kelv );
#endif
LM92.c
- Codice: Seleziona tutto
/********************************************************\
* Libreria LM92 *
* Attua comunicazione con 1 LM92 *
*Funzioni di conversione del dato per essere visualizzato*
* *
* RICHIEDE SEGMConv ( saa1064.h ) *
* *
* Autore: Crestus *
* Data: 23/11/10 *
* *
* Modifiche future: -Gestione 4 LM92 *
* -Correzione segno Meno *
* -passaggio puntatore o return? *
* -mi serve sapere se negativo? *
\********************************************************/
/* *****************************************************\
* PROPRIETA' del numero restituito dal LM92: *
* gli ultimi 4 bit del 16 bit sono solo e sempre *
* i decimali! *
* li vado a separare per poter lavorare più agevolmente!*
\*******************************************************/
//File INCLUDE
#include <LM92.h>
#include <p18f14k50.h>
#include <saa1064.h>
#include <i2c.h>
/***********************************************************\
* Definizione Indirizzi Periferiche *
* Modificare Gli indirizzi successivi per adattamenti *
\***********************************************************/
#define LMW 0x90 // Indirizzi LM92
#define LMR 0x91 // Indirizzi LM92
#define LMTempReg 0x00 // Indirizzo Byte di controllo
#define LMControlReg 0x01 // Valore Byte di controllo standard LM92 (nessuna Feature abilitata)
/***********************************************************\
* Definizione Funzionali *
* Modificare Se collegamenti diversi dei Display *
\***********************************************************/
#define ZERO 0xE7 // Definizioni Necessarie per operare cotrolli
#define NULLA 0x00 // su cifre da non visualizzare
/***********************************************************\
* Definizione Bit Numero Negativo *
* Modificare se il bit è in posizione differente *
\***********************************************************/
#define TEST_BIT(var, bit) (((var) & (1 << (bit))) != 0)
#define NEGBOOL TEST_BIT(temp16, 12)
/***********************************************************\
* Inizializzazione Sensore di temperatura *
\***********************************************************/
void LMInit() {
OpenI2C(MASTER,SLEW_OFF);
StartI2C();
WriteI2C(LMW);
WriteI2C(LMTempReg);
StopI2C();
CloseI2C();
}
/***********************************************************\
* Lettura Sensore di temperatura *
* Utilizzo: temp2[2] vettore in cui memorizzare i *
* byte che contengono la temperatura *
\***********************************************************/
void LMRead(unsigned char temp2[]) {
OpenI2C(MASTER,SLEW_OFF);
StartI2C();
WriteI2C(LMW);
WriteI2C(LMTempReg);
RestartI2C();
WriteI2C(LMR);
temp2[0]=ReadI2C();
AckI2C();
temp2[1]=ReadI2C();
NotAckI2C();
StopI2C();
CloseI2C();
}
/***********************************************************\
* Conversione dato grezzo in dato visualizzabile *
* Utilizzo: -temp[2] byte temperatura da LMRead() *
* -visual[5] byte numeri da visualizzare *
* -*neg puntatore che indica se è negativo*
* -kelv scelta se visualizzare i kelvin *
\***********************************************************/
void TPConv ( unsigned char temp[], unsigned char visual[], unsigned char *neg, unsigned char kelv ) {
int decimalint, interint, temp16;
unsigned char decimali, interi;
// conversione 2 BYTE --> 1 INT
temp16 = temp[0]; // trasferisco HighByte
temp16 <<= 8; // posiziono
temp16 += temp[1]; //trasferisco LowByte --- oppure temp16 |= temp[1];... + lo stesso...
temp16 >>= 3; // elimino i bit di controllo
// gestione numeri negativi
*neg = 0;
if (NEGBOOL) { //Se è negativo
*neg ++; // mi segno che è negativo
temp16 = ~ temp16; // complemento a due (I)
temp16 ++ ; // complemento a due (II)
}
// Parte Decimali - Parte I
decimalint = temp16 & 0x000F; // gli ultimi 4 bit sono i decimali
decimalint = decimalint * 625; // moltiplicando per il loro Valore
if ( kelv ) // se voglio i KELVIN
decimalint += 1500; //aggiungo il 0,15 ma è tutto moltiplicato per 1000....
decimalint += 50; // Faccio poi arrotondamento (I) - prima cifra decimale
decimali = decimalint / 100; // (II) Al massimo viene 99 --> posso usare un char
//Parte intera
interi = temp16 >> 4; // i restanti Bit sono cifre prima della virgola ( non moltiplicazione)
// tolto il 13° bit e i 4 bit dopo la virgola posso passare ad un char (sempre < 128° C)
if ( decimali > 100) // se ci fosse un riporto dovuto all'arrotondamento
interi ++; // lo aggiungo alle cifre prima della virgola..
if ( kelv ){ // se voglio i KELVIN
interint = interi; // <-- Devo passare agli INT!!
interint += 273;
visual[2] = interint % 10; // UNITA' stesso procedimento
interi = interint / 10; // solo che sfrutto il fatto che la divisione
}
else { // se voglio i GRADI
visual[2] = interi % 10; // UNITA' % mi fornisce il resto dopo la divisione
interi /= 10; // essendo multipli di 10 ottengo il numero dopo la divisione
}
visual[1] = interi % 10; // DECINE di un char non mi restituisce
interi /= 10; // cifre decimali
visual[0] = interi % 10; // CENTINAIA
// Parte Decimali - Parte II
visual[4] = decimali % 10; // seconda cifra decimale
decimali /= 10; // stesso pricipio di sopra
visual[3] = decimali % 10; // prima cifra decimale
// Conversione Per Visualizzazione
SEGMConv (visual, 5); // conversione in stringhe per SAA
if (visual[0] == ZERO) // se le centinaia sono 0
visual[0] = NULLA;
// Aggiunta Segno Meno
if(NEGBOOL)
visual[0] |= 0x08; //provvisorio con il punto....(dp)
// Aggiunta Virgola
visual[2] |= 0x08; // punto della virgola (dp)
}
Nota: Dopo il processo di trascrizione del codice nel linguaggio per il tuo compilatore (che sinceramente non ho letto cosa tu abbia scelto), potrebbe risultare non ottimizzato. Questo perché ho fatto qualche test per il compilatore all'epoca..e questa era l'opzione più ottimizzata che mi venisse in mente...
Il codice è scritto per un PIC18F14K50 - C18 lite.
EDIT: scusate se può sembrar borioso il mio tono... è solo che sono molto fiero di me, fiero di poter materialmente contribuire con qualcosa di reale e di cui vado fiero (penso che ogni programmatore vada fiero del proprio codice... ritenendolo il migliore possibile per raggiungere lo scopo...

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)
