PCF8574 expansor I/O de 8 bit por I2C

publicado en: Sin Categoria | 0

pcf8574-expansor-io-8-bit-i2c-2El PCF8574 (datasheet), en ocasiones nos hemos encontrado frente a la necesidad de aumentar la cantidad de entradas y salida digital del microcontrolador utilizado en nuestros proyectos. Sin embargo, frente a esta necesidad ya existen varias soluciones como por ejemplo: registros de desplazamiento como los circuitos integrados 74HCT595/74HC164, artificios en hardware y otros. No obstante, estos registro solo aumentan salidas y no entradas digitales.

El PCF8574 es un chip expansor de entradas y salidas digitales capaz de proporcionar un arreglo de 8 entradas o salidas digitales. Primero, el chip se puede controlar a través del protocolo I2C que utiliza solo 2 lineas para su comunicación. Además, cuenta con una salida de interrupción que se habilita cuando el pin configurado como entrada cambia de estado. Tambien, se puede configurar la dirección del chip de manera externa a través de 3 pines, esto le permite conectar 8 dispositivos al bus I2C, dándole una capacidad de tener hasta 64 entradas o salidas digitales. Todas estas características le permiten ser compatibles con muchos microcontroladores.

CARACTERÍSTICAS DEL PCF8574

  • Interfaz bus I2C a 100Khz.
  • Expansor I/O de 8-bit.
  • Operación de voltaje: 2.5 – 6 vdc.
  • Interrupción open-drain.
  • Hasta 8 direcciones programables.
  • Corriente de hasta 80mA por canal.

APLICACIONES DEL PCF8574

  • Control de leds y display.
  • Teclado matriciales.
  • Control industrial.
  • PLC.
  • Equipos médicos.
  • Dispositivos móviles.
  • Maquinas de juegos.

DESCRIPCIÓN DE REGISTROS DEL PCF8574

A continuación se muestra la arquitectura interna representado en diagrama de bloques

pcf8574-expansor-io-8-bit-i2c-3

Secuencia de lectura y escritura en los registros.

pcf8574-expansor-io-8-bit-i2c-4

Secuencia de lectura de los pines I/O utilizando Interrupción.

pcf8574-expansor-io-8-bit-i2c-5

CIRCUITO DE CONEXIÓN PIC16F1829 Y PCF8574

pcf8574-expansor-io-8-bit-i2c-6

EJEMPLO PIC16F1829 CON PCF8574

A continuación se muestra como controlar entradas y salidas digitales con 2 PCF8574 a través del bus I2Cy utilizando el PIC16F1829. Primero, cada device PCF8574 tendrá una dirección como se muestra en gráfica de arriba, esto se configura a través de los pines A[0-2] del mismo. Luego, en el device #0 se tendrá las entradas digitales  y en el deveice #1 las salidas digitales. Finalmente, en el device #0 se controlará el pin INT que es de interrupción para saber cuando cambia de estado los botones conectados. Todo ello se controlará a través del controlador PIC16F1829, a continuación se muestra el código y sus librerías.

Código principal MAIN.

#define _XTAL_FREQ 32000000
#include 
#include "fuses.h"
#include "i2c.h"

unsigned char cont = 0;

void main(void) {
    OSCCON = 0b11110010; // PLLEN=1(x4), IRCF=8Mhz, SCS=OSC_INTERNAL
    ANSELA = 0;
    i2c_init(FREC_400KHZ);
    __delay_ms(100);
    i2c_start();
    i2c_write(0x42);
    i2c_write(cont++);
    i2c_stop();
    TRISAbits.TRISA2 = 1;
    INTCONbits.PEIE = 1;
    INTCONbits.INTE = 1;
    OPTION_REGbits.INTEDG = 0;
    INTCONbits.INTF = 0;
    INTCONbits.GIE = 1;
    while (1) {
    }
    return;
}

void interrupt isr(void) {
    if (INTCONbits.INTF) {
        i2c_start();
        i2c_write(0x41);
        cont = i2c_read(0);
        i2c_stop();
        _nop();
        _nop();
        _nop();
        i2c_start();
        i2c_write(0x42);
        i2c_write(cont);
        i2c_stop();
        INTCONbits.INTF = 0;
    }
}

Librería I2C.

#ifndef I2C_H
#define	I2C_H

#define FREC_400KHZ  400000
#define FREC_100KHZ  100000

void i2c_init(unsigned long frec) {
    TRISBbits.TRISB4 = 1;
    TRISBbits.TRISB6 = 1;
    SSP1CON1 = 0b00101000;
    SSP1ADD = (_XTAL_FREQ / (4 * frec)) - 1;
    SSP1STATbits.SMP = 0;
}

void i2c_start(void) {
    while ((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F));
    SSP1CON2bits.SEN = 1;
}

void i2c_write(unsigned char value) {
    while ((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F));
    SSP1BUF = value;
}

unsigned char i2c_read(unsigned char value) {
    volatile unsigned char temp = 0;
    while ((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F));
    SSP1CON2bits.RCEN = 1;
    while ((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F));
    temp = SSP1BUF;
    while ((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F));
    SSP1CON2bits.ACKDT = (value) ? 0 : 1;
    SSP1CON2bits.ACKEN = 1;
    return temp;
}

void i2c_stop(void) {
    while ((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F));
    SSP1CON2bits.PEN = 1;
}

#endif	/* I2C_H */

Librería FUSES

#ifndef FUSES_H
#define	FUSES_H

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = ON          // Flash Program Memory Code Protection (Program memory code protection is enabled)
#pragma config CPD = ON         // Data Memory Code Protection (Data memory code protection is enabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = ON       // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)

#endif	/* FUSES_H */

Deja una respuesta