Autor Tema: Problema en i2c para enviar y recibir datos desde el master (Solucionado)  (Leído 7948 veces)

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

Desconectado freshdesing

  • Colaborador
  • PIC12
  • *****
  • Mensajes: 88
Buenas, en CSS, puedo leer una dirección de memoria en el esclavo desde el master, mediante:

MASTER:
Código: CSS
  1. // Lectura de un dato en la memoria del esclavo
  2.  
  3.          i2c_start ();           //Inicio comunicacion
  4.          i2c_write (0xa0);       //Direccion del esclavo
  5.          i2c_write (0x02);       //Direccion de memoria que queremos leer en
  6.                                  //el esclavo [buffer[0x02] = read_adc()].
  7.          i2c_stop();             //Parada del ciclo de escritura
  8.          i2c_start ();           //Se inicia el ciclo de lectura
  9.          i2c_write (0xa1);       //Añadir 1 a la direccion para pasar al modo
  10.                                  //lectura. A6 A5 A4 A2 A1 A0 R/W  ->
  11.                                  // ->R/W = 0 modo escritura; 1 modo lectura
  12.          result = i2c_read(0);   //Leemos en la direccion apuntada anteriormente
  13.          i2c_stop ();            //Fin de la comunicacion


Y si quiero mandar solo un dato:

Código: CSS
  1. i2c_start();               //Inicio comunicacion
  2.          i2c_write(0xa0);           //Direccion del esclavo
  3.          i2c_write(dato);           //Envia dato
  4.          i2c_stop();                //Fin de la comunicacion
  5.          delay_ms(100);             //
  6.          dato=dato+1;

y en el ESCLAVO:
Código: CSS
  1. #INT_SSP
  2. void ssp_interupt ()
  3. {
  4.    state = i2c_isr_state();
  5.    if(state < 0x80)                 //Master esta enviando datos
  6.    {
  7.       if(state == 0)                   //Se recibe dato
  8.          {
  9.          *****dato = i2c_read();*****
  10.          }
  11.       if(state == 1)                   //El primer byte es la direccion
  12.          {
  13.          address = i2c_read();
  14.          }
  15.       if(state == 2)                   //El segundo byte es el dato
  16.          {
  17.          buffer[address] = i2c_read();
  18.          }
  19.    }
  20.    
  21.    if(state == 0x80)                //master pide un dato
  22.    {
  23.       i2c_write (buffer[address]);  //Mandar el dato en la direccion solicitada
  24.      
  25.    }
  26.    
  27. }


Pues el problema que tengo es el siguiente:
Si en el esclavo en la interrupción de i2c  tengo
Código: CSS
  1. if(state == 0)                   //Se recibe dato
  2.          {
  3.        
  4.          }
y no pongo nada, el MAESTRO puede leer el dato del ESCLAVO. Pero si por ejemplo quisiera enviar un dato del maestro al ESCLAVO cada vez que pulso un botón en el MAESTRO, y el esclavo encender un array de 8 leds en un puerto,
Código: CSS
  1. output_d(dato);
, no hace nada.

En esta parte
Código: CSS
  1. if(state == 0)                   //Se recibe dato
  2.          {
  3.          dato = i2c_read();
  4.          }

añado esto, pero en este caso, el MAESTRO ,que lee el ADC del ESCLAVO, se queda en 5V (0xFF) y al pulsar el boton el ESCALVO no hace nada. Si quito esta línea si funciona. Entiendo que si el ESCLAVO lee state==0, entonces tiene que leer el dato que le manda el MAESTRO. Supongo que el i2c no funciona como pienso. ¿Sabe alguien que estoy haciendo mal?


Agrego todo el código del MAESTRO y ESCLAVO.

Gracias de antemano.

MAESTRO
Código: CSS
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //                     COMUNICACION I2C
  3. //                     Abril 2011
  4. //
  5. //   Programa:   Comunicacion I2C
  6. //   Version:   4
  7. //   ficheros: ***i2c_2011_v4_LCD_master.c***
  8. //             i2c_2011_v4_LCD_slave.c
  9. //             lcd.c
  10. //            
  11. //              
  12. //
  13. //
  14. //   Dispositivo: PIC 16F877A         Compilador:    CCS vs4.049
  15. //
  16. //
  17. //
  18. //
  19. //     Descripción:
  20. //       Comunicacion entre dos pics 16f877A o 18F452, mediante los pines
  21. //       SCL(C3) y SDA(C4). El esclavo lee el valor ADC y lo almacena en
  22. //       buffer[0x02]. El mestro le requiere dicho dato, diciendole la direccion
  23. //       de memoria que quiere leer. Pulsando RB7 en el maestro, este le manda
  24. //       un dato de 8bits al esclavo, que lo representa en 8 leds.
  25. //
  26. //
  27. //
  28. ///////////////////////////////////////////////////////////////////////////////
  29.  
  30.  
  31. #include <16f877A.h>
  32. #fuses HS,NOLVP,NOWDT,NOPROTECT
  33. #use delay(clock=20000000)
  34. #use I2C(FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW)  //using hardware I2C, built
  35. // into the PIC, make sure to include this line in any master I2C program
  36.  
  37.  
  38. #use fast_io(A)
  39. #use fast_io(B)
  40. #use standard_io(C)
  41. #use fast_io(D)
  42. #use fast_io(E)
  43.  
  44. #byte port_a = 0x05
  45. #byte port_b = 0x06
  46. #byte port_c = 0x07
  47. #byte port_d = 0x08
  48. #byte port_e = 0x09
  49.  
  50.  
  51.  
  52. #define use_portd_lcd TRUE         //definir portb lcd
  53. #include <lcd.c>                  //libreria manejo lcd
  54.  
  55.  
  56. int8 result = 0;
  57. float valor=0;
  58. int8 dato=0;
  59.  
  60.  
  61.  
  62. void main(void)
  63. {
  64.    set_tris_b(0xFF);
  65.    port_b_pullups(false);   // Resistencias de polarización del puerto B
  66.    lcd_init();              //inicializa lcd
  67.    disable_interrupts(INT_RB);
  68.    enable_interrupts(GLOBAL);
  69.    
  70.  
  71.    
  72.    while(TRUE)
  73.    {
  74.    
  75.    
  76.    
  77.      
  78. // Lectura de un dato en la memoria del esclavo
  79.  
  80.          i2c_start ();           //Inicio comunicacion
  81.          i2c_write (0xa0);       //Direccion del esclavo
  82.          i2c_write (0x02);       //Direccion de memoria que queremos leer en
  83.                                  //el esclavo [buffer[0x02] = read_adc()].
  84.          i2c_stop();             //Parada del ciclo de escritura
  85.          i2c_start ();           //Se inicia el ciclo de lectura
  86.          i2c_write (0xa1);       //Añadir 1 a la direccion para pasar al modo
  87.                                  //lectura. A6 A5 A4 A2 A1 A0 R/W  ->
  88.                                  // ->R/W = 0 modo escritura; 1 modo lectura
  89.          result = i2c_read(0);   //Leemos en la direccion apuntada anteriormente
  90.          i2c_stop ();            //Fin de la comunicacion
  91.        
  92.      
  93.       valor=(float)result*5/255;  //Rango de 0-5v y 255 valores posibles
  94.       delay_ms(1000);
  95.       printf(lcd_putc,"\fLa medida es \n%4.3f",valor);
  96.      
  97.       if(INPUT(PIN_B7));
  98.          {  
  99.          i2c_start();               //Inicio comunicacion
  100.          i2c_write(0xa0);           //Direccion del esclavo
  101.          i2c_write(dato);           //Envia dato
  102.          i2c_stop();                //Fin de la comunicacion
  103.          delay_ms(100);             //
  104.          dato=dato+1;
  105.          }
  106.  
  107.  
  108.    }  //fin while
  109. }  //fin main


ESCLAVO
Código: CSS
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //                     COMUNICACION I2C
  3. //                     Abril 2011
  4. //
  5. //   Programa:   Comunicacion I2C
  6. //   Version:   4
  7. //   ficheros: i2c_2011_v4_LCD_master.c
  8. //             ***i2c_2011_v4_LCD_slave.c***
  9. //             lcd.c
  10. //            
  11. //              
  12. //
  13. //
  14. //   Dispositivo: PIC 16F877A         Compilador:    CCS vs4.049
  15. //
  16. //
  17. //
  18. //
  19. //     Descripción:
  20. //       Comunicacion entre dos pics 16f877A o 18F452, mediante los pines
  21. //       SCL(C3) y SDA(C4). El esclavo lee el valor ADC y lo almacena en
  22. //       buffer[0x02]. El mestro le requiere dicho dato, diciendole la direccion
  23. //       de memoria que quiere leer.Pulsando RB7 en el maestro, este le manda
  24. //       un dato de 8bits al esclavo, que lo representa en 8 leds.
  25. //
  26. //
  27. //
  28. ///////////////////////////////////////////////////////////////////////////////
  29.  
  30.  
  31. #include <16f877A.h>
  32. #fuses HS,NOLVP,NOWDT,NOPROTECT
  33. #DEVICE ADC=8
  34. #use delay(clock=20000000)
  35.  
  36. #use i2c(SLAVE, FAST, SCL=PIN_C3, SDA=PIN_C4, address=0xA0, FORCE_HW)  
  37. //using hardware I2C, built into the PIC, make sure to include this
  38. // line in any slave I2C program
  39.  
  40. int state;      // I2C var
  41. int8 dato=0;
  42. int8 address, buffer[0x03];   // direccion y array de Bytes
  43.                          
  44.  
  45. #INT_SSP
  46. void ssp_interupt ()
  47. {
  48.    state = i2c_isr_state();
  49.    if(state < 0x80)                 //Master esta enviando datos
  50.    {
  51.       if(state == 0)                   //Se recibe dato
  52.          {
  53.          dato = i2c_read();
  54.          }
  55.       if(state == 1)                   //El primer byte es la direccion
  56.          {
  57.          address = i2c_read();
  58.          }
  59.       if(state == 2)                   //El segundo byte es el dato
  60.          {
  61.          buffer[address] = i2c_read();
  62.          }
  63.    }
  64.    
  65.    if(state == 0x80)                //master pide un dato
  66.    {
  67.       i2c_write (buffer[address]);  //Mandar el dato en la direccion solicitada
  68.      
  69.    }
  70.    
  71. }
  72.  
  73. void main()
  74. {
  75.    set_tris_d(0x00);
  76.    setup_adc_ports(AN0);            //Configuracion AN0 como analogico
  77.    setup_adc(ADC_CLOCK_INTERNAL);
  78.    enable_interrupts(INT_SSP);      //Activamos las interrupciones de I2C
  79.    enable_interrupts(GLOBAL);
  80.  
  81.    while(TRUE)
  82.    {
  83.       set_adc_channel(0);
  84.       delay_us(10);
  85.       buffer[0x02] = read_adc();    //Guardamos la lectura del ADC en el buffer
  86.       delay_ms(100);
  87.       output_d(dato);
  88.    }
  89. }

« Última modificación: 28 de Abril de 2011, 09:17:07 por freshdesing »

Desconectado freshdesing

  • Colaborador
  • PIC12
  • *****
  • Mensajes: 88
Re: Problema en i2c para enviar y recibir datos desde el master
« Respuesta #1 en: 28 de Abril de 2011, 04:46:18 »
...

Desconectado freshdesing

  • Colaborador
  • PIC12
  • *****
  • Mensajes: 88
Problema en i2c para enviar y recibir datos desde el master (Solucionado)
« Respuesta #2 en: 28 de Abril de 2011, 09:19:17 »
Dejo el esquema (pdf y proteus), y los proyectos (uno para maestro  y otro para esclavo), espero que os sirvan.


Un saludo.



Uploaded with ImageShack.us

« Última modificación: 29 de Abril de 2011, 05:33:21 por freshdesing »

Desconectado djrc3000

  • PIC10
  • *
  • Mensajes: 4
Re: Problema en i2c para enviar y recibir datos desde el master (Solucionado)
« Respuesta #3 en: 17 de Noviembre de 2011, 16:16:49 »
Compañero estoy en las mismas... Yo tengo el mismo problema, y no he podido aun con el.
  Sigo Trabajando en ello, apenas pueda darle solucion posteare aqui los detalles de la comunicacion i2c bidireccional, pues ya puedo enviar datos desde el Master al Slave, pero no he podido hacer lo contrario...

Desconectado freshdesing

  • Colaborador
  • PIC12
  • *****
  • Mensajes: 88
Re: Problema en i2c para enviar y recibir datos desde el master (Solucionado)
« Respuesta #4 en: 18 de Noviembre de 2011, 06:47:07 »
¿te srive lo que he dejado? Buscaré a ver si tengo algo más y lo subo. Un saludo