Autor Tema: Comunicación i2c entre pics (PIC18F y PIC16F)  (Leído 9486 veces)

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

Desconectado Slade

  • PIC10
  • *
  • Mensajes: 9
Comunicación i2c entre pics (PIC18F y PIC16F)
« en: 12 de Enero de 2009, 16:31:01 »
Saludos
     
    Weno esta es la situación, estoy diseñando un driver de LCD usando un PIC16F877A, el cual trabajara dependiendo de como se configure por un dip-sw si la comunicacion es por I2C o por el USART al resetear el pic, cuando lo configuro para I2C y reseteo, en la pantalla sale "I2C INICIADO", he inmediatamente comienza a recibir cualquier dato que le llegue y lo muestra en la pantalla; estoy enviando un solo dato continuamente con el PIC18F4550 (maestro) pero todos los datos que recibe el 16f (esclavo) son 0xFF  :?.
    He probado cambiando la velocidad del master, la ultima configuracion que emplee es 400k, las resistencias de pullups son de 4.7k, y he probado con 3.3k, 2.2k, y 1k, etc. no tengo idea de que pueda ser.... ademas es la primera vez q hago este tipo de comunicacion entre pics y no dispongo de alguna EEPROM o RTC para probar  :(. Otra cosa mas aunq no creo q sea muy importante, estoy alimentando TODO con 4 pilas de NiMH recargables de 1.2V - 2200mA y el compilador que uso es CCS C.

    Aqui les dejo el programa:

------------------------------------ MAESTRO -----------------------------------------------

#include <18F4550.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //Crystal osc <= 4mhz
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT_NOSL            //Brownout enabled during operation, disabled during SLEEP
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES MCLR                     //Master Clear pin enabled
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL1                     //No PLL PreScaler
#FUSES CPUDIV3

#use delay(clock=4000000)
#use i2c(Master,Fast=400000,sda=PIN_B0,scl=PIN_B1,force_hw)
#use fast_io(A)

void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_low_volt_detect(FALSE);
   setup_oscillator(False);

   set_tris_a(0xFE);
   output_a(0);

   while(1)
   {
      i2c_start();
      i2c_write(0x08);        // Esta es la direccion del esclavo
      i2c_write(0x33);        // El dato es 0x33 que en ASCII seria 3

      i2c_stop();
      delay_ms(1000);
   }

}


--------------------------------- ESCLAVO --------------------------------------

#include <16F877A.h>
#include ".\include\lcd_J (2dot0).c"

#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //High speed Osc (> 4mhz)
#FUSES PUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=4000000)

#use fast_io(A)
#use fast_io(E)


int X=0;

void menu()
{
   char ms1[]={"MODO PRUEBA"};
   char ms2[]={"DIP-SW 4  5"};
   char ms3[]={"   I2C 0  1"};
   char ms4[]={" RS232 1  0"};

   send_lcd_ctrl(0x01);delay_ms(10);
   lcd_goto_xy(3,1);lcd_printf(ms1);
   lcd_goto_xy(3,2);lcd_printf(ms2);
   lcd_goto_xy(3,3);lcd_printf(ms3);
   lcd_goto_xy(3,4);lcd_printf(ms4);
}

void mensaje()
{
   enum modo {test,RS232,I2C,test} opc;
   char msi2c[]={"MODO I2C"};
   char msrs232[]={"MODO RS232"};
   char msreset[]={"PRESS  RESET"};

   menu();
   opc=input_a()&0x03;
   do{
      while(opc==(input_a()&0x03)){}
      delay_ms(20);
      opc=input_a()&0x03;
      switch(opc)
      {
         case I2C:
            send_lcd_ctrl(0x01); delay_ms(10);
            lcd_goto_xy(5,2); lcd_printf(msi2c);
            lcd_goto_xy(3,3); lcd_printf(msreset);
            break;

         case RS232:
            send_lcd_ctrl(0x01); delay_ms(10);
            lcd_goto_xy(4,2); lcd_printf(msrs232);
            lcd_goto_xy(3,3); lcd_printf(msreset);
            break;

         default:
            menu();
      }
   }while(1);
}

void main()
{
   int i;
   char mensi2c[]={"I2C INICIADO"};
   char mensrs232[]={"RS232 INICIADO"};
   port_b_pullups(TRUE);
   set_tris_a(0xFF);
   set_tris_e(0xFE);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   output_e(0);
   lcd_port('b');
   init_lcd();

   for(i=0;i<6;i++)
   {
      lcd_goto_xy((3+(i*2)),3); send_lcd('.');
      delay_ms(50);
   }

   switch(input_a()&0x03)
   {
      case 1:

               #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
//               enable_interrupts(INT_RDA);
//               enable_interrupts(GLOBAL);
               send_lcd_ctrl(0x01); delay_ms(10);
               lcd_goto_xy(3,2); lcd_printf(mensrs232);
               break;
      case 2:
               #use i2c(Slave,sda=PIN_C4,scl=PIN_C3,address=0x08,force_hw)
//               enable_interrupts(INT_SSP);
//               enable_interrupts(GLOBAL);
               send_lcd_ctrl(0x01); delay_ms(10);
               lcd_goto_xy(3,2); lcd_printf(mensi2c);
               break;
      default: mensaje();
   }
   delay_ms(500);

   while(1)
   {
      if(i2c_poll())
      {
         X=i2c_read();
 
         send_lcd(X);
      }
   }
}


-------------------------------------------------------------------------------------------


De antemano grax !!!!!!!!  :-/
« Última modificación: 12 de Enero de 2009, 16:38:18 por Slade »

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Comunicación i2c entre pics (PIC18F y PIC16F)
« Respuesta #1 en: 12 de Enero de 2009, 20:14:24 »
vale usar el " #use i2c " una vez dentro del main?  :?
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Comunicación i2c entre pics (PIC18F y PIC16F)
« Respuesta #2 en: 12 de Enero de 2009, 21:06:17 »
Siempre y cuando lo pongas antes de usar cualquier funcion de i2c. Pero como toda directiva de compilador, conviene ponerla al inicio.
saludos!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado Slade

  • PIC10
  • *
  • Mensajes: 9
X FIN!!!!
« Respuesta #3 en: 16 de Enero de 2009, 22:50:04 »
Saludos foreros

     Weno despues de tanto probar, replantear, programar y ajustar, X FIN FUNCIONA!!!! ESTA VIVO!!!!!!!   :-/     :-/

     Tengo q agradecerte gera, ya que uno de los multiples errores que cometi fue el de "experimentar" con las directivas dentro del main; ademas resulta que las supuestas resistencias de 4.7k que tenia eran de 47k... un pequeño detalle...  :-) Total al final consegui una EEPROM y pude realizar la comunicacion entre el master (18F) los esclavos 16F y la EEPROM.
     
    Weno aqui les dejo el codigo final... que esto "da al pelo" como decimos aqui en mi pais.


-------------------------------- MAESTRO ----------------------------------
#include <18F4550.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES XT                       //Crystal osc <= 4mhz
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT_NOSL            //Brownout enabled during operation, disabled during SLEEP
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES MCLR                     //Master Clear pin enabled
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL1                     //No PLL PreScaler
#FUSES CPUDIV1

#use delay(clock=4000000)
#use i2c(Master,Fast=400000,sda=PIN_B0,scl=PIN_B1,force_hw)
#use fast_io(A)

int i;
int aux[10];
long direccion=0x0000;

void send_i2c(int dato, int dir);
void prueba_usart();
void prueba_i2c();
void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_low_volt_detect(FALSE);

   set_tris_a(0xFE);
   output_a(0);

   delay_ms(1000);

   while(1)
   {
      send_i2c('H',0xB8);

      i2c_start();
      i2c_write(0xA0);
      i2c_write( direccion>>8 );
      i2c_write(direccion);
      i2c_start();
      i2c_write(0xA1);

      for(i=0;i<9;i++)
         aux=i2c_read();

      aux[9]=i2c_read(0);

      i2c_stop();

      for(i=0;i<10;i++)
         send_i2c(aux,0xB8);

      output_high(PIN_A0);
      delay_ms(500);
      output_low(PIN_A0);
      delay_ms(500);

   }
}

void send_i2c(int dato, int dir)
{
   i2c_start();
   i2c_write(dir);
   i2c_write(dato);
   i2c_stop();
   delay_ms(2);
}

---------------------------------------- ESCLAVO 16F LCD -------------------------------
#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                   //High speed Osc (> 4mhz)
#FUSES PUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected


#use delay(clock=12000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Slave,sda=PIN_C4,scl=PIN_C3,address=0xB8,force_hw)

#include ".\include\lcd_J (2dot0).c"
#use fast_io(A)
#use fast_io(E)
#bit SSPOV=0x14.6
#bit BF=0x94.0

void menu()
{
   char ms1[]={"MODO PRUEBA"};
   char ms2[]={"DIP-SW 4  5"};
   char ms3[]={"   I2C 0  1"};
   char ms4[]={" RS232 1  0"};

   send_lcd_ctrl(0x01);delay_ms(10);
   lcd_goto_xy(3,1);lcd_printf(ms1);
   lcd_goto_xy(3,2);lcd_printf(ms2);
   lcd_goto_xy(3,3);lcd_printf(ms3);
   lcd_goto_xy(3,4);lcd_printf(ms4);
}

void mensaje()
{
   enum modo {test,RS232,I2C,test} opc;
   char msi2c[]={"MODO I2C"};
   char msrs232[]={"MODO RS232"};
   char msreset[]={"PRESS  RESET"};

   menu();
   opc=input_a()&0x03;
   do{
      while(opc==(input_a()&0x03)){}
      delay_ms(20);
      opc=input_a()&0x03;
      switch(opc)
      {
         case I2C:
            send_lcd_ctrl(0x01); delay_ms(10);
            lcd_goto_xy(5,2); lcd_printf(msi2c);
            lcd_goto_xy(3,3); lcd_printf(msreset);
            break;

         case RS232:
            send_lcd_ctrl(0x01); delay_ms(10);
            lcd_goto_xy(4,2); lcd_printf(msrs232);
            lcd_goto_xy(3,3); lcd_printf(msreset);
            break;

         default:
            menu();
      }
   }while(1);
}

void main()
{
   int i;
   char mensi2c[]={"I2C INICIADO"};
   char mensrs232[]={"RS232 INICIADO"};
   port_b_pullups(TRUE);
   set_tris_a(0xFF);
   set_tris_e(0xFC);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   output_e(0);
   lcd_port('b');
   init_lcd();

   for(i=0;i<6;i++)
   {
      lcd_goto_xy((3+(i*2)),3); send_lcd('.');
      delay_ms(50);
   }

   switch(input_a()&0x03)
   {
      case 1:
               enable_interrupts(INT_RDA);
               send_lcd_ctrl(0x01); delay_ms(10);
               lcd_goto_xy(3,2); lcd_printf(mensrs232);
               break;
      case 2:
               enable_interrupts(INT_SSP);
               send_lcd_ctrl(0x01); delay_ms(10);
               lcd_goto_xy(3,2); lcd_printf(mensi2c);
               break;
      default: mensaje();
   }

 
   enable_interrupts(GLOBAL);
   while(1)
   {
           BF=0;                        //Bandera de Buffer lleno
           SSPOV=0;                 //Overflow en el buffer
           output_low(PIN_E0);
           output_low(PIN_E1);
    }
}

#int_SSP
void SSP_isr()
{
   int estado,dato;
   estado=i2c_isr_state();
   if((estado>0)&&(estado<0x80))
   {
         dato=i2c_read();
         output_high(PIN_E0);
         send_lcd(dato);
   }
   else output_high(PIN_E1);

}

#int_RDA
void RDA_isr()
{
   char aux;

      aux=getch();
      send_lcd(aux);
}

------------------------------------------------------------------------------------------------------

La EEPROM tiene gravados los numeros en ASCII del 0 al 9 en las primeras 10 posiciones, el maestro lee la memoria y luego la envia al 16F para mostrarlas en la LCD, ademas al inicio de cada trama mando una "H" solo para probar que la comunicacion este bn.

Uno de los problemas que de verdad acabo con mi paciencia, fue luego de añadir la EEPROM al bus i2c fue que el esclavo 16F, porque se quedaba "colgado", estuve investigando y leyendo el manual, y esto tenia que ver con los bits BF (Registro SSPSTAT) y SSPOV (Registro SSPCON) ya que al estar seteadas el esclavo no envia el ACK y se queda "colgado", esto se soluciona seteando estos bits. De todos modos LEAN EL MANUAL!!!!!!!!!!!!!!

Y weno no me queda mas que agradecer a las 2 personas de las 50 y tantas visitas (de las cuales 13 eran mias  :)) por tomarse el tiempo en contestar este post. gracias y hasta pronto

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Comunicación i2c entre pics (PIC18F y PIC16F)
« Respuesta #4 en: 27 de Enero de 2009, 00:23:27 »
De nada, me alegra saber q mi humilde consejo sirvio de algo :)
saludos!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado rodrigo_control2009

  • PIC12
  • **
  • Mensajes: 54
    • Blog  de la  Orden del  temple
Re: X FIN!!!!
« Respuesta #5 en: 19 de Abril de 2009, 16:07:37 »
Perdonden  mi  gran  ignorancia  pero  al  principio  se  declaran  dos  variables  que  no  logro  ver  donde  son  ocupadas 

#bit SSPOV=0x14.6
#bit BF=0x94.0

Gracias 




Saludos foreros

     Weno despues de tanto probar, replantear, programar y ajustar, X FIN FUNCIONA!!!! ESTA VIVO!!!!!!!   :-/     :-/

     Tengo q agradecerte gera, ya que uno de los multiples errores que cometi fue el de "experimentar" con las directivas dentro del main; ademas resulta que las supuestas resistencias de 4.7k que tenia eran de 47k... un pequeño detalle...  :-) Total al final consegui una EEPROM y pude realizar la comunicacion entre el master (18F) los esclavos 16F y la EEPROM.
     
    Weno aqui les dejo el codigo final... que esto "da al pelo" como decimos aqui en mi pais.


-------------------------------- MAESTRO ----------------------------------
#include <18F4550.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES XT                       //Crystal osc <= 4mhz
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT_NOSL            //Brownout enabled during operation, disabled during SLEEP
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES MCLR                     //Master Clear pin enabled
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PLL1                     //No PLL PreScaler
#FUSES CPUDIV1

#use delay(clock=4000000)
#use i2c(Master,Fast=400000,sda=PIN_B0,scl=PIN_B1,force_hw)
#use fast_io(A)

int i;
int aux[10];
long direccion=0x0000;

void send_i2c(int dato, int dir);
void prueba_usart();
void prueba_i2c();
void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_low_volt_detect(FALSE);

   set_tris_a(0xFE);
   output_a(0);

   delay_ms(1000);

   while(1)
   {
      send_i2c('H',0xB8);

      i2c_start();
      i2c_write(0xA0);
      i2c_write( direccion>>8 );
      i2c_write(direccion);
      i2c_start();
      i2c_write(0xA1);

      for(i=0;i<9;i++)
         aux=i2c_read();

      aux[9]=i2c_read(0);

      i2c_stop();

      for(i=0;i<10;i++)
         send_i2c(aux,0xB8);

      output_high(PIN_A0);
      delay_ms(500);
      output_low(PIN_A0);
      delay_ms(500);

   }
}

void send_i2c(int dato, int dir)
{
   i2c_start();
   i2c_write(dir);
   i2c_write(dato);
   i2c_stop();
   delay_ms(2);
}

---------------------------------------- ESCLAVO 16F LCD -------------------------------
#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                   //High speed Osc (> 4mhz)
#FUSES PUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected


#use delay(clock=12000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Slave,sda=PIN_C4,scl=PIN_C3,address=0xB8,force_hw)

#include ".\include\lcd_J (2dot0).c"
#use fast_io(A)
#use fast_io(E)
#bit SSPOV=0x14.6
#bit BF=0x94.0

void menu()
{
   char ms1[]={"MODO PRUEBA"};
   char ms2[]={"DIP-SW 4  5"};
   char ms3[]={"   I2C 0  1"};
   char ms4[]={" RS232 1  0"};

   send_lcd_ctrl(0x01);delay_ms(10);
   lcd_goto_xy(3,1);lcd_printf(ms1);
   lcd_goto_xy(3,2);lcd_printf(ms2);
   lcd_goto_xy(3,3);lcd_printf(ms3);
   lcd_goto_xy(3,4);lcd_printf(ms4);
}

void mensaje()
{
   enum modo {test,RS232,I2C,test} opc;
   char msi2c[]={"MODO I2C"};
   char msrs232[]={"MODO RS232"};
   char msreset[]={"PRESS  RESET"};

   menu();
   opc=input_a()&0x03;
   do{
      while(opc==(input_a()&0x03)){}
      delay_ms(20);
      opc=input_a()&0x03;
      switch(opc)
      {
         case I2C:
            send_lcd_ctrl(0x01); delay_ms(10);
            lcd_goto_xy(5,2); lcd_printf(msi2c);
            lcd_goto_xy(3,3); lcd_printf(msreset);
            break;

         case RS232:
            send_lcd_ctrl(0x01); delay_ms(10);
            lcd_goto_xy(4,2); lcd_printf(msrs232);
            lcd_goto_xy(3,3); lcd_printf(msreset);
            break;

         default:
            menu();
      }
   }while(1);
}

void main()
{
   int i;
   char mensi2c[]={"I2C INICIADO"};
   char mensrs232[]={"RS232 INICIADO"};
   port_b_pullups(TRUE);
   set_tris_a(0xFF);
   set_tris_e(0xFC);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   output_e(0);
   lcd_port('b');
   init_lcd();

   for(i=0;i<6;i++)
   {
      lcd_goto_xy((3+(i*2)),3); send_lcd('.');
      delay_ms(50);
   }

   switch(input_a()&0x03)
   {
      case 1:
               enable_interrupts(INT_RDA);
               send_lcd_ctrl(0x01); delay_ms(10);
               lcd_goto_xy(3,2); lcd_printf(mensrs232);
               break;
      case 2:
               enable_interrupts(INT_SSP);
               send_lcd_ctrl(0x01); delay_ms(10);
               lcd_goto_xy(3,2); lcd_printf(mensi2c);
               break;
      default: mensaje();
   }

 
   enable_interrupts(GLOBAL);
   while(1)
   {
           BF=0;                        //Bandera de Buffer lleno
           SSPOV=0;                 //Overflow en el buffer
           output_low(PIN_E0);
           output_low(PIN_E1);
    }
}

#int_SSP
void SSP_isr()
{
   int estado,dato;
   estado=i2c_isr_state();
   if((estado>0)&&(estado<0x80))
   {
         dato=i2c_read();
         output_high(PIN_E0);
         send_lcd(dato);
   }
   else output_high(PIN_E1);

}

#int_RDA
void RDA_isr()
{
   char aux;

      aux=getch();
      send_lcd(aux);
}

------------------------------------------------------------------------------------------------------

La EEPROM tiene gravados los numeros en ASCII del 0 al 9 en las primeras 10 posiciones, el maestro lee la memoria y luego la envia al 16F para mostrarlas en la LCD, ademas al inicio de cada trama mando una "H" solo para probar que la comunicacion este bn.

Uno de los problemas que de verdad acabo con mi paciencia, fue luego de añadir la EEPROM al bus i2c fue que el esclavo 16F, porque se quedaba "colgado", estuve investigando y leyendo el manual, y esto tenia que ver con los bits BF (Registro SSPSTAT) y SSPOV (Registro SSPCON) ya que al estar seteadas el esclavo no envia el ACK y se queda "colgado", esto se soluciona seteando estos bits. De todos modos LEAN EL MANUAL!!!!!!!!!!!!!!

Y weno no me queda mas que agradecer a las 2 personas de las 50 y tantas visitas (de las cuales 13 eran mias  :)) por tomarse el tiempo en contestar este post. gracias y hasta pronto
[/quote]
“El hombre ideal, sería persa de origen, árabe de religión, iraquí por cultura, hebreo por experiencia, cristiano por conducta, hindú por perspicacia, sufí por su estilo de vida, angélico por su moral y divino por sus ideas y conocimiento, destinado a la eternidad”

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Comunicación i2c entre pics (PIC18F y PIC16F)
« Respuesta #6 en: 21 de Abril de 2009, 13:45:57 »
aqui:

 while(1)
   {
           BF=0;                        //Bandera de Buffer lleno
           SSPOV=0;                 //Overflow en el buffer
           output_low(PIN_E0);
           output_low(PIN_E1);
    }

y no son variables, sino bits.

saludos  :-/
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado rodrigo_control2009

  • PIC12
  • **
  • Mensajes: 54
    • Blog  de la  Orden del  temple
RTOS
« Respuesta #7 en: 22 de Abril de 2009, 22:58:30 »
Gracias   luego de escribir  el  comentario  logre  ver  los  bits   pero  aun sigo  con  problemas  a  la  vista  aca  en este  codigo  se declara  al  principio  #define B0 PIN_B0
y  recorro  el  progrma  y  no  veo  donde  se utiliza
Gracias 

#INCLUDE <18F4550.h>
#device adc=10
#use delay(clock=20000000)
#fuses hs,NOWDT
#include <lcd420x.c>
#use rtos(timer=0,minor_cycle=1ms)
#use standard_io(B)
#use standard_io(c)
#define B0 PIN_B0

int16 valor;   //lectura de temperatura
int16 control; //valor del PWM
float a=0.1243;
float b=0.00006;
float c=62.1514;   //constantes del PID
float temp_limit=500.0;   //temperatura a alcanzar
float rT,eT,pT,qT,yT,uT;
float pT_1=0.0;
float eT_1=0.0; //variables de ecuaciones
float max=1000.0;
float min=0.0;     //límites máximo y mínimo de control.
float tempera;   //Para visualizar la temperatura del horno.
int16  t_l;      //Para visualizar la temperatura límite.
int8 sem;        //Variable de semáforo.


#task(rate=1ms,max=1ms)
void pid ( );

#task(rate=10ms,max=1ms,queue=2)
void display( );

#task(rate=10ms,max=1ms)
void teclado ( );


void main(){

lcd_init();

setup_timer_2(t2_div_by_4,249,1);  //periodo de la señal PWM a 1ms
setup_ccp1(ccp_pwm);               //Módulo CCP a modo PWM

setup_adc_ports(all_analog);      //Puerto A analógico
setup_adc(ADC_CLOCK_INTERNAL);    //reloj convertidor AD interno
set_adc_channel(0);

sem=1;
rtos_run ( );
}

void pid ( )
   {
   rtos_wait(sem);

  valor=read_adc();               //Lectura de la temperatura
  yT=valor*5000.0/1024.0;        //conversión a mV (0.25V a 250mV)
  rT=temp_limit;

  eT=rT-yT;            //Cálculo error
  pT=b*eT+pT_1;        //Cálculo del término integral
  qT=c*(eT-eT_1);      //Cálculo del término derivativo
  uT=pT+a*eT+qT;       //Cálculo de la salida PID

  if (uT>max) {        //Salida PID si es mayor que el MAX
     uT=max;}
  else {
     if (uT<min){      //Salida PID si es menor que el MIN
        uT=min;}
        }
  control=uT;         //Transferencia de salida PID a señal PWM
  set_pwm1_duty(control);

  pT_1=pT;            //Guardar variables
  eT_1=eT;

   rtos_signal(sem);
   rtos_yield();

   }

void display()
{
rtos_wait(sem);

tempera=yT/10;
lcd_gotoxy(1,1);
printf(lcd_putc, "Temp= %F\n", tempera);
t_l=temp_limit/10;
printf(lcd_putc, "Limite= %Lu", t_l);

rtos_signal(sem);
rtos_yield();
}

void teclado()
{
rtos_wait(sem);
if (input(PIN_C4)==0) temp_limit=temp_limit+10.0;
if (temp_limit > 1000.0) temp_limit=500.0;

rtos_signal(sem);
rtos_yield();
}
“El hombre ideal, sería persa de origen, árabe de religión, iraquí por cultura, hebreo por experiencia, cristiano por conducta, hindú por perspicacia, sufí por su estilo de vida, angélico por su moral y divino por sus ideas y conocimiento, destinado a la eternidad”

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Comunicación i2c entre pics (PIC18F y PIC16F)
« Respuesta #8 en: 23 de Abril de 2009, 01:45:34 »
pues parece que simplemente no lo usan  :mrgreen:
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com


 

anything