Hola, soy nuevo en el foro.
Vereis tengo una duda, estoy trabajando en un proyecto con 2 PIC'S 18f2550, intento comunicarlos por I2C pero nose que hare mal por que no funciona. El primer pic realiza el control de unos motores mediante una señal PWM mientras que el otro se encarga de obtener medidas para indicar que accion debe realizar el otro pic.
El problema viene aqui nada mas empezar :S no consigo hacer que se comuniquen los dichosos chips, podeis hecharme una ayudita?
estos son los codigos:
MAESTRO
ESCLAVO
Como podeis ver faltan las funciones de obtener el valor de los receptores, pero estoy inicializando los valores de la posicion_servo1 y 2 a un valor y este valor no se trasmite al otro pic. el maestro si que parece que emita la transmision I2C pero el esclavo no hace nada, me e equivocado con la #int_ssp? alguno sabe por que no funciona?
Gracias de antemano.
Vereis tengo una duda, estoy trabajando en un proyecto con 2 PIC'S 18f2550, intento comunicarlos por I2C pero nose que hare mal por que no funciona. El primer pic realiza el control de unos motores mediante una señal PWM mientras que el otro se encarga de obtener medidas para indicar que accion debe realizar el otro pic.
El problema viene aqui nada mas empezar :S no consigo hacer que se comuniquen los dichosos chips, podeis hecharme una ayudita?
estos son los codigos:
MAESTRO
Código:
#include <18F2550.h>
#fuses HS,USBDIV,PLL5
#use delay(clock=20000000)
#use I2C(MASTER, sda=PIN_B0, scl=PIN_B1, FAST, FORCE_HW)
//////////////////////////////////////////////////////////////////////
////////////////////////////DEFINES///////////////////////////////////
//////////////////////////////////////////////////////////////////////
#define ENCENDER output_high
#define APAGAR output_low
#define LED_PIC PIN_C6
//////////////////////////////////////////////////////////////////////
///////////////////////////VARIABLES//////////////////////////////////
//////////////////////////////////////////////////////////////////////
int posicion_servo1 = 0;
int posicion_servo2 = 0;
/////////////////////////////////////////////////////////////////////
///////////////////////////INTERRUPCIONES////////////////////////////
/////////////////////////////////////////////////////////////////////
#INT_TIMER2
void PWM_movimiento_servos(void)
{
//mirar de mejorar el movimiento de los servos
}
/////////////////////////////////////////////////////////////////////
/////////////////////////////FUNCIONES///////////////////////////////
/////////////////////////////////////////////////////////////////////
void escribir_i2c(BYTE direccion, int dato)
{
i2c_start();
i2c_write(direccion);
i2c_write(dato);
i2c_stop();
delay_us(50);
}
int leer_i2c(BYTE direccion, int opcion)
{
int dato = 0;
i2c_start();
i2c_write(direccion);
i2c_write(opcion);
i2c_start();
i2c_write(direccion+1);
dato = i2c_read();
i2c_stop();
return(dato);
}
void parpadeo()
{
ENCENDER(LED_PIC);
delay_ms(500);
APAGAR(LED_PIC);
delay_ms(500);
}
/////////////////////////////////////////////////////////////////////
///////////////////////////////MAIN//////////////////////////////////
/////////////////////////////////////////////////////////////////////
void main(void)
{
setup_timer_2(T2_DIV_BY_1,249,2); //inicializacion de las interrupciones del timer 2 a 0.1 ms cada una
set_timer2(0); //inicializar a 0 el timer2
delay_ms(1000); //esperamos 1 segundo que para asegurarnos que se inicialice toda la placa antes de empezar la fiesta
enable_interrupts(INT_TIMER2); //interrupcion del timer 2
enable_interrupts(GLOBAL); //habilitamos las interrupciones
while(TRUE)
{
posicion_servo1 = leer_i2c(0xa0, 1); //leer posicion en la que debe situarse el servo 1
posicion_servo2 = leer_i2c(0xa0, 2); //leer posicion en la que debe situarse el servo 1
};
}
ESCLAVO
Código:
#include <18F2550.h>
#fuses HS,USBDIV,PLL5
#use delay(clock=20000000)
#use I2C(SLAVE, sda=PIN_B0, scl=PIN_B1, ADDRESS= 0xa0, FAST, FORCE_HW)
//////////////////////////////////////////////////////////////////////
////////////////////////////DEFINES///////////////////////////////////
//////////////////////////////////////////////////////////////////////
#define ENCENDER output_high
#define APAGAR output_low
#define LED_PIC PIN_C6
//////////////////////////////////////////////////////////////////////
///////////////////////////VARIABLES//////////////////////////////////
//////////////////////////////////////////////////////////////////////
BYTE i2c_dato_entrada; //dato que se escribe mediante I2C
BYTE direccion = 0x00;
int posicion_servo1 = 0;
int posicion_servo2 = 0;
/////////////////////////////////////////////////////////////////////
///////////////////////////INTERRUPCIONES////////////////////////////
/////////////////////////////////////////////////////////////////////
#INT_SSP
void ssp_interupt () //salta una interrupcion y nos disponemos a tratarla
{
byte temp, i2c_estado, i2c_dato_funcion;
i2c_estado = i2c_isr_state(); //leemos el valor del isr (el que nos indica que accion debemos tratar, o bien leer o bien escribir)
if(i2c_estado <0x80) //el master te esta enviando informacion por lo que debemos leer lo que nos dice
{
temp = i2c_read();
if(i2c_estado == 1)
{
direccion = temp;
}
if(i2c_estado == 2)
{
//este dato puede ser o bien la funcion a realizar o bien el valor que queremos introducir al pic mediante I2C
i2c_dato_entrada = i2c_read(); //leemos "dato" del master, si hubieran mas datos habria que hacer mas reads, en nuestro caso solo leemos un byte por cada funcion de lectura en el esclavo (el master es el que escribe)
}
}
if(i2c_estado >= 0x80) //el master esta pidiendonos un dato con lo que debemos responderle con un write
{
i2c_dato_funcion = i2c_dato_entrada;
if(i2c_dato_funcion == 1) //el master nos pide la posicion del servo1
{
i2c_write(posicion_servo1);
}
if(i2c_dato_funcion == 2) //el master nos pide la posicion del servo2
{
i2c_write(posicion_servo2);
}
}
}
/////////////////////////////////////////////////////////////////////
/////////////////////////////FUNCIONES///////////////////////////////
/////////////////////////////////////////////////////////////////////
int posicion_servo1_mediante_triangulacion(int receptor1,int receptor3, int posicion_servo1)
{
if(receptor1 < receptor3)
{
posicion_servo1 = posicion_servo1 + 1;
}
else if(receptor1 > receptor3)
{
posicion_servo1 = posicion_servo1 - 1;
}
return(posicion_servo1);
}
int posicion_servo2_mediante_triangulacion(int receptor2,int receptor3, int posicion_servo2)
{
if(receptor3 < receptor2)
{
posicion_servo2 = posicion_servo2 - 1;
}
else if(receptor3 > receptor2)
{
posicion_servo2 = posicion_servo2 + 1;
}
return(posicion_servo2);
}
/////////////////////////////////////////////////////////////////////
///////////////////////////////MAIN//////////////////////////////////
/////////////////////////////////////////////////////////////////////
void main(void)
{
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(TRUE)
{
};
}
Como podeis ver faltan las funciones de obtener el valor de los receptores, pero estoy inicializando los valores de la posicion_servo1 y 2 a un valor y este valor no se trasmite al otro pic. el maestro si que parece que emita la transmision I2C pero el esclavo no hace nada, me e equivocado con la #int_ssp? alguno sabe por que no funciona?
Gracias de antemano.