Saltar al contenido principal
LibreTexts Español

15.2: Entrada/Salida

  • Page ID
    81927
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    Considere una aplicación integrada típica, como un termostato programable o “inteligente”. A diferencia de un termostato electromecánico normal, estos dispositivos permiten al dueño de la casa cambiar automáticamente la temperatura en diferentes momentos del día con el fin de ahorrar energía. Después de todo, ¿por qué tener la calefacción o el aire acondicionado funcionando cuando no hay nadie en casa? Ciertamente, estos dispositivos no vienen con monitor o teclado. En su lugar puede haber una pequeña pantalla LCD con algunos mensajes fijos y una pantalla numérica de dos dígitos para la temperatura. Para la entrada puede haber tan pocos como dos o tres botones para la programación (set item más arriba y abajo). En comparación, un horno microondas probablemente tendrá un teclado numérico completo con una serie de botones de función especial junto con múltiples pantallas de siete segmentos, o posiblemente varias pantallas alfanuméricas para mensajes cortos. En cualquier caso, estos dispositivos son muy diferentes de la computadora de escritorio estándar. En consecuencia, el enfoque de un programador para el procesamiento de entrada y salida será muy diferente en el caso integrado.

    Para empezar, es poco probable que haya funciones de estilo printf () y scanf (). Son en gran parte inservibles en este mundo. ¿De qué sirve printf () si todo lo que tiene para el hardware de salida es un montón de LEDs? Para la entrada, a menudo necesita leer el estado de los interruptores, los pulsadores y posiblemente alguna forma de control de nivel, como una perilla giratoria. Para la salida, a menudo necesita simplemente encender un LED o establecer un valor en una pantalla de siete segmentos. Para los mensajes de estilo “fijo”, estos también necesitan solo una sola señal para encenderlos o apagarlos, como un LED. En aplicaciones más avanzadas, una pantalla alfanumérica multilínea puede estar disponible por lo que establecer letras individuales es una posibilidad. En casi todos los casos, estas tareas se manejan configurando o borrando bits en puertos de salida o entradas específicos en el microcontrolador. Algunos puertos se pueden configurar como un byte o palabra. Además, algunos puertos pueden ser bidireccionales, lo que significa que pueden comportarse como entrada o salida dependiendo de alguna otra configuración del registro. Los puertos son poco más que pines en el microcontrolador que están conectados a circuitos externos. Por lo tanto, si un puerto está conectado a un circuito LED, establecer la salida del puerto ALTO podría encender el LED mientras que el puerto LOW podría apagar el LED. La pregunta obvia entonces es “¿Cómo lees o escribes en un puerto?” En muchos casos, los puertos serán mapeados en memoria. Es decir, se asigna una dirección específica en el mapa de memoria a un puerto dado. Lees y escribes desde/hacia él igual que cualquier otra variable. Además, los sistemas de desarrollo a veces disfrazan estas direcciones como variables globales predefinidas. También podrían incluir una biblioteca de rutinas específicas para utilizar los puertos. Por lo tanto, establecer un cierto puerto (llamémoslo el puerto “A”) a un alto podría ser tan simple como PORT_A = 1; o set_porta (1);. Leer desde un puerto podría ser algo así como a = PORT_A; o a = get_porta ();. En consecuencia, el código incrustado a menudo se trata de leer y escribir hacia/desde puertos y luego ramificarse a las tareas solicitadas.

    Hay algunos trucos para esto. Por ejemplo, ¿cómo saber si se ha pulsado una tecla? Llamar a get_porta () te indica el estado del switch conectado al puerto A en el instante en que lo llamas. Aquí no hay “historia” si se trata de un simple pulsador momentáneo en lugar de un interruptor de palanca. En un caso como este podrías “sondear” al puerto esperando que algo suceda. Esto implica usar un bucle simple y leer repetidamente el estado del puerto en el bucle. El código estalla cuando cambia el estado:

    while( get_portA() );
    

    Esto seguirá haciendo un bucle hasta que get_porta () devuelva 0. Por supuesto, si necesitas monitorear varios puertos como es típico, necesitarás leer un valor de cada uno para la prueba. Esta forma de monitoreo mientras se espera que algo suceda se llama bucle de eventos. Puede que no sea evidente, pero su casa y su automóvil probablemente estén llenos de dispositivos que ejecutan bucles de eventos, ¡solo esperando que haga algo! Estos bucles se ejecutan bastante rápido por lo que no se nota un desfase de tiempo entre tu push y la acción resultante. En el extremo de salida, un puerto normalmente permanece en el valor que lo configuraste, por lo que no hay necesidad de un bucle para “mantenerlo establecido”.

    Para pantallas más complicadas, como un dispositivo de siete segmentos o alfanumérico, es posible que deba crear una tabla de valores que indique patrones de bits para cada número o letra que se va a mostrar. Estos patrones, o palabras, se enviarían entonces varios puertos que a su vez están conectados a las pantallas.

    Para dispositivos de entrada variable como un control de volumen, el dispositivo externo (perilla, deslizador, sensor, etc.) se conectará a un convertidor analógico a digital o ADC. Esto podría ser un circuito separado o el controlador puede tenerlos incorporados. El convertidor convierte el voltaje analógico en un valor numérico que se puede leer desde un puerto. Por ejemplo, un control de volumen puede ser solo un potenciómetro conectado a una tensión fija. A medida que se mueve la perilla, el voltaje en el brazo del limpiaparabrisas cambiará. El convertidor A/D puede codificar esto en un solo byte. Un byte varía de 0 a 255 en valor. Así, si el volumen está al máximo, el puerto leerá 255. Si el volumen está a mitad de camino el puerto leerá aproximadamente 127, y finalmente 0 cuando el volumen esté apagado.


    This page titled 15.2: Entrada/Salida is shared under a CC BY-NC-SA 4.0 license and was authored, remixed, and/or curated by James M. Fiore via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.