- ¿Qué es el protocolo de comunicación I2C?
- ¿Cómo funciona la comunicación I2C?
- ¿Dónde utilizar la comunicación I2C?
- I2C con PIC16F877a usando el compilador XC8
- Programación usando los archivos de encabezado I2C:
- Simulación de Proteus:
Los microcontroladores PIC son una poderosa plataforma proporcionada por microchip para proyectos integrados, su naturaleza versátil ha hecho que encuentre formas en muchas aplicaciones y la fase aún continúa. Si ha estado siguiendo nuestros tutoriales PIC, se habrá dado cuenta de que ya hemos cubierto una amplia gama de tutoriales sobre el microcontrolador PIC comenzando desde los conceptos básicos. Desde ahora, hemos cubierto los conceptos básicos, podemos entrar en cosas más interesantes como el portal de comunicación.
En el vasto sistema de aplicaciones integradas, ningún microcontrolador puede realizar todas las actividades por sí mismo. En algún momento tiene que comunicarse con otros dispositivos para compartir información, existen muchos tipos diferentes de protocolos de comunicación para compartir esta información, pero los más utilizados son USART, IIC, SPI y CAN. Cada protocolo de comunicación tiene sus propias ventajas y desventajas. Centrémonos en la parte IIC por ahora, ya que eso es lo que vamos a aprender en este tutorial.
¿Qué es el protocolo de comunicación I2C?
El término IIC significa " Circuitos Inter integrados ". Normalmente se denota como I2C o I al cuadrado C o incluso como protocolo de interfaz de 2 cables (TWI) en algunos lugares, pero todo significa lo mismo. I2C es un protocolo de comunicación síncrono, lo que significa que ambos dispositivos que comparten la información deben compartir una señal de reloj común. Tiene solo dos cables para compartir información, de los cuales uno se usa para la señal del gallo y el otro se usa para enviar y recibir datos.
¿Cómo funciona la comunicación I2C?
La comunicación I2C fue introducida por primera vez por Phillips. Como se dijo anteriormente, tiene dos cables, estos dos cables se conectarán a través de dos dispositivos. Aquí un dispositivo se denomina maestro y el otro dispositivo se denomina esclavo. La comunicación debe ocurrir y siempre ocurrirá entre dos maestros y esclavos. La ventaja de la comunicación I2C es que se puede conectar más de un esclavo a un maestro.
La comunicación completa se lleva a cabo a través de estos dos cables, a saber, Serial Clock (SCL) y Serial Data (SDA).
Serial Clock (SCL): comparte la señal de reloj generada por el maestro con el esclavo
Datos en serie (SDA): envía los datos hacia y desde el maestro y el esclavo.
En un momento dado, solo el maestro podrá iniciar la comunicación. Dado que hay más de un esclavo en el bus, el maestro debe referirse a cada esclavo utilizando una dirección diferente. Cuando se trata, solo el ungüento con esa dirección en particular responderá con la información mientras que los demás siguen sin hacerlo. De esta forma podemos usar el mismo bus para comunicarnos con múltiples dispositivos.
¿Dónde utilizar la comunicación I2C?
La comunicación I2C se utiliza solo para comunicaciones de corta distancia. Ciertamente es confiable hasta cierto punto, ya que tiene un pulso de reloj sincronizado para hacerlo inteligente. Este protocolo se utiliza principalmente para comunicarse con sensores u otros dispositivos que tienen que enviar información a un maestro. Es muy útil cuando un microcontrolador tiene que comunicarse con muchos otros módulos esclavos utilizando un mínimo de solo cables. Si está buscando una comunicación de largo alcance, debe probar RS232 y si está buscando una comunicación más confiable, debe probar el protocolo SPI.
I2C con PIC16F877a usando el compilador XC8
Basta de presentaciones, entremos en él y aprendamos cómo podemos usar un microcontrolador para realizar la comunicación I2C. Antes de comenzar, aclare que este tutorial solo habla de I2C en PIC16F877a usando el compilador XC8, el proceso será el mismo para otros microcontroladores, pero es posible que se requieran pequeños cambios. También recuerde que para microcontroladores avanzados como la serie PIC18F, el compilador en sí puede tener alguna biblioteca incorporada para usar las funciones I2C, pero para PIC16F877A no existe nada de eso, así que construyamos uno por nuestra cuenta. La biblioteca explicada aquí se proporcionará como un archivo de encabezado para descargar en la parte inferior que se puede usar para que PIC16F877A se comunique con otros dispositivos I2C.
Como siempre, el mejor lugar para comenzar cualquier cosa es nuestra hoja de datos. Busque detalles sobre I2C en la hoja de datos y verifique qué registros deben configurarse. No voy a explicar en detalle ya que la hoja de datos ya lo ha hecho por usted. Más abajo, voy a explicar las diferentes funciones presentes en el archivo de encabezado y su responsabilidad en el programa.
void I2C_Initialize ()
La función de inicialización se usa para decirle al microcontrolador que vamos a usar el protocolo I2C. Esto se puede hacer configurando los bits requeridos en el registro SSPCON y SSPCON2. El primer paso sería declarar los pines IIC como pines de entrada, aquí los pines RC3 y RC4 deben usarse para la comunicación I2C por lo que los declaramos como pines de entrada. A continuación, deberíamos configurar SSPCON y SSPCON2, que es un registro de control MSSP. Estamos operando el PIC en modo maestro IIC con una frecuencia de reloj de FOSC / (4 * (SSPADD + 1)). Consulte los números de página de la hoja de datos mencionada en las líneas de comentarios a continuación para comprender por qué ese registro en particular está configurado de esa manera.
Entonces, a continuación, tenemos que configurar la frecuencia del reloj, la frecuencia del reloj para diferentes aplicaciones puede variar, por lo que obtenemos la elección del usuario a través de la variable feq_k y la usamos en nuestras fórmulas para configurar el registro SSPADD.
void I2C_Initialize (const unsigned long feq_K) // Comenzar IIC como maestro { TRISC3 = 1; TRISC4 = 1; // Establecer pines SDA y SCL como pines de entrada SSPCON = 0b00101000; // pg84 / 234 SSPCON2 = 0b00000000; // pg85 / 234 SSPADD = (_XTAL_FREQ / (4 * feq_K * 100)) - 1; // Configuración de la velocidad del reloj pg99 / 234 SSPSTAT = 0b00000000; // pg83 / 234 }
Anular I2C_Hold ()
La siguiente función importante es la función I2C_hold , que se utiliza para detener la ejecución del dispositivo hasta que se complete la operación I2C actual. Tendríamos que verificar si las operaciones I2C deben realizarse antes de comenzar cualquier nueva operación. Esto se puede hacer comprobando el registro SSPSTAT y SSPCON2. El SSPSTAT contiene la información sobre el estado del bus I2C.
El programa puede parecer un poco complicado ya que incluye un operador "y" y "o". Cuando lo rompes como
SSPSTAT y 0b00000100 SSPCON2 y 0b00011111
Significa que nos estamos asegurando de que el 2º bit en SSPSTAT sea cero y, de manera similar, los bits del 0 al 4 sean cero en SSPCON2. Luego combinamos todos estos para verificar que el resultado sea cero. Si el resultado es cero, el programa continuará si no que permanece anclado a ella hasta que se pone a cero ya que se utiliza en un tiempo bucle.
void I2C_Hold () { while ((SSPCON2 & 0b00011111) - (SSPSTAT & 0b00000100)); // verifique esto en los registros para asegurarse de que la IIC no esté en curso }
Anular I2C_Begin () y anular I2C_End ()
Cada vez que escribimos o leemos cualquier dato usando el bus I2C , debemos comenzar y finalizar la conexión I2C. Para iniciar una comunicación I2C tenemos que configurar el bit SEN y para finalizar la comunicación tenemos que configurar el bit de estado PEN. Antes de alternar cualquiera de estos bits, también deberíamos verificar si el bus I2C está ocupado usando la función I2C_Hold como se discutió anteriormente.
anular I2C_Begin () { I2C_Hold (); // Mantenga el programa si I2C está ocupado SEN = 1; // Comenzar IIC pg85 / 234 } void I2C_End () { I2C_Hold (); // Mantenga el programa si I2C está ocupado PEN = 1; // Fin de IIC pg85 / 234 }
Void I2C_Write ()
La función de escritura se utiliza para enviar cualquier dato desde el módulo maestro al módulo salve. Esta función se utiliza normalmente después de una función de inicio I2C y va seguida de una función de fin I2C. Los datos que deben escribirse en el bus IIC se pasan a través de los datos variables. Luego, estos datos se cargan en el registro de búfer SSPBUF para enviarlos a través del bus I2C.
Normalmente, antes de escribir un dato, se escribirá una dirección, por lo que tendrá que usar la función de escritura dos veces, una para configurar la dirección y otra para enviar los datos reales.
anular I2C_Write (datos sin firmar) { I2C_Hold (); // Mantenga el programa está I2C está ocupado SSPBUF = datos; // pg82 / 234 }
corto sin firmar I2C_Read ()
La función final que debemos conocer es la función I2C_Read . Esta función se utiliza para leer los datos que se encuentran actualmente en el bus I2C. Se utiliza después de pedirle a un esclavo que escriba algún valor en el bus. El valor que se reciba estará en la SSPBUF podemos transferir ese valor a cualquier variable para nuestra operación.
Durante una comunicación I2C, el esclavo después de enviar los datos solicitados por el maestro enviará otro bit que es el bit de reconocimiento, este bit también debe ser verificado por el maestro para asegurarse de que la comunicación fue exitosa. Después de verificar el acuse de recibo del bit ACKDT, debe habilitarse estableciendo el bit ACKEN.
unsigned short I2C_Read (unsigned short ack) { unsigned short entrante; I2C_Hold (); RCEN = 1; I2C_Hold (); entrante = SSPBUF; // obtener los datos guardados en SSPBUF I2C_Hold (); ACKDT = (ack)? 0: 1; // verifica si se recibió un bit de confirmación ACKEN = 1; // pg 85/234 return entrante; }
Es decir, estas funciones deberían ser suficientes para configurar una comunicación I2C y escribir o leer datos de un dispositivo. También tenga en cuenta que hay muchas otras funcionalidades que la comunicación I2C puede realizar, pero en aras de la simplicidad no las estamos discutiendo aquí. Siempre puede consultar la hoja de datos para conocer el funcionamiento completo del
El código completo con el archivo de encabezado para la comunicación PIC16F877A I2C se puede descargar desde el enlace.
Programación usando los archivos de encabezado I2C:
Ahora que hemos aprendido cómo funciona una comunicación I2C y cómo podemos usar el archivo de encabezado creado para ella, creemos un programa simple en el que usaremos el archivo de encabezado y escribiremos algunos valores en las líneas I2C. Luego simularemos este programa y comprobaremos si estos valores se están escribiendo en el bus.
Como siempre, el programa comienza configurando los bits de configuración y configurando la frecuencia del reloj en 20 MHz como se muestra a continuación.
#pragma config FOSC = HS // Bits de selección del oscilador (oscilador HS) #pragma config WDTE = OFF // Bit de habilitación del temporizador de vigilancia (WDT deshabilitado) #pragma config PWRTE = ON // Bit de habilitación del temporizador de encendido (PWRT habilitado) # pragma config BOREN = ON // Brown-out Reset Enable bit (BOR habilitado) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 es E / S digital, HV encendido MCLR debe usarse para la programación) #pragma config CPD = OFF // Bit de protección de código de memoria EEPROM de datos (protección de código EEPROM de datos desactivada) #pragma config WRT = OFF // Bits de habilitación de escritura de memoria de programa flash (protección de escritura desactivada; toda la memoria de programa puede ser escrito por EECON control) #pragma config CP = OFF // Bit de protección de código de memoria de programa flash (protección de código desactivada) #define _XTAL_FREQ 20000000
El siguiente paso sería agregar el archivo de encabezado del que acabamos de hablar. El archivo de encabezado se llama PIC16F877a_I2C.hy se puede descargar desde el enlace que discutimos anteriormente. Asegúrese de que el archivo de encabezado se agregue en el archivo de encabezado de la lista de su proyecto, la estructura del archivo de su proyecto debería verse así
Después de asegurarse de que el archivo de encabezado se agregue a su archivo de proyecto, incluya el archivo de encabezado en el archivo C principal
#incluir
Dentro del tiempo de bucle que comenzaremos las comunicaciones I2C escribir unos valores aleatorios al bus I2C y luego Finalizar la comunicación I2C. Los valores aleatorios que he elegido son D0, 88 y FF. Puede ingresar los valores que desee. Pero recuerde esos valores ya que los estaremos verificando en nuestra simulación.
while (1) { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0x88); I2C_Write (0xFF); I2C_End (); __delay_ms (1000); }
El programa completo se puede encontrar en la parte inferior de la página, puede usarlo o descargar el archivo zip completo del programa desde aquí. Después de obtener el programa, compílelo y prepárese para la simulación.
Simulación de Proteus:
Proteus tiene un buen instrumento llamado depurador I2C que se puede usar para leer los datos en un bus I2C, así que construyamos un circuito usándolo y verifiquemos si los datos se están escribiendo correctamente. El diagrama de circuito completo se muestra a continuación
Cargue el archivo hexadecimal que fue generado por nuestro programa haciendo doble clic en el Microcontrolador. Luego simule el programa. Notará una ventana emergente que mostrará toda la información sobre el bus I2C. La ventana de nuestro programa se muestra a continuación.
Si observa de cerca los datos que se escriben, puede notar que son los mismos que escribimos en nuestro programa. Los valores son D0, 88 y FF. Los valores se escriben para cada 1 segundo, por lo que el tiempo también se actualiza como se muestra a continuación. La flecha azul indica que está escrito de maestro a esclavo; de lo contrario, estaría apuntando en la dirección opuesta. A continuación se muestra una mirada más cercana a los datos que se envían.
Esto es solo un vistazo de lo que puede hacer I2C, también puede leer y escribir datos en múltiples dispositivos. Cubriremos más sobre I2C en nuestros próximos tutoriales mediante la interfaz de varios módulos que funcionan con el protocolo I2C.
Espero que haya entendido el proyecto y haya aprendido algo útil de él. Si tiene alguna duda, publíquela en la sección de comentarios a continuación o utilice los foros para obtener ayuda técnica.
A continuación se proporciona el código completo; puedes descargar archivos de encabezado con todo el código desde aquí.