Newsgroup: it.hobby.elettronica.digitale
Titolo: WinAVR e define

Ciao,
Il CCS per i PIC consente l'uso di funzioni quali:
#define	BTN	PIN_A3
output_high(BTN);
la comodità è che mi posso dimenticare la porta a cui sono associati i 
vari pin. Cambiando assegnazione non devo modificare nulla (tranne 
appunto la define).
WinAVR invece ha definito negli include (es. iom8.h) costanti IMHO senza 
molta utilità:
/* PORTB */
#define PB7	7
#define PB6	6
#define PB5	5
#define PB4	4
#define PB3	3
#define PB2	2
#define PB1	1
#define PB0	0
Perché dico senza utilità? Perché quando devo andare a modificare lo 
stato di un pin uso:
#define	BTN	PB2
PORTB |= _BV(BTN);
che equivale a un semplice _BV(2);
Mi devo ricordare e scrivere esplicitamente la porta relativa. Se 
cambiassi idea e BTN lo associo al PA1, dovrei scorrere tutto il codice 
e cambiare ogni istruzione di I/O.
Quindi ecco le domande:
1) E' possibile usare una macro o una funzione simile a quella CCS per 
evitare questo "problema"?
2) Per quanto l'uso di _BV() sia raccomandato, non fa un po' a botte con 
il discorso sulla portabilità? Cioè, se si volesse davvero mantenerla 
occorrerebbe usare qualcosa del tipo: PORTB |= (1 << BTN), giusto?
3) ultima cosa non strettamente correlata: non ricordo se in questo NG o 
in altri, ma era stato consigliato di usare per le dichiarazioni dei 
tipi di dati uint8_t, uint16_t e così via al posto di unsigned char e 
unsigned int. Quale è (se c'è) il motivo?
Grazie!
Marco / iw2nzm

 unsigned int. Quale č (se c'č) il motivo?
Il motivo č semplice: uint8_t e co. sono tipi ISO e quindi standard.
Inoltre cosa molto pių importante, non č assolutamente vero che unsigned 
char = 8bit o unsigned int = 16bit. Se vuoi un unsigned a 8 bit 
*portabile*, devi usare uint8_t e cosė lo stesso per i 16 e i 32 bit. 
Sui tipi base non c'č nessuna garanzia. L'unica cosa garantita dallo 
standard č che:
sizeof(char) <= sizeof(int) <= sizeof(long)
Nota che sono tutti "minore uguale", potrebbe anche essere tutti lunghi 
32/64 bit!
Assumere che un int sia lungo 16 bit o un char 8, č uno dei principali 
motivi che rendono i programmi *non* portabili.
La cosa migliore č usare i tipi standard, e se essi non sono forniti 
ridefinirli in modo corretto.
Anzi, un modo ancora pių giusto č usare dei tipi personalizzati.
Se devi definire una variabile che servirā per misurare, per esempio, 
una velocitā, positiva e intera, da 0 a 200 km/h, fai:
typedef uint8_t speed_t;
E poi puoi usare speed_t nelle dichiarazioni di tipo. In questo modo, 
quando dovrai cambiare tipo (e succederā, perchč le specifiche 
cambieranno e la velocitā massima sarā di 256 km/h :-) ) non dovrai far 
altro che cambiare un typedef. Questo diminuisce drasticamente la 
probabilitā di inserire bug e aumenta di nuovo la leggibilitā.
Ciao

 probabilità di inserire bug e aumenta di nuovo la leggibilità.
Questo l'ho faccio già da tempo! :)
Grazie per il tempo che hai dedicato alla lunga riposta,
Marco / iw2nzm

 Grazie per il tempo che hai dedicato alla lunga riposta,
Prego, come avrai capito mi piace sempre parlare di queste cose, spero 
solo di non aver detto cose ovvie o noiose :-)
Ciao

 Il motivo è semplice: uint8_t e co. sono tipi ISO e quindi standard.
Sto googlando alla ricerca dell'elenco completo dei tipi ISO... ma con 
chiave di ricerca iso data types o simili non ho trovato granché.
Conosci un link a una tabella riassuntiva?
Thx
Marco / iw2nzm

 Conosci un link a una tabella riassuntiva?
Gli standard ISO mi sa che sono a pagamento, perņ la definizione dei 
tipi standard si trova nel file stdint.h, ecco la descrizione della 
wikipedia:
http://en.wikipedia.org/wiki/Stdint.h
Ciao

 
http://en.wikipedia.org/wiki/Stdint.h
Ottimo, grazie!
Marco / iw2nzm