Conflicto timer0 e I2C pic16f877a

Saludos compañeros, como el titulo lo dice, tengo problemas con mi proyecto.

Como antecedentes ya logre la comunicación via I2C entre 4 microcontroladores, 1 maestro (pic18f4550) y 3 esclavos (pic18f452, pic16f877a y pic16f877), pero en la programación de uno de ellos (pic15f877a el cual controla 8 servos) el programa funciona correctamente, pero al agregar el código para la comunicacion I2C la lectura que obtengo del máster es inconsistente ya que el dato que recibe es correcto pero al generarse la interrupción del timer0 el dato obtenido del máster es incorrecto.

Y así continua fluctuando entre dato correcto e incorrecto cada interrupción del timer0 :unsure:

adjunto el programa:

Código:
#include <16f877a.h>                   
#fuses  XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP       

#use delay(clock=4000000)              

#byte portb=0x06
#byte trisb=0x86

#include <lcd.c>                       
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0XA0, slow , FORCE_HW)


#bit  Bit_PWM0 =  PORTb.0              
#bit  Bit_PWM1 =  PORTb.1              
#bit  Bit_PWM2 =  PORTb.2              
#bit  Bit_PWM3 =  PORTb.3              
#bit  Bit_PWM4 =  PORTb.4              
#bit  Bit_PWM5 =  PORTb.5              
#bit  Bit_PWM6 =  PORTb.6              
#bit  Bit_PWM7 =  PORTb.7              


void main (void);             
void Generador_pwm (void);   
int8 control_PWM=0,dato;
int8 PWM0=0,PWM1=0,PWM2=0,PWM3=0,PWM4=0,PWM5=0,PWM6=0,PWM7=0; 

#int_Timer0

void Generador_pwm(){
  
  control_PWM++;
 
      Bit_PWM0=1;      
      Bit_PWM1=1;
      Bit_PWM2=1;
      Bit_PWM3=1;
      Bit_PWM4=1;
      Bit_PWM5=1;
      Bit_PWM6=1;
      Bit_PWM7=1;
   }
   
   if (control_PWM==PWM0) Bit_PWM0=0;
   if (control_PWM==PWM1) Bit_PWM1=0;
   if (control_PWM==PWM2) Bit_PWM2=0;
   if (control_PWM==PWM3) Bit_PWM3=0;
   if (control_PWM==PWM4) Bit_PWM4=0;
   if (control_PWM==PWM5) Bit_PWM5=0;
   if (control_PWM==PWM6) Bit_PWM6=0;
   if (control_PWM==PWM7) Bit_PWM7=0;
  
   set_timer0(255);                    
}

void main(){

   set_tris_b(0x00);                  
   
   pwm0=11;                      
   pwm1=11; 
   pwm2=11; 
   pwm3=11; 
   pwm4=11; 
   pwm5=11; 
   pwm6=11;
   pwm7=11;
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);         
   enable_interrupts(INT_TIMER0);    
   enable_interrupts(GLOBAL);        
   
   lcd_init();             
     
   while (true){
   
               lcd_gotoxy(5,1);
               printf(lcd_putc,"El numerito es");
               lcd_gotoxy(5,2);
               printf(lcd_putc,"%i",dato);
          
               dato=i2c_read();
       
       }
}

Cabe recordar que el programa funciona correctamente sin agregar el código del I2C.
Y si empleo en el codigo la función i2c_poll() el programa no anda para nada.:confused::enfadado:

Código:
if(i2c_poll())
            {
                dato=i2c_read();
            }
El circuito ya lo tengo armado en la protoaboard y simulado en ISIS de proteus y en los dos obtengo el mismo resultado.:cry:

Adjunto los archivos de Proteus y los programas de CCS.

si alguien me puede dar algún consejo u orientación en el tema se lo agradeceré por siempre, ya que solo es esto lo que me detiene para concluir mi proyecto.(y);)
 

Adjuntos

  • i2c prueba pic16f877a.rar
    27.1 KB · Visitas: 10
  • programas ccs.rar
    1.6 KB · Visitas: 8
Última edición:
Trabajando con el programa me di cuenta que no es conflicto con el timer0, yo estaba equivocado al culpar al timer0, pero el problema se encuentra en la recepción de los datos del maestro ayer me decidí a realizar un programa de prueba solo de comunicacion I2C el cual envía del maestro al esclavo únicamente datos empezando con un solo dato y este si que trabaja bien, pero al agregar otro dato el esclavo no recibe los datos correctos, en un proyecto anterior emplee comunicacion SPI en el cual pude enviar un conjunto de variables al mismo tiempo y para I2C, quise usar la misma metodología, pero la verdad no se si esta es la manera de enviar las variables de maestro a esclavo, adjunto el programa de prueba.


MAESTRO:
Código:
#include <18f4550.h>
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
#device adc=8
#use delay(clock=4000000)
#include <lcd.c>
#use i2c(MASTER,SDA=PIN_B0,SCL=PIN_B1,slow,FORCE_HW)


int8 dato1;
int8 dato2;
int8 dato3;
int8 dato4;
int8 dato5;
int8 dato6;
int8 dato7;
int8 dato8;
void i2cdatos(void);

void i2cdatos()
{
               i2c_start();
               i2c_write(0xa0);
               i2c_write(dato1);     //enviamos un dato, p.e el entero 6
               i2c_write(dato2);
               i2c_write(dato3);
               i2c_write(dato4);
               i2c_write(dato5);
               i2c_write(dato6);
               i2c_stop();
               delay_ms(1000);
}

void main(void)
{
   
   lcd_init();
   lcd_gotoxy(5,1);
   printf(lcd_putc,"i2c COM");
   delay_ms(3000);
   printf(lcd_putc,"\f");
      
      while(TRUE)
      {
           
      
      
      dato1=104;
      dato2=94;
      dato3=84;
      dato4=74;
      dato5=64;
      dato6=54;
      dato7=44;
      dato8=4;
      
      
      lcd_gotoxy(1,1);
      printf(lcd_putc,"%i, %i, %i, %i",dato1,dato2,dato3,dato4);
      lcd_gotoxy(1,2);
      printf(lcd_putc,"%i, %i, %i, %i",dato5,dato6,dato7,dato8);
      i2cdatos();      
           }
     
}

ESCLAVO:

Código:
#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#include <lcd.c>
#define led        pin_b0
#define led1       pin_b1


#define off OUTPUT_LOW
#define on OUTPUT_HIGH 
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0xa0, slow , FORCE_HW)

int8 PWM0=0,PWM1=0,PWM2=0,PWM3=0,PWM4=0,PWM5=0,PWM6=0,PWM7=0;
void i2cdatos()
{
if (i2c_poll())
{
       pwm0=i2c_read(0);
       pwm1=i2c_read(0);
       pwm2=i2c_read(0);
       pwm3=i2c_read(0);
       pwm4=i2c_read(0);
       pwm5=i2c_read(1);      
}

}

void main(void)
{

      
      
      lcd_init();
      lcd_gotoxy(5,1);
      on (led1);
      lcd_putc("Esperando");
      set_tris_B(0x00);
  
  
  OUTPUT_b(0X00);
  
      while(TRUE)
      {
        
i2cdatos();
       
       printf(lcd_putc,"\f");
       lcd_gotoxy(1,1);
       printf(lcd_putc,"%i,%i,%i,%i",pwm0,pwm1,pwm2,pwm3);
       lcd_gotoxy(1,2);
       printf(lcd_putc,"%i,%i,%i,%i",pwm4,pwm5,pwm6,pwm7);        
              
      }
}


En la simulación

el I2C debugger me muestra que después del primer dato enviado los demas datos entregan un Nak y pues esto no debe pasar
558531_284845351608064_100002478057856_573508_515563637_n.jpg


Si alguien a conseguido enviar mas de una variable a la vez vía I2C agradeceré su consejos.
 
Atrás
Arriba