¿Cómo habilitar el pin de salida en alto de forma predeterminada en Arduino Uno?

En Arduino Uno, noté que cuando configuro un PIN para la salida, el estado inicial predeterminado es bajo. ¿Hay alguna manera de establecer el estado de salida inicial en alto?

La documentación de pinmode solo admite input, input_pullupy output. Me gustaría que hubiera una opción para output_pullup. Si coloco una resistencia pull-up externa de 10k Ohm alrededor del PIN de salida, ayuda un poco a empujar el estado inicial hacia lo alto.

Aún así, si hay una solución basada en software (es decir, flashear el Arduino Uno para que la salida predeterminada sea alta), sería muy apreciada.

Respuestas (3)

No hay nada que le impida escribir los registros de salida (PORTx) antes de escribir los registros de dirección (DDRx). Desafortunadamente, las funciones de la biblioteca Arduino ( pinModey digitalWrite) tienen una serie de efectos secundarios y pueden o no funcionar. (Quizás alguien más familiarizado que yo con las bibliotecas de Arduino pueda aconsejarme si un digitalWriteseguido de un pinModefuncionará.

Por lo tanto, la manipulación directa del registro puede lograr lo que desea, si la solución de @Tom es insuficiente (la solución de Tom debería funcionar en casi todos los casos). Primero, consulte la página 77 de la hoja de datos del ATmega328 y observe la tabla 14-1.

Suponiendo que un pin comience con los bits DDR y PORT limpios: es un pin de entrada Hi-z. Establezca el bit PORT, el pin ahora es una entrada con un pullup. Ahora, cuando configura el bit DDR, el pin pasa de una entrada con pullup directamente a una salida alta.


Editar: tratando de comprender mejor lo que sucedería con el siguiente código leyendo wiring_digital.c:

// where p is an Arduino pin, x is the corresponding port,
// and n is the corresponding bit
// pin starts with DDRxn == 0, PORTxn == 0
digitalWrite(PINp, HIGH);
// PORTx |= 1<<n, from line 159
// PORTxn == 1, DDRxn == 0: input pullup
pinMode(PINp, OUTPUT)
// DDRx |= 1<<n, from line 56
// PORTxn == 1, DDRxn == 1: output high

Entonces, parece que llamar digitalWriteantes pinModehará exactamente lo que quieres. Ignore el lío sobre la manipulación directa del registro anterior.

Solo para agregar un poco, el AVR se inicia con todos los pines predeterminados en Tristate, por lo que si necesita afirmar el nivel alto durante el reinicio, debe usar un pullup; de lo contrario, configurar los pines es la forma más fácil setup(). Si el cargador de arranque configura el pin, la solución no funcionará por cierto.

No puede cambiar el valor predeterminado del hardware. Hay un código que se ejecuta al inicio que usted no controla (hay al menos algún código de inicio en la ROM dentro del procesador, y también puede haber un gestor de arranque que se puede cambiar pero que es difícil de modificar para usted). A veces, este código puede alternar los pines de formas inesperadas mientras busca dispositivos de arranque alternativos o lo que sea. Esto me ha causado muchos problemas en varios momentos de mi carrera, porque no siempre está bien documentado por los proveedores de silicio (proveedores de segundo nivel de bajo costo).

A partir de su pregunta, no está claro si el procesador está bajando activamente el pin que desea usar, o si solo tiene un pulldown débil. Si es solo un pulldown débil, puedes dominarlo con un pullup de 1k. Además, puedes probar las ideas mencionadas anteriormente. Básicamente, debe asegurarse de alguna manera de que los datos estén configurados en alto ANTES de que la dirección se configure para generar en el código sobre el que tiene control. No sé mucho sobre arduino, pero me he ocupado de este tipo de cosas en varios microprocesadores y normalmente es posible establecer datos antes de establecer la dirección de un pin IO. A veces, el mismo bit que habilita el pullup interno también establece los datos en 1 para la salida.

Si el pin está bajando activamente por el código que no tiene la capacidad de modificar, un pullup no solucionará el problema. Pero es posible que pueda consultar la documentación (o experimentar) y encontrar otro pin que no se agote después del reinicio.

Buena suerte.

Estoy bastante seguro de que no hay ROM de arranque en AVR.
DE ACUERDO. Todavía hay un código de rom de máscara que hace que el procesador haga lo que hace durante el inicio. En principio, es posible que el código maskrom alterne las E/S.
No estoy seguro de que haya ninguna ROM de máscara. Todo indica que el restablecimiento y el inicio del AVR están controlados completamente por hardware.
¿Qué hace cuando arranca? Si hace algo más complejo que obtener el código de una dirección fija y comenzar a ejecutarlo, entonces probablemente tenga una rom de máscara en el procesador. O algo muy parecido.
Restablece los periféricos, inicializa la fuente del reloj y salta al vector de restablecimiento. Nada que probablemente requiera máscara ROM.
Entonces, tampoco es probable que cambien los IO. Debería haber una solución para el OP, entonces.

Si bien no es exactamente lo que estaba buscando, agregar un código adicional setup()debería funcionar:

void setup() {
    pinMode(PINx, OUTPUT); // replace PINx with the pin number
    digitalWrite(PINx, HIGH); //makes PINx high almost immediately (few uS)
    // rest of code
}

No hay problema con realizar escrituras digitales o lecturas digitales en void setup(), puede hacer cualquier cosa en setup(), pero solo se ejecuta una vez. A menos que quiera decir 'ir alto en el instante en que se aplica la energía' porque, aparte de una resistencia pullup, creo que no tendrá suerte

Técnicamente, puede hacer cualquier cosa en setup () cuando lo desee , es solo una función C normal. La línea setup();está en la función principal al principio (mucho después de una init()llamada oculta).
Me refiero al momento en que se aplica la alimentación externa o al momento en que se presiona el botón de reinicio en la placa. es el tiempo antes de setup()que se llamara
Es posible que se quede atascado con un pull up, aunque si necesita un pull up fuerte, podría tener un PMOS o PNP tirando del pin alto al encenderlo, que se apagaría una vez que se ejecutara la configuración (), la captura es lo que necesitaría DOS pines IO, uno para la salida y otro para deshabilitar el pull up (aunque todos los pull ups podrían compartir un control común). En realidad, ¿qué pasa con la instalación de un inversor? Eso siempre sería alto siempre que la entrada fuera baja, ¿funcionaría eso?