Sabemos que existen diversos sistemas de comunicación para transmitir datos entre PICs (comunicación serie, SPI, I2C, etc.). Aquí vamos a desarrollar un sistema de comunicación propio para la transmisión de bytes de datos de un PIC maestro a uno esclavo y viceversa. No se trata de competir con los sistemas estándar de comunicación existentes sino de disponer de un recurso cuando tenemos que transferir datos de un PIC a otro sin demasiadas exigencias. La única condición en el código desarrollado es que ambos PICs, maestro y esclavo, trabajen con la misma frecuencia de reloj.
El proceso se ha pensado para un bus de 4 líneas:
- Mx_pin es unidireccional y transfiere
información del PIC Maestro al PIC Esclavo.
- Ex_pin hace la misma función que el anterior
pero la transferencia es del PIC Esclavo al Maestro.
- Inicio_pin también es unidireccional y se emplea para avisar al PIC
Esclavo desde el Maestro de que se va a producir una transferencia de
información.
- Sincro_pin es bidireccional y su misión es sincronizar
el envío de información de uno de los PIC con su recepción por el
otro PIC.
Para enviar un byte al Esclavo, el PIC
maestro comienza el proceso poniendo a '1' Inicio_pin. Este pulso alerta al PIC
esclavo para atender la petición del maestro. Previamente, el maestro ha
asegurado el Mx_pin a '0' .
Cuando el Esclavo atiende a la solicitud, lee el estado del Mx_pin. Un '0' significa que el maestro le
va a enviar un byte de datos. Un '1' significa que el maestro le va a solicitar leer un byte de datos.
Cuando el esclavo ya ha accedido a la solicitud del maestro y leído el estado del
Mx_pin, da un pulso en el Sincro_pin para avisar al maestro de que puede mandarle el primer bit del byte a transmitir, comenzando por el
bit más significativo b7. El PIC esclavo espera unos 5 uS para asegurar que el
maestro pase al Mx_pin el siguiente bit. Cuando el esclavo lee el valor vuelve
a dar un pulso en Sincro_pin para avisar al maestro. El proceso se repite para
los 8 bits del byte transmitido. Después de leer el último bit, el esclavo da
un pulso de unos 10uS en el pin Ex_pin
como confirmación de recepción del byte completo.
Para solicitar un byte al Esclavo, el PIC maestro comienza el proceso asegurando el pin Mx_pin a '1' . A continuación da un pulso de
comienzo de comunicación en el pin Inicio_pin. Este pulso alerta al esclavo
para que atienda el requerimiento del maestro. El esclavo lee el estado del pin
Mx_pin. El valor '1' le avisa de que el maestro le solicita un byte para leer. El esclavo confirma
su lectura mediante un pulso en Sincro_pin. En ese momento el control del pin Sincro_pin
pasa al maestro (pasa a ser salida en el maestro y entrada en el esclavo).
Para solicitar un byte al Esclavo, el PIC maestro comienza el proceso asegurando el pin Mx_pin a '
Ahora es el esclavo quien trasmite el byte de
datos bit a bit por Ex_pin y el maestro quien advierte al esclavo de que ya ha
leído el bit en curso mediante un pulso en la linea Sincro_pin.
Finalizada la recepción del byte completo por
el maestro este lo indica con un pulso de 10uS en Mx_pin.
Tanto en el maestro como en el esclavo, la estrategia empleada, a nivel de código para
enviar un byte (8 bits) bit a bit por una única línea, consiste en emplear una variable
de valor inicial 0x80 (0b10000000) con
la que haremos una comparación AND con el byte a enviar. Si el byte a enviar
tiene ese mismo bit a '1' ,
el resultado de la función AND será 1 y si es 0 será 0. Y ese será el valor que
enviaremos del bit. Rotaremos el bit de la variable una posición (0b01000000=>
mascara = 0x40) para comparar el siguiente bit del byte (b6) y así
sucesivamente para los 8 bits.
int mascara = 0x80;
/**
Envío del byte de datos **/
for
(bit=8; bit>=1; bit--){
//Para los 8 bits
if
((dato & mascara)>0) output_high(Mx_pin); //Si bit en curso es 1
else
output_low (Mx_pin); //Si
bit en curso es 0
mascara = mascara >> 1; //Preparación proximo bit
}
Al otro lado está el PIC que recibe el byte bit a bit. Cuando el bit recibido es 0
realiza una función OR entre la variable temporal (que inicialmente tiene valor 0)
y la constante mascara0 (con valor 0b00000000). Cuando el bit recibido es 1
realiza la función OR entre la variable temporal y la constante mascara1. Rota una
posición los bits de la variable temporal y vuelve a recibir el siguiente bit. Así hasta los 8 bits.
int mascara0 = 0;
int mascara1 = 0x01;
int temporal = 0;
/** Lectura de los 8 bits del byte enviado **/
for (bit=8; bit>=1; bit--){
delay_us (5);
if (input_state (Ex_pin))
temporal|=mascara1; //Si bit
recibido es 1
else temporal|=mascara0; //Si bit recibido es
0
DatoE_RyP_COM=temporal;
//Guarda recepción
temporal = temporal << 1 ;
//Preparación para recibir siguiente bit
}
Todas las funciones necesarias para realizar la comunicacion entre los dos PICs se ha incluido en una librería <RyP_COM.c> que es la que deberemos llamar en el código principal.
Previamente deberemos definir si el PIC lo vamos a utilizar como Maestro...
O como esclavo...
También deberemos definir, antes de cargar la librería, los pines del bus a emplear. Se pueden elegir los que se deseen pero, sino se especifica ninguno, la librería cargará los que tiene por defecto.
En el código del PIC maestro, para enviar un byte al esclavo, llamaremos a la función...
Donde "Dato_Maestro" será la variable que contiene el byte a enviar.
Cuando lo que se quiere es leer un byte del esclavo, la función es...
El byte recibido se almacena en la variable "Dato_Esclavo".Los nombres de las variables se pueden elegir a voluntad.
En el esclavo, la función a invocar es...
Se encarga de testear las posibles solicitudes del PIC maestro. En la variable "Dato_Maestro" se almacena el byte recibido y se envía el byte contenido en "Dato_Esclavo". También para esta función los nombres de las variables se pueden elegir a voluntad, siempre y cuando sean previamente declaradas.
El código de ejemplo aquí mostrado es una muestra de su uso. El PIC Maestro lee el valor de su conversor A/D y lo envía al Esclavo. De la misma forma solicita el valor de la lectura del conversor A/D del Esclavo. Ambas lecturas se muestran en los displays de los respectivos PICs.
En esta animación vemos su funcionamiento y las señales generadas.
#include <RyP_COM.c>
Previamente deberemos definir si el PIC lo vamos a utilizar como Maestro...
#define MASTER 1 //PIC como Maestro
O como esclavo...
#define SLAVE 1 //PIC como Esclavo
También deberemos definir, antes de cargar la librería, los pines del bus a emplear. Se pueden elegir los que se deseen pero, sino se especifica ninguno, la librería cargará los que tiene por defecto.
#define Mx_pin PIN_B1
#define Ex_pin PIN_B2
#define Inicio_pin PIN_B3
#define Sincro_pin PIN_B4
#define Ex_pin PIN_B2
#define Inicio_pin PIN_B3
#define Sincro_pin PIN_B4
En el código del PIC maestro, para enviar un byte al esclavo, llamaremos a la función...
Tx_RyP_COM (Dato_Maestro); //Envío de un dato al esclavo
Donde "Dato_Maestro" será la variable que contiene el byte a enviar.
Cuando lo que se quiere es leer un byte del esclavo, la función es...
Rx_RyP_COM (Dato_Esclavo); //Solicitud de dato al esclavo
El byte recibido se almacena en la variable "Dato_Esclavo".Los nombres de las variables se pueden elegir a voluntad.
En el esclavo, la función a invocar es...
Test_RyP_COM (Dato_Esclavo, Dato_Maestro);
Se encarga de testear las posibles solicitudes del PIC maestro. En la variable "Dato_Maestro" se almacena el byte recibido y se envía el byte contenido en "Dato_Esclavo". También para esta función los nombres de las variables se pueden elegir a voluntad, siempre y cuando sean previamente declaradas.
El código de ejemplo aquí mostrado es una muestra de su uso. El PIC Maestro lee el valor de su conversor A/D y lo envía al Esclavo. De la misma forma solicita el valor de la lectura del conversor A/D del Esclavo. Ambas lecturas se muestran en los displays de los respectivos PICs.
En esta animación vemos su funcionamiento y las señales generadas.
[+/-] Ver / Ocultar código PIC Maestro
Los archivos del proyecto se pueden descargar en este enlace:
El proyecto contenido en el artículo ha sido diseñado y probado con éxito utilizando las siguientes versiones de software:
- Windows 10 (64 bits)
- Proteus V7.7 SP2
- CCS PIC C COMPILER v5.015
- Windows 10 (64 bits)
- Proteus V7.7 SP2
- CCS PIC C COMPILER v5.015
No hay comentarios:
Publicar un comentario