Saltar al contenido principal
LibreTexts Español

24.1: Introducción

  • Page ID
    81943
  • \( \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}}} \)

    La discusión que sigue trata estrictamente de la detección de nivel lógico alto/bajo de dos estados. Para señales analógicas continuamente variables, consulte la entrada Bits & Pieces que cubre AnalogRead (). A través de la función PinMode (), o accediendo directamente a los bits de registro de dirección de datos apropiados (DDRx), las conexiones IO de propósito general se pueden configurar para leer el estado de conmutadores externos o niveles lógicos. Con el Arduino Uno, 5 voltios representa una lógica alta mientras que 0 voltios representa una lógica baja. Una capacidad adicional del ATMega 328P en el Uno es la capacidad de incluir una resistencia interna opcional de pull-up en el pin de entrada. Esto permite la conexión de un simple interruptor pasivo de cortocircuito a tierra (es decir, el pin de entrada flota alto cuando el interruptor está abierto y baja cuando el interruptor está activado).

    Para leer entradas de pin individuales, el sistema Arduino ofrece la función DigitalRead (). Se pueden leer múltiples pines simultáneamente accediendo directamente al registro apropiado, que examinaremos después. A continuación se muestra una copia de la documentación en línea para la función DigitalRead ():

    Figura\(\PageIndex{1}\): digitalRead docs

    DigitalRead () 1

    Descripción

    Lee el valor de un pin digital especificado, ya sea ALTO o BAJO.

    Sintaxis

    DigitalRead (pin)

    Parámetros

    pin: el número del pin digital que desea leer (int)

    Devoluciones

    ALTO O BAJO

    Ejemplo

    int ledPin = 13;    // LED connected to digital pin 13
    int inPin = 7;      // pushbutton connected to digital pin 7
    int val = 0;        // variable to store the read value
    
    void setup()
    {
        pinMode(ledPin, OUTPUT);      // sets the digital pin 13 as output
        pinMode(inPin, INPUT);        // sets the digital pin 7 as input
    }
    void loop()
    {
        digitalWrite(ledPin, val);    // read the input pin
        val = digitalRead(inPin);     // sets the LED to the button's value
    }
    

    Establece el pin 13 en el mismo valor que el pin 7, que es una entrada.

    Nota

    Si el pin no está conectado a nada, DigitalRead () puede devolver ALTO o BAJO (y esto puede cambiar aleatoriamente).

    Los pines de entrada analógica se pueden utilizar como pines digitales, denominados A0, A1, etc.

    Ver también

    A continuación se muestra una versión ligeramente limpiada del código fuente (que se encuentra en el archivo wiring_digital.c):

    int digitalRead( uint8_t pin )
    {
        uint8_t timer, bit, port;
    
        timer = digitalPinToTimer( pin );
        bit = digitalPinToBitMask( pin );
        port = digitalPinToPort( pin );
    
        if (port == NOT_A_PIN)                    return LOW;
    
        if (timer != NOT_ON_TIMER)                turnOffPWM(timer);
    
        if (*portInputRegister(port) & bit)       return HIGH;
    
        return LOW;
    }
    
    static void turnOffPWM( uint8_t timer )
    {
        switch ( timer )
        {
            case TIMER0A:   cbi( TCCR0A, COM0A1 );    break;
            case TIMER0B:   cbi( TCCR0A, COM0B1 );    break;
            
            // and so forth for all available timers, not shown
        }
    }
    

    Las tres primeras líneas convierten el designador de pines Arduino al puerto ATMega 328P apropiado, número de bits y temporizador. Si el puerto no es válido, la función sale.

    timer = digitalPinToTimer( pin );
    bit = digitalPinToBitMask( pin );
    port = digitalPinToPort( pin );
    
    if (port == NOT_A_PIN) return LOW;
    

    El temporizador es importante porque el sistema Arduino preconfigura los tres temporizadores integrados de Uno para su uso con la función AnalogWrite () a través de un esquema de modulación de ancho de pulso. Esto afecta a seis de los posibles pines. Para un correcto funcionamiento de la lectura digital, estos temporizadores deben estar apagados. Vimos este mismo bit de código dentro de la función digitalWrite ().

    if (timer != NOT_ON_TIMER) turnOffPWM(timer);
    

    En este punto se lee el contenido del registro de entrada (el nombre directo del registro de entrada es PINx) y luego se anD con el bit solicitado. Esto elimina todos los demás bits para que podamos devolver ya sea un simple alto o bajo.

    if (*portInputRegister(port) & bit) return HIGH;
    
    return LOW;
    

    La función utilizada para apagar los temporizadores de modulación de ancho de pulso es poco más que una declaración de interruptor/caso. Si el pin de Arduino especificado está conectado internamente a un temporizador, ese temporizador se encuentra en la sentencia switch y se ejecuta una llamada cbi () en el registro de control de contador de tiempo apropiado. La función cbi () se traduce en una sola instrucción de lenguaje ensamblador para borrar el bit especificado en el registro de control, apagando así ese temporizador.

    static void turnOffPWM( uint8_t timer )
    {
        switch (timer)
        {
            case TIMER0A:    cbi(TCCR0A, COM0A1);    break;
            case TIMER0B:    cbi(TCCR0A, COM0B1);    break;
            case TIMER1A:    cbi(TCCR1A, COM1A1);    break;
            case TIMER1B:    cbi(TCCR1A, COM1B1);    break;
            case TIMER2A:    cbi(TCCR2A, COM2A1);    break;
            case TIMER2B:    cbi(TCCR2A, COM2B1);    break;
        }
    }
    

    En algunas aplicaciones, es necesario leer varios bits a la vez, por ejemplo, al leer datos paralelos. Esto se puede realizar a través de un acceso directo al registro PinX correspondiente. PinX es más bien como el gemelo fraterno del registro PortX. Si bien PortX se usa para escribir datos digitales en una conexión externa, PinX es donde se leen datos digitales de una conexión externa. Así como hay cuatro registros de puerto de salida, A a D, hay cuatro registros de pines de entrada, A a D. No todos los microcontroladores están configurados de esta manera. Algunos de ellos utilizan el mismo registro tanto para lectura como para escritura (siendo la función controlada por el registro de dirección de datos asociado).

    Aquí se explica cómo acceder directamente a un solo bit en un pin conectado sin temporizador. Primero, borre el bit de registro de dirección de datos deseado para activar el modo de entrada. En segundo lugar, si se desea, configure el mismo bit en el registro de puertos asociado para habilitar la resistencia pull-up opcional. Si no quieres el pull-up, deja ese poco claro. Por último, lee el bit deseado en el registro de pines y Y con la máscara de bits para eliminar los otros bits. Por ejemplo, para leer el bit 4 (0x10 o 00010000 en binario) en el puerto B:

    DDRB &= (~0x10);        // activate input mode
    PORTB |= 0x10;          // enable pull-up or use the bitSet macro
                            // bitSet( PORTB, 4 );
    value = PINB & (~0x10); // retrieve data
    

    Es sólo un trabajo menor alterar esto para múltiples bits. Para leer ambos bits 0 y 4 pero sin las resistencias pull-up (patrón de bits 00010001 o 0x11):

    DDRB &= (~0x11);            // activate input mode
    PORTB &= (~0x11);           // disable pull-up
    value = PINB & (~0x11);     // retrieve data bits
    

    o si quieres los bits por separado:

    value0 = PINB & (~0x01);    // retrieve data bit 0
    value4 = PINB & (~0x10);    // retrieve data bit 4
    

    1. http://arduino.cc/en/Reference/DigitalRead

    This page titled 24.1: Introducción 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.