El compilador no detectará ningún error y el código se compilará y ejecutará. Por lo tanto, para ver qué sucede, necesitamos explorar la magia detrás de escena. Para un resumen, salte al final.
La segunda línea en su código es donde sucederá la magia y ahí es donde debemos enfocarnos.
pinMode(pin, OUTPUT);
La porción de pinMode
relevante para esta discusión es:
void pinMode(uint8_t pin, uint8_t mode)
{
uint8_t bit = digitalPinToBitMask(pin); //The first instance where pin is used
uint8_t port = digitalPinToPort(pin);
if (port == NOT_A_PIN) return;
//Do something
}
(La implementación completa se puede encontrar en cableado_digital.c )
Entonces, aquí, digitalPinToBitMask
parece estar usando pin
para calcular un bit intermedio. Explorando más a fondo, digitalPinToBitMask
hay una macro definida en Arduino.h
cuya definición es esta línea:
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
Este forro de aspecto extraño hace una tarea muy simple. Indiza el elemento P th en la matriz digital_pin_to_bit_mask_PGM
y lo devuelve. Esta matriz digital_pin_to_bit_mask_PGM
se define en pins_arduino.h
el mapa de pin para la placa específica que se utiliza.
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),
...
};
Este conjunto tiene 20 elementos en total, por lo que no tenemos suerte. 999 indexará una ubicación de memoria en la memoria flash fuera de esta matriz, lo que conducirá a un comportamiento impredecible. O lo hará?
Todavía tenemos otra línea de defensa contra la anarquía en tiempo de ejecución. Es la siguiente línea de la función pinMode
:
uint8_t port = digitalPinToPort(pin);
digitalPinToPort
nos lleva por un camino similar. Se define como una macro junto con digitalPinToBitMask
. Su definición es:
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
Ahora, indexamos el elemento P th del digital_pin_to_port_PGM
cual es una matriz definida en el mapa pin:
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PD, /* 0 */
PD,
....
PC,
PC,
};
Esta matriz contiene 20 elementos, por lo que 999 está nuevamente fuera de rango. Nuevamente, este comando lee y devuelve un valor de la memoria flash de cuyo valor no podemos estar seguros. Esto conducirá nuevamente a un comportamiento impredecible de aquí en adelante.
Todavía hay una última línea de defensa. Esa es la if
verificación pinMode
del valor de retorno de digitalPinToPort
:
if (port == NOT_A_PIN) return;
NOT_A_PIN
se define como 0 in Arduino.h
. Entonces, si el byte devuelto por digitalPinToPort
resulta ser cero, entonces pinMode
fallará silenciosamente y regresará.
En cualquier caso, pinMode
no puede salvarnos de la anarquía. 999 está destinado a resultar en la fatalidad.
TL; DR, el código se ejecutará y el resultado será impredecible. Lo más probable es que no se establezca ningún pin OUTPUT
y digitalWrite
fallará. Si tiene una suerte excepcionalmente mala, entonces se puede establecer un pin aleatorio en OUTPUT
, y digitalWrite
puede establecerlo en HIGH
.
uint8_t
por lo que primero se convertiría en 231 mediante la llamada de códigopinMode
. El resultado final es el mismo:pinMode
ydigitalWrite
tendrá un comportamiento impredecible y podría darle una paliza partes aleatorias de la memoria si los llama con un argumento mal alfiler.En las bibliotecas estándar, hay macros diseñadas para convertir pines en puertos, que se utilizan en el ensamblaje. Aquí están para el Uno de Arduino 1.0.5:
Hay más, pero no los mostraré aquí.
Creo que su programa restaría 14 de 999, lo que aún sería demasiado grande para el brograma. Luego trataría de señalar el elemento 985 de la
digital_pn_to_bit_mask_PGM
matriz, que solo contiene 20 elementos. Lo más probable es que termine atornillando al Arduino señalando un punto aleatorio en el programa.fuente