PCF8574.
EXPANSOR REMOTO DE PUERTO 8-BIT I/O POR I2C-BUS.
Traducción libre del datasheet PCF8574.pdf
En esta ocasión he preparado un artículo que solamente quiere poner al alcance del aficionado a la electrónica que no disponga de conocimientos del ‘inglés’. Espero dar una idea de las posibilidades que ofrece este pequeño dispositivo puesto al alcance tanto del ingeniero como del aficionado que por distintas razones no puede entender los beneficios que aporta este circuito integrado.
1. CARACTERÍSTICAS
1 2 3 4 5 6 7 8 9 |
· Suministro de voltaje de funcionamiento 2.5 a 6 V · Bajo consumo de corriente de espera (standby) de 10 mA máximo · Expansor I²C a puerto paralelo · Open-drain interrupt de salida · Puerto remoto 8-bit I/O para el I²C-bus · Compatible con la mayoría de microcontroladores · Salidas Latched con drivers de alta capacidad de corriente para conducir directamente LEDs. · Direccionado por hardware 3 pines dirección para emplear hasta 8 dispositivos (hasta 16 PCF8574A) · DIP16, o space-saving SO16 o SSOP20 packages. |
(Ver Hojas de Datos)
2. DESCRIPCIÓN GENERAL.
El PCF8574 es un circuito CMOS de silicio. Este tiene el propósito general de expansor remoto de E/S para la mayor parte de familias de microcontrolador a través del bus bidireccional de dos líneas (I2C). Este es el diagrama de bloques:
El dispositivo es un expansor remoto de 8bits I/O para bus I2C, consiste en un puerto cuasi bidireccional de 8 bit y una interfaz I2C-bus. El PCF8574 tiene una baja corriente consumo e incluye salidas cerrojo con capacidad de alta corriente para conducir directamente LEDs. Este, también posee una línea de interrupción (INT), que puede ser conectada a la lógica interrupt del microcontrolador. Mediante el envío de una señal interrupt sobre esta línea, la E/S remota puede informar al microcontrolador si hay datos entrantes en sus puertos sin necesidad de comunicarse a través del I2C-bus. Esto quiere decir que el PCF8574 puede seguir siendo un simple dispositivo esclavo. El PCF8574 y PCF8574A son versiones que difieren sólo en su dirección Slave, como se muestra más abajo, en la Fig.10.
6. CARACTERÍSTICAS DEL I2C-BUS.
El I2C bus son 2 vías, 2 líneas de comunicación entre diferentes módulos o circuitos integrados. Las dos líneas, una línea de datos serie (SDA) y una línea de reloj (SCL). Ambas líneas deben ser conectadas a un suministro positivo a través de una polarización a alto (PRA), aun cuando se conecte a la salida de las etapas de un dispositivo. La transferencia de datos sólo se podrá iniciar cuando el bus no esté ocupado.
6.1 BIT DE TRANSFERENCIA.
Se transfiere un bit de datos en cada pulso de reloj. Los datos en la línea SDA deben permanecer estables durante el período de pulso ALTO del reloj, con cambios en la línea de datos en este tiempo ha de ser interpretado como señales de control (ver Fig. 5).
6.2 CONDICIONES DE START Y STOP.
Ambas líneas de datos y reloj siguen siendo ALTO cuando el bus no está ocupado. Una transición de ALTO -a- BAJO de la línea de datos, mientras el reloj es ALTO se define como la condición de inicio (S). Una transición de BAJO -a- ALTO de la línea de datos mientras el reloj es ALTO se define como la condición de parada (P) (ver Fig. 6).
6.3 CONFIGURACIÓN DEL SISTEMA.
Un dispositivo que genera un mensaje es un «emisor», un dispositivo que lo recibe es un «receptor». El dispositivo que controla el mensaje es el ‘maestro’ y los dispositivos que son controlados por el maestro son los «esclavos» (ver Fig.7).
6.4 ACKNOWLEDGE (RECONOCIMIENTO).
El número de bytes de datos transferidos entre las condiciones de inicio y parada del transmisor al receptor no esta limitado. Cada byte de ocho bits está seguido de un bit de reconocido. El bit de reconocido es un nivel ALTO puesto en el bus por el transmisor, mientras el maestro genera un reconocido suplementario relacionado con el pulso de reloj.
Un receptor esclavo cuando es direccionado debe generar un reconocido después de la recepción de cada byte. Un maestro también debe generar un reconocido después de la recepción de cada byte que ha sido registrado por los transmisores esclavos. El dispositivo reconoce que la línea SDA tiene una caída a bajo (pull-down) durante el pulso de reconocimiento de reloj, de modo que la línea SDA sea estable BAJO durante el período relacionado con el pulso ALTO de reconocimiento de reloj, los tiempos de configuración y mantenimiento deben ser tenidos en cuenta.
Un maestro debe señal de un receptor final de los datos al transmisor, al no reconocer una generación en el último byte que ha sido generado por los esclavos. En este caso, el transmisor debe abandonar la línea de datos a fin de que el ALTA maestro para generar una condición de parada.
Un maestro receptor debe señalar un fin de datos al transmisor para no engendrar un reconocido en el último byte que ha sido registrado por el esclavo. En este acontecimiento el transmisor debe dejar la línea de datos ALTO para permitir al maestro engendrar una condición de parada.
DESCRIPCIÓN FUNCIONAL.
Direccionamiento.
Cada una de las ocho E/S de los PCF8574’s pueden ser usadas por separado, como una entrada o salida. Los datos de entrada se transfieren del puerto al microcontrolador por el modo LECTURA (véase la Fig.12 en el DS). Los datos de salida son transmitidos al puerto por el modo ESCRITURA (véase la Fig.11).
Para el direccionamiento ver figuras 10, 11 12 y en el DS.
7.2 INTERRUPT.
El PCF8574 proporciona una salida de drenaje abierto (INT), que puede alimentar a una entrada correspondiente del microcontrolador. Esto dota a los chips de un tipo de maestro de la función que puede iniciar una acción en el resto del sistema. Se genera un interrupt por cualquier aumento o disminución del borde de la entradas del puerto en el modo de entrada.
Después del tiempo Tiv en que el INT de la señal es válida. Restablecer y reactivar el circuito de interrupción se logra cuando los datos sobre el puerto se cambia a la configuración original o los datos se leen o se escriben en el puerto que ha generado la interrupción.
El restablecimiento ocurre así:
1 2 3 4 |
• En el modo lectura del bit reconocer después borde creciente de la salida de la señal de SCL. • En el modo escritura del bit reconocer después de la transición de HIGH-a-LOW de la señal de SCL. • Los interrupts que se producen durante el reconocimiento del reloj el pulso se puede perder (o muy poco), debido al restablecimiento del interrupt en este pulso. |
Cada cambio de la E/S después del restablecimiento serán detectados y después del próximo flanco ascendente de reloj, se transmitirá como INT. La lectura o escritura a otro dispositivo, no afecta al circuito interrupt.
7.3 CUASI-BIDIRECCIONAL I/OS.
Una E/S cuasi-bidireccional se puede utilizar como una entrada o salida sin el uso de una señal de control para la dirección de datos (ver la figura 15).
VALORES LÍMITES.
De conformidad con la valoración máxima absoluta.
Más información relevante, respecto de condiciones de trabajo y tensiones, deben seguir el enlace del Data Sheet.
UN EJEMPLO.
Veamos un ejemplo sencillo, con una aplicación que nos sirva de referencia para recalcar conceptos. Utilizaremos dos unidades del PCF8574, una unidad servirá para leer datos desde unos pulsadores (o teclado) y la otra unidad, controlará los datos que leerá microcontrolador Arduino desde la interfaz I2C para encender unos LEDs o segmentos de un display.
Qué hace el código: lee si alguno de los pulsadores es presionado. Arduino procesa la información que le envía desde la interfaz 1 PCF8574 de la izquierda y mediante el interfaz 2 PCF8574 de la derecha, enciende los segmentos del número que corresponde del display. Por cierto, aunque en el circuito esquematizado aparece conectado el Dp (punto decimal), en el código, no lo he incluido.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
// // Doble Didplay siete-segmentos LED con botones // Basado en un trabajo de Natalia Fargasch Norman // // http://www.tinkerhobby.com/arduino-2-digit-7-segment-display-with-buttons/ // // Common Anode digit 1 pin 10 // Common Anode digit 2 pin 5 // // Modificado y mejorado 11.08.11 // V. García // // Utiliza 2202 bytes con Arduino v0013 y v0023. Si utiliza una ver. mayor cambie // la #define F 7 por const int F = 7; // // G F CA A B // | | | | | -> pins and segments they control // ------------- // | A | // F| |B // |---- G ----| // E| |C // | D | // ------------- // | | | | | -> pins and segments they control // E D CA C DP // Composición de los digitos en Segmentos // 0 => -FEDCBA // 1 => ----BC- // 2 => G-ED-BA // 3 => G--DCBA // 4 => GF--CB- // 5 => GF-DC-A // 6 => GFEDC-A // 7 => ----CBA // 8 => GFEDCBA // 9 => GF-DCBA // Pines digitales usados Arduino para encender // los correspondientes segmentos LED del display #define A 2 #define B 3 #define C 4 #define D 5 #define E 6 //#define F 7 const int F = 7; #define G 8 // Pulsadoes boton conectados a pines 9, 10 y 11 #define BTN1 9 // avance #define BTN2 10 // descuenta #define BTN3 11 // reset // Pines comunes de cada display de anodo comun #define CA1 12 #define CA2 14 #define led 13 // puede usarse para activar un relé // Pines para A B C D E F G, en secuencia // se pueden usar los que más interesen const int segs[7] = { 2, 3, 4, 5, 6, 7, 8 }; // Segmentos que componen cada número // Para CC. //const byte numbers[10] = { 0b0111111, 0b0000110, 0b1011011, 0b1001111, 0b1100110, 0b1101101, 0b1111101, 0b0000111, 0b1111111, 0b1101111}; // Para CA. const byte numbers[10] = { 0b1000000, 0b1111001, 0b0100100, 0b0110000, 0b0011001, 0b0010010, 0b0000010, 0b1111000, 0b0000000, 0b0010000}; int digit1 = 0; int digit2 = 0; void setup() { pinMode(A, OUTPUT); pinMode(B, OUTPUT); pinMode(C, OUTPUT); pinMode(D, OUTPUT); pinMode(E, OUTPUT); pinMode(F, OUTPUT); pinMode(G, OUTPUT); pinMode(BTN1, INPUT); pinMode(BTN2, INPUT); pinMode(BTN3, INPUT); digitalWrite(BTN1, HIGH); // activa RPA digitalWrite(BTN2, HIGH); // activa RPA digitalWrite(BTN3, HIGH); // activa RPA pinMode(CA1, OUTPUT); pinMode(CA2, OUTPUT); pinMode(led, OUTPUT); // LED o relé // digit1 = 9; digit2 = 9; // solo para test } void loop() { // chequea boton1. Incrementa int val1 = digitalRead(BTN1); if (val1 == LOW) { if (digit2 >= 9 && digit1 >= 9) { digit2 = 0; digit1++; digit1 %= 10; // if (digit1 >=9) { digit2++; } } else if (digit1 >= 9) { digit2++; digit2 %= 10; } digit1++; digit1 %= 10; delay(10); } // chequea boton2. Decrementa int val2 = digitalRead(BTN2); if (val2 == LOW) { if (digit1 >= 0) { if (digit1 < 0) { digit1 = 0; } digit1--; } if(digit1 < 0) { digit1 = 9; if (digit2 < 0) { digit2 = 0; } digit2--; } if (digit2< 0) { digit2 = 9; } } // display numero unsigned long startTime = millis(); for (unsigned long elapsed=0; elapsed < 300; elapsed = millis() - startTime) { lightDigit1(numbers[digit1]); delay(5); lightDigit2(numbers[digit2]); delay(5); } } void lightDigit1(byte number) { digitalWrite(CA1, LOW); digitalWrite(CA2, HIGH); lightSegments(number); } void lightDigit2(byte number) { digitalWrite(CA1, HIGH); digitalWrite(CA2, LOW); lightSegments(number); } void lightSegments(byte number) { for (int i = 0; i < 7; i++) { int bit = bitRead(number, i); digitalWrite(segs[i], bit); } } |
Si tiene alguna duda indíquemelo.