pins_arduino.h

Salve a tutti,
Ho iniziato a leggere il tutorial sulla programmazione dei microcontrollori ATMEL contenuto in una rivista e per curiosità personale stavo guardando il file pins_arduino.h (contenuto nella cartella hardware dell'IDE) per capire come dai nomi delle porte del micro si passi, grazie all'IDE, ad indicare solo il numero corrispondente al PIN.
Qualcuno mi sa spiegare le parti che costituiscono il file???

P.S.: Non posso allegare il file perchè è troppo lungo...

Grazie mille

Davide

ciao Davide

Non capisco, dici che il file é troppo grande per incollarlo ma vorresti averlo spiegato?

Ciao Uwe

Il file contiene la mappatura che permette di associare il numero o il nome del pin al relativo registro o porta interna del microcontrollore.
La mappatura è specifica, infatti esiste per ogni modello di microcontrollore un suo file pin header.

Per capirne il funzionamento puoi seguire i passaggi ad esempi iniziando dalla funzione digitalwrite contenuta in wiring_digital.c

void digitalWrite(uint8_t pin, uint8_t val)
{
	uint8_t timer = digitalPinToTimer(pin);
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	volatile uint8_t *out;
	if (port == NOT_A_PIN) return;
	// If the pin that support PWM output, we need to turn it off
	// before doing a digital write.
	if (timer != NOT_ON_TIMER) turnOffPWM(timer);
	out = portOutputRegister(port);
	uint8_t oldSREG = SREG;
	cli();
	if (val == LOW) {
		*out &= ~bit;
	} else {
		*out |= bit;
	}
	SREG = oldSREG;
}

come vedi per settare il valore viene ricercato la porta e il bit relativo al numero del pin immesso.
Questo viene fatto con due funzioni digitalPinToBitMask(pin) e digitalPinToPort(pin) che sono definite in Arduino.h

#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )

Questi due define (che vengono sostituiti in fase di compilazione) richiamano la funzione pgm_read_byte che non fa altro che leggere il valore delle costanti: digital_pin_to_port_PGM + (P) e digital_pin_to_bit_mask_PGM + (P) che sono definite in pins_arduino.h

const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
	PD, /* 0 */
	PD,
	PD,
	PD,
	PD,
	PD,
	PD,
	PD,
	PB, /* 8 */
	PB,
	PB,
	PB,
	PB,
	PB,
	PC, /* 14 */
	PC,
	PC,
	PC,
	PC,
	PC,
};

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
	_BV(0), /* 0, port D */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(6),
	_BV(7),
	_BV(0), /* 8, port B */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(0), /* 14, port C */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
};

Ecco che magicamente dal pin 5 si passa al Bit X della Porta Y.

Il valore di out viene invece individuato tramite portOutputRegister(port) che è definito in Arduino.h come:

#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )

che va a leggere tramite pgm_read_word il valore di port_to_output_PGM + (P) in:

const uint16_t PROGMEM port_to_output_PGM[] = {
	NOT_A_PORT,
	NOT_A_PORT,
	(uint16_t) &PORTB,
	(uint16_t) &PORTC,
	(uint16_t) &PORTD,
};

Note che tutte le costanti sono definite come array il cui indice è il numero del pin indicato in ingresso con il digitalwrite e opportunamente modificato.

Grazie mille per le risposte...mi scuso ma quando ho provato ad inserire il codice del file mi diceva che il messaggio era troppo grande...
Davide