Newsgroup: it.hobby.elettronica.digitale
Titolo: da 2 variabili char a 1 long e viceversa

come posso fare in C a trasformare 1 long in 2 char e viceversa?
lo scopo e memorizzare in eeprom l'intero contenuto della long in due celle
distinte
grazie anticipatamente
(ps esiste una guida scaricabile, o un sito, con questo genere di contenuti?
io ho cercato ma non trovo nulla di questo tipo)


shift a destra di 8 bit ( >> ) o divisione per 256 per il byte alto
modulo per 256 ( % ) o and bit a bit  ( & ) con 0xff o ancora cast a 
char per il byte basso
oppure
union l_or_c_t {
	long l;
	char c[2];
};
union l_or_c_ t lorc;
lorc.l = 0xaa55;
lorc.c[0] e lorc.c[1]
permettono di accedere separatamente ai due byte del long.
quest'ultima soluzione con un attento uso di typedef e macro potrebbe 
essere totalmente trasparente al programmatore ed al compilatore
PERO':
sicuro che il long e' a 16 bit ? tipicamente e' l' int ad essere a 16 
bit mentre il long potrebbe essere a 32 ( il tutto e' comunque scalabile  )
a seconda del compilatore le varie forme possono essere variamente 
ottimizzate.
potrebbero esserci dei piccoli problemi se i long e/o i char sono signed 
da verificare sul campo ( o sul compilatore :-) ), probabilmente 
conviene passare preventivamente tramite un tipo unsigned


Visto che il contenuto da salvare potrebbe essere arbitrario, io ti 
suggerisco una funzione generica che salva in EEPROM semplicemente tutto 
quello che gli passi, un esempio potrebbe essere questa:
void eeprom_writebuf(unsigned char addr, void *_data, unsigned char len)
{
	unsigned char *data = (unsigned char *)_data;
	while (len--)
		eeprom_write(addr++, *data++);
}
e per la rilettura:
void eeprom_readbuf(unsigned char addr, void *_data, unsigned char len)
{
	unsigned char *data = (unsigned char *)_data;
	while (len--)
		*data++ = eeprom_read(addr++);
}
Attenzione che queste funzioni non fanno nessun tipo di controllo sul 
buon fine dell'operazione e sulla legalitą degli indirizzi passati.
Per l'uso, fai cosģ:
long dato;
long datoletto;
// scrittura in EEPROM del dato
eeprom_writebuf(0, &dato, sizeof(dato));
//rileggo da EEPROM in datoletto
eeprom_readbuf(0, &datoletto, sizeof(datoletto));
Ciao

 mentre il long potrebbe essere a 32 ( il tutto e' comunque scalabile  )
ah giusto... ma non c'è problema.. 16 bit bastano e avanzano.. eventualmente 
le variabili che ora sono long diventeranno int
grazie ancora!
ps grazie anche a francesco (risparmio un post) 

 sperando che non si offenda :-)
Nono, risparmiare è sempre un bene ;-)

tutto ok..
mi manca solo una cosa:
se ho un valore.. ipotizziamo int.. di 16 bit
come faccio a mettere in un'altra variabile solo gli 8 bit meno
significativi?
ho pensato a una operazione di AND con un valore tipo 0x00FF... è una
soluzione valida?


e' LA soluzione,
in realta' dovrebbe bastare il semplice cast
c = (char) i;
o addirittura:
c = i;
le varie incarnazioni dei compilatori C in ogni caso potrebbero 
inc.....rsi un pochino, un warning del tipo 'la variabile destinazione 
ha una dimensione piu' piccola della sorgente' sarebbe d'obbligo.
da notare un paio di cose:
anche con le soluzioni precedenti permettono di recuperare solo il byte 
basso.
a seconda della qualita' del compilatore le varie possibilita' possono 
generare codice piu' o meno ottimizzato e prestante