Autor Tema: Ayuda con I2C, el maestro no lee correctamente el esclavo  (Leído 1588 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado exodusrock

  • PIC10
  • *
  • Mensajes: 2
Ayuda con I2C, el maestro no lee correctamente el esclavo
« en: 12 de Septiembre de 2009, 19:44:06 »
Hola amigos, mi proyecto es el siguiente, tengo un maestro y dos esclavos conectados por medio de I2C, un esclavo se encarga de leer unos sensores que los simulo con botones y led's, (al pulsar el botón se prende el led, así el sensor estaría "prendido") simplemente tengo que leer con el maestro y decir si están prendidos o apagados , ademas que debo leer también dos potenciometros y decir el respectivo voltaje en que están y publicar estos datos en una lcd, el otro esclavo varia con un potenciometro la velocidad de un motor dc con pwm, y desde el maestro también le puedo variar la velocidad.

En la simulación en proteus el segundo esclavo funciona a la perfección, pero al leer el buffer del primero siempre publica que están apagados los sensores así los led's estén prendidos, también al publicar el voltaje de los pot siempre me muestra el mismo valor así varié dichos potenciometros. no se si sera la interrupción en el esclavo pues solo se que se utiliza para esta comunicación.

Publico el codigo del maestro y del esclavo. Me gustaría que me ayudaran a encontrar el error, pues ya llevo dos días intentándolo y nada que funciona


--------------------maestro-----------------------

#include <16F877A.h>
#device ADC=8
#fuses HS,NOWDT,NOLVP,PUT
#use delay (clock=20000000)
#include <lcd.c>
#include <kbd_lib.c>
#use i2c (master, sda=pin_C4, scl=pin_c3)
#byte    SSPCON = 0x14

void lectura(void);
void toma_adc(void);
char c;
int valor;
int a,b,e,d;
int pot1,pot2;
float cte=0.01953125, vol1,vol2;

void main(){
   lcd_init();
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(all_ANALOG);

   while(true){
      c=kbd_getc();
      toma_adc();
      i2c_start();
      i2c_write(0xb0);   // direccion de slave
      i2c_write(0x00);   // posicion del buffer
      i2c_write(valor);    //siempre envio el dato de la conversion
      i2c_stop();
      delay_ms(20);

      if(c==0){}   //...pulsar una tecla
      else if(c=='D'){      // habilita el control remoto y varia velocidad motor
         lcd_putc("\fcontrol\nremoto!!");
         i2c_start();
         i2c_write(0xb0); // direccion de slave
         i2c_write(0x01); // posicion del buffer
         i2c_write(1);       //bandera por la que preguntare en el esclavo
         i2c_stop();
         delay_ms(20);
      }
      else if(c=='C'){      //habilita el control local
         lcd_putc("\fcontrol\nlocal!!");
         i2c_start();
         i2c_write(0xb0); // direccion de slave
         i2c_write(0x01); // posicion del buffer
         i2c_write(0);    //bandera por la que preguntare en el esclavo
         i2c_stop();
         delay_ms(20);
      }
      else if(c=='B'){      //lee los sensores del esclavo
         lectura();
         lcd_putc("\f");
         if(a==1){
            lcd_gotoxy(1,1);
            printf(Lcd_putc, "S1= on");
         }
         else{
            lcd_gotoxy(1,1);
            printf(Lcd_putc, "S1= off");
         }
         if(b==1){
            lcd_gotoxy(9,1);
            printf(lcd_putc, "S2= on");
         }
         else{
            lcd_gotoxy(9,1);
            printf(lcd_putc, "S2= off");
         }
         if(d==1){
            lcd_gotoxy(1,2);
            printf(lcd_putc, "S3= on");
         }
         else{
            lcd_gotoxy(1,2);
            printf(lcd_putc, "S3= off");
         }
         if(e==1){
            lcd_gotoxy(9,2);
            printf(lcd_putc, "S4= on");
         }
         else{
            lcd_gotoxy(9,2);
            printf(lcd_putc, "S4= off");
         }
      }
      else if(c=='E'){      //lee los pot del esclavo
         delay_ms(10);
         i2c_start();
         i2c_write(0xa0);       // direccion de slave1
         i2c_write(0x04);
         i2c_start();
         i2c_write(0xa0+1);
         pot1=i2c_read(0);
         i2c_stop();
         delay_ms(20);

         i2c_start();
         i2c_write(0xa0);       // direccion de slave2
         i2c_write(0x05);
         i2c_start();
         i2c_write(0xa0+1);
         pot2=i2c_read(0);
         i2c_stop();
         delay_ms(10);

         vol1=cte*pot1;      // convierto el valor de la conversion.....
         vol2=cte*pot2;      //.......a su correspondiente voltaje
         printf(lcd_putc, "\fpot 1: %f V\npot 2: %f V",vol1,vol2);
      }
   }

}
void lectura(void){
      //delay_ms(10);
      i2c_start();
      i2c_write(0xa0); // direccion de slave
      i2c_write(0x00);    // direccion del buffer
      i2c_start();
      i2c_write(0xa0+1);
         a=i2c_read(0);
      i2c_stop();
      delay_ms(20);

      i2c_start();
      i2c_write(0xa0);
      i2c_write(0x01);      //direccion del buffer
      i2c_start();
      i2c_write(0xa0+1);
         b=i2c_read(0);
      i2c_stop();
      delay_ms(20);

      i2c_start();
      i2c_write(0xa0);
      i2c_write(0x02);      //direccion del buffer
      i2c_start();
      i2c_write(0xa0+1);
         d=i2c_read(0);
      i2c_stop();
      delay_ms(20);

      i2c_start();
      i2c_write(0xa0);
      i2c_write(0x03);      //direccion del buffer
      i2c_start();
      i2c_write(0xa0+1);
         e=i2c_read(0);
      i2c_stop();
      delay_ms(10);
}

void toma_adc(void){
   set_adc_channel(0);
   delay_ms(1);
   valor=read_adc();
   delay_ms(1); //para que se estabilice
}





---------------esclavo sensor---------------

#include <16F877A.h>
#device ADC=8
#fuses xt,NOWDT,NOLVP,PUT
#use delay (clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0)
#byte    SSPCON = 0x14

void toma_adc0(void);
void toma_adc1(void);
typedef enum {NOTHING, CONTROL_READ,ADDRESS_READ, READ_COMMAND_READ} I2C_STATE;

int con1, con2;
I2C_STATE fState;
BYTE address, buffer[0x06], recibe;

#INT_SSP
void ssp_interupt (){
   if (i2c_poll() == FALSE) {
      if (fState == ADDRESS_READ) {  //i2c_poll() returns false on the
         i2c_write (buffer[address]);//interupt receiving the second
         fState = NOTHING;           //command byte for random read operation
      }
   }
   else {
      recibe = i2c_read(0);

      if (fState == NOTHING){
         fState = CONTROL_READ;
      }
      else if (fState == CONTROL_READ) {
         address = recibe;
         fState = ADDRESS_READ;
      }
      else if (fState == ADDRESS_READ) {
         buffer[address] = recibe;
         fState = NOTHING;
      }
   }
}

void main (){
   fState = NOTHING;
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(all_ANALOG);

   while(true){
      if (input(pin_D4)==1){      //pregunto por los botones
            output_high(pin_B0);
            buffer[0x00]=1;
      }
      else {
            output_low(pin_B0);
            buffer[0x00]=0;
      }


      if (input(pin_D5)==1){
            output_high(pin_B1);
            buffer[0x01]=1;
      }
      else {
            output_low(pin_B1);
            buffer[0x01]=0;
      }


      if (input(pin_D6)==1){
            output_high(pin_B2);
            buffer[0x02]=1;
      }
      else {
            output_low(pin_B2);
            buffer[0x02]=0;
      }


      if (input(pin_D7)==1){
            output_high(pin_B3);
            buffer[0x03]=1;
      }
      else {
            output_low(pin_B3);
            buffer[0x03]=0;
      }


      if (bit_test(SSPCON,6)){
         bit_clear (SSPCON,6);
         recibe = i2c_read(0);
      }
      toma_adc0();
      buffer[0x04]=con1;
      toma_adc1();
      buffer[0x05]=con2;
   }
}


void toma_adc0(void){
   set_adc_channel(0);
   delay_ms(1);
   con1=read_adc();
   delay_ms(1); //para que se estabilice
}
void toma_adc1(void){
   set_adc_channel(1);
   delay_ms(1);
   con2=read_adc();
   delay_ms(1); //para que se estabilice
}

---------------esclavo motor--------------------

#include <16f877a.h>
#device ADC=8
#fuses XT,NOWDT,NOLVP,PUT
#use delay (clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xb0)
#byte    SSPCON = 0x14


void toma_adc(void);
typedef enum {NOTHING, CONTROL_READ,ADDRESS_READ, READ_COMMAND_READ} I2C_STATE;

byte valor0,valor1;
I2C_STATE fState;
BYTE address, buffer[0x02],recibe,flag;

#INT_SSP
void ssp_interupt (){
   if (i2c_poll() == FALSE) {
      if (fState == ADDRESS_READ) {  //i2c_poll() returns false on the
         i2c_write (buffer[address]);//interupt receiving the second
         fState = NOTHING;           //command byte for random read operation
      }
   }
   else {
      recibe = i2c_read(0);

      if (fState == NOTHING){
         fState = CONTROL_READ;
      }
      else if (fState == CONTROL_READ) {
         address = recibe;
         fState = ADDRESS_READ;
      }
      else if (fState == ADDRESS_READ) {
         buffer[address] = recibe;
         fState = NOTHING;
      }
   }
}

void main (){
   fState = NOTHING;
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);
   setup_adc_ports(all_ANALOG); //entrada 0 como analogica
   setup_adc(ADC_CLOCK_INTERNAL); //configura el conversor
   setup_ccp1(ccp_pwm);
   setup_timer_2(t2_div_by_1,255,1);
   set_pwm1_duty(0);

   while(true){
      if (bit_test(SSPCON,6)){
         bit_clear (SSPCON,6);
         recibe = i2c_read();
      }
      toma_adc();
      valor1=buffer[0x00];
      flag=buffer[0x01];
      if(flag==0){
         set_pwm1_duty(valor0);
         output_high(pin_B0);
         output_low(pin_B1);
      }
      else if(flag==1){
         set_pwm1_duty(valor1);
         output_high(pin_B1);
         output_low(pin_B0);
      }
   }
}

void toma_adc(void){
   set_adc_channel(0);
   delay_ms(1);
   valor0=read_adc();
   delay_ms(1); //para que se estabilice
}


pido disculpas por las molestias causadas y por el post tan largo
pero en verdad necesito ayuda!!!!
Gracias


 

anything