Hola a todos, es la primera vez que escribo en el foro pero ya hace tiempo que merodeo por aquí. Primero que todo quiero felicitar a todos los del foro, es genial que haya gente como vosotros dispuestos a compartir todo, ojala yo también pueda ayudar con lo que pueda!
Estoy haciendo un proyecto para la universidad, es un control de riego monitorizado vía GSM. El problema en que me encuentro ahora es con el bus I2C, os explico: Tengo una pic central que me hace de master i otras 6 Pics que son los sensores, estas las tengo con slave. Mi problema es que con una sola pic slave todo me funciona perfectamente, cuando conecto las otras pics slaves todo sigue funcionando perfectamente hasta que intento leer los datos de otra pic slave que no sea la inicial. Me explico, inicio el programa (lo estoy simulando con proteus) i todo funciona a la perfección (me llegan los datos de la pic slave a la master perfectamente) la master pide a la slave que le mande el dato y llega sin problemas, el problema me lo encuentro cuando quiero leer de otra pic slave, cambio al address de la nueva slave i el sistema se que queda tirado, a la master no le llega nada... A alguien se le ocurre que puede pasar?¿
He estado haciendo pruebas y creo que el problema esta en el 0 del i2c_read(0); en el código del master. Tengo entendido que un 0 significa que el sistema funciona sin ACK i que con un 1 con ACK (sin nada es por defecto un 1). No se muy bien por que pero cuando pongo un 0 funciona solo con un slave y si pongo cualquier orto valor no me funciona. Es como si la master se quedara esperando que la slave le diera un ACK i no hace nada mas. Alguien sabe como hacer el ACK desde el salve?¿
Espero que alguien me pueda dar una mano... os pongo el código a bajo:
MASTER
#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP,LVP
#use delay(clock=4000000)
#use i2c(MASTER, sda=PIN_C4, scl=PIN_C3,FAST,FORCE_HW)
void init_slave(){
output_float(PIN_C3);
output_float(PIN_C4);
}
//Esta rutina lee un byte desde el esclavo.
//chadd es la direccion del esclavo 0-7 (0xA0 hasta 0xA7).
//address es la posicion de memoria.
//La función devuelve el byte leido.
byte read_slave(byte chadd) {
byte data;
//chadd = (chadd<<1) + 0xa0;
i2c_start();
//chadd = chadd | 1;
i2c_write(chadd);
data=i2c_read(0);
i2c_stop();
delay_us(50);
return(data);
}
void MostraDada(int dada){
set_tris_b(0b00000000); // todo el puerto B como salidas.
delay_ms(25);
output_b(dada);
delay_ms(500);
}
byte QuinSensor(){
byte adressasensor=0;
switch(input_d()){
case 1: adressasensor=0xa1;
output_high(PIN_A0);
break;
case 2: adressasensor=0xb1;
output_high(PIN_A1);
break;
case 4: adressasensor=0xc1;
output_high(PIN_A2);
break;
case 8: adressasensor=0xd1;
output_high(PIN_A3);
break;
case 9: adressasensor=0xe1;
output_high(PIN_A4);
break;
case 10: adressasensor=0xf1;
output_high(PIN_A5);
break;
default:
break;
}
return adressasensor;
}
void main(){
int dada_llegida=4;
byte num_sensor=1;
set_tris_b(0b00000000); // todo el puerto B como salidas.
set_tris_c(0b10000000); // RX como entrada, el resto salidas.
set_tris_d(0b11111111); // com entrades '1'
set_tris_a(0b00000000); //com a sortides
init_slave();
while(TRUE){
num_sensor=QuinSensor();
dada_llegida=read_slave(num_sensor); //Leer el byte en la posicion 0 del esclavo.
MostraDada(dada_llegida);
}
}
SALVE
#include <16F876.h>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#use fast_io(b)
#use I2C(slave,sda=PIN_C4,scl=PIN_C3, ADDRESS=0xa0,FAST,FORCE_HW) //defineixo el bus I2C en mode slave i adressa 0xa0
int llegit;
#INT_SSP
void ssp_interupt(){
BYTE state,incoming,address;
state = i2c_isr_state();
if(state < 0x80) //Master is sending data
{
}
if(state == 0x80) //Master is requesting data
{
i2c_write(llegit);
}
}
void LlegeixADC(){
setup_adc (adc_clock_div_32); //activem el ADC amb
setup_adc_ports (RA0_RA1_RA3_ANALOG); //Configurem els ports analogics; RA0 RA1 i el voltatge de referència 5V
set_adc_channel (0); //escollim el canal a mesurar
delay_us(20); //esperem 20us
llegit=read_adc(); //fem la conversió
output_b(llegit);
setup_adc(adc_off); //apaguem ADC
}
void main(void){
set_tris_b(0b00000000); // todo el puerto B como salidas.
//set_tris_c(0b10011000); // RX, SDA y SCL como entradas, el resto salidas.
output_float(PIN_C3); //I2C pin float
output_float(PIN_C4); //I2C pin float
//Habilito interrupcions del port I2C.
enable_interrupts(INT_SSP);
// Habilito interrupcions Generals
enable_interrupts(GLOBAL);
output_b(0xff);
while(TRUE){
LlegeixADC();
}
}