Autor Tema: Problemas con I2C para 1 Maestro con 24 Esclavos (16 PIC y 8 Memorias)  (Leído 9549 veces)

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

Desconectado ales

  • PIC10
  • *
  • Mensajes: 33
Hola a todos y gracias por leer mis dudas

Estoy haciendo el Proyecto Final en Ingeniería Automática en donde por cierto no tuve un plan docente sobre PIC solo sobre 8051 y 8086, solo he programado en PIC de forma autodidacta por los conocimientos que tenía en C y los micros antes mencionados. Estoy programando con el CCS y sería bueno que cualquier respuesta me la hagan llegar a través de este compilador o con una explicación.
Entrando en detalles:
Necesito conectar un PIC 16F877A como Master a 16 PIC 16F877A como esclavos, además conectaré un banco de 8 memorias 24LC512 y todo por el bus I2C.
Tengo varios problemas:
 1 - Ya logro escribir en todas las memorias pero se lee de ellas cualquier dato menos el que escribo, estuve viendo alguna información en el foro sobre conectar resistencias PULL-UP a Vcc por lo que las probaré a ver si funcionan, aunque no vi nada respecto a la conexión de más de una memoria y la librería que me proporciona el CCS está configurada para 1 sola memoria y tuve que reprogramarla. Si han visto algo al respecto y me lo hacen llegar se los agradeceré así puedo comparar mis ideas.
 2 - El otro problema y no menos importante es que logré enviar información a los esclavos, pero No logró enviar información de los esclavos al Master (Me refiero a las PIC esclavas.  Con respecto a esto mis PIC esclavas tendrán el mismo código fuente por lo que su identifiación para el Master será por Hardware, o sea el mismo programa de los esclavos leerá en su inicialización su identificación, creo que es bueno aclarar esto porque he visto que siempre se habla del protocolo de I2C de un bit R/W para leer o escribir en los esclavos y no se como encajarlo con mis esclavos. La idea de mis esclavos es algo así como las patas A2, A1 y A0 de las memorias 24LC512 donde a través de estas se pone la identificación de cada memoria y ellas por supuestos mantienen un mismo programa.
 Resumiendo el punto 2: Necesito establecer comunicación con varios esclavos PIC (16) poniéndoles identificación por Hardware a través del puerto I2C.

Si los agobie un poco con tanta explicación les pido disculpa es que consideraba necesaria toda la información para que les fuera más fácil poder ayudarme.

También me pueden escribir a: ales_rf@yahoo.es

Y les recuerdo que cualquier información que me hagan llegar me será de mucha utilidad.
Gracias nuevamente, se que utilizan su tiempo para hacer del mio más productivo.


Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1297
Re: Problemas con I2C para 1 Maestro con 24 Esclavos (16 PIC y 8 Memorias)
« Respuesta #1 en: 27 de Marzo de 2008, 14:34:01 »
Qeu tal ales,

Bienvenido al foro y solo te recuerdo que te pases a leer las reglas del foro para que en un futuro no te llamen la atencion los amigos moderadores. ESto es claro para mantener el mejor orden en el mismo, se que comprenderas el punto.

Con respecto a tus dudas.

El bus I2C es un bus de open drain por lo que si no pones las resistencias de pull-up el bus no trabajara adecuadamente, necesitas colocarlas y el valor de las mismas es de unos 4.7 Kohm.

Ahora bien el protocolo I2C es protocolo serial sincrono mestro-esclavo. Esto que quiere decir que necesitas una senail de clock para sincronizar los datos, la cual es generada por el modulo mestro. Los esclavos no pueden enviar informacion a menos que el maestro los solicite, ya que el maestro es quien genera la senial de clock. Por lo tanto si quieres enviar informacion de alguno de los esclavos, el maestro comienza la comunicacion y le solicita los datos a los esclavos.

Saludos y espero haberte ayudado a despejar las dudas.

Elreypic.

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Problemas con I2C para 1 Maestro con 24 Esclavos (16 PIC y 8 Memorias)
« Respuesta #2 en: 27 de Marzo de 2008, 20:06:05 »
El CCS trae ejemplos de como implementar un maestro y un esclavo, estúdiatelo por que es muy didáctico y esta perfectamente explicado.

Un saludo
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado manex_1987

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1127
Re: Problemas con I2C para 1 Maestro con 24 Esclavos (16 PIC y 8 Memorias)
« Respuesta #3 en: 28 de Marzo de 2008, 11:08:22 »
Lo de la identificacion por hardware no es mas que una "ayuda" para que el usuario pueda elegir la direccion de la memo, pues sabemos que no podemos elegir "libremente" la direccion de ellas dado que no son micros como para ser reprogramados 100% en su esencia.

Pero en un micro eso cambia. Si tu aplicacion exige que se pueda cambiar la direccion de un micro "on the fly" (osea sin tener que reprogramar el micro), entonces adelante con la identificacion por hardware. De lo contrario, es absurdo, pues desde el mismo programa puedes asignar una direccion a tu micro. No he andado con tu micro (ese modelo exacto) pero todos son parecidos, y supongo que si miras en el datasheet encontraras un registro de 8 bits donde puedes poner la direccion de tu pic como I2C esclavo. Escribe en ese registro antes de cualquier transaccion I2C, y adelante.

La identificacion por hardware va por el mismo hilo: Al principio del programa lees unos determinados pines, y de acuerdo a su estado (1 o 0) cambias los bits de la direccion, la cual luego escribiras, antes de cualquier transaccion I2C, en el registro de direccion I2C esclavo.

Un saludo.

Desconectado ales

  • PIC10
  • *
  • Mensajes: 33
Lograda comunicación I2C con todos los esclavos incluyendo Memorias
« Respuesta #4 en: 31 de Marzo de 2008, 09:34:33 »
Gracias por responderme, pero tuve un fin de semana muy bueno y ya logré la comunicación I2C con las 8 memorias y con los Esclavos que puedo poner hasta 120, aunque solo por ahora hallan 4.
Necesito identificación de dirección por HW ya que mis esclavos tendrán el mismo programa y necesitaba conocer cual era cada cual.
Aqui les adjunto mis software y el hardware del Proteus por si les sirve de algo.

Gracias por todo.

Desconectado oschupocar

  • PIC10
  • *
  • Mensajes: 4
Re: Problemas con I2C para 1 Maestro con 24 Esclavos (16 PIC y 8 Memorias)
« Respuesta #5 en: 22 de Mayo de 2008, 13:05:41 »
Quemas ales
Es para comentarle que estoy intentando hacer la comunicacion I2C entre un maestro y varios esclavos, y mi problema es que solo me acepta la comunicacion con el primer esclavo que me comunico y al querer comunicarme con otro esclavo se pierde el maestro y creo que es la sincronizacion del SCL.

Pero estuve leyendo en este foro y usted logro comunicarse con varios microcontroladores 16F877A, sera posible que me colabore con este problema o que me oriente con esta comunicacion I2C.

Le recuerdo enviandole este mensaje a su correo, de todas maneras dejo mi direccion de correo para podernos comunicar.

oschupocar@yahoo.es

le agradeceria si me colabora, porque es de suma importancia

Desconectado ales

  • PIC10
  • *
  • Mensajes: 33
Re: Problemas con I2C para 1 Maestro con 24 Esclavos (16 PIC y 8 Memorias)
« Respuesta #6 en: 22 de Mayo de 2008, 23:47:17 »
Hola Oschupocar, me gustaría ayudarte pero necesito que seas un poco más específico, o al menos, pon el codigo del programa para darle una hojeada y sacar conclusiones, además en esto de la I2C es importante saber con que programa estás corriendo el HW y con cual el SW, yo por ejemplo trabajo con Proteus 7.2 y CCS, y con el proteus es un dolor de cabeza muchas cosas por eso te digo de saber si es éste o no.

Saludos.

Desconectado oschupocar

  • PIC10
  • *
  • Mensajes: 4
Re: Problemas con I2C para 1 Maestro con 24 Esclavos (16 PIC y 8 Memorias)
« Respuesta #7 en: 27 de Mayo de 2008, 10:52:41 »
Bueno Ales Gracias por la pronta respuesta, Yo estoy trabajando en MPLAB v8 y proteus 7,2. No se si el codigo tenga problema debido a que esta comunicacion funciona bien con el maestro y un solo esclavo, sin importar la direccion del Slave.

 

;Slave
   list       p=16F877A
   include      "P16F877A.INC"

   __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_ON & _CPD_OFF

   errorlevel   1,-301

;Definición de constantes

   #define   DirNodo      b'00001000'   ;Dirección I2C de este esclavo

;Definición de variables

   cblock   0x20   
   MensajeIn                                   ;Contendrá el dato recibido por I2C del master
   MensajeOut                   ;Contendrá el dato a enviar por I2C al master
   BkStatus                                   ;Backup del registro STATUS
   BkW                      ;Backup W
   Temp                      ;Variable Temporal usada para evaluación de eventos I2C
   endc                      ;Fin de definiciones


   org   0x00
   goto   INICIO

   org   0x04      
;-------------------------------------------------------------------------------
Interrupcion                                      ;RUTINA DE INTERRUPCIÓN. Se ocupa de los eventos I2C
;-------------------------------------------------------------------------------
                                                       ;Guardamos copia de algunos registros
   movwf   BkW                   ;Hace copia de W
   movf   STATUS,W                   ;Hace copia de registro de estado
   banksel   PORTA
   movwf   BkStatus
                                                   ;Chequeamos si la interrupción es por evento I2C. En caso positivo llamamos
                                                   ;a la rutina de proceso del evento
   banksel     PIR1
   btfss   PIR1,SSPIF   ;Ha ocurrido un evento SSP? (I2C)
   goto   IntNoSSP                   ;No. entonces será por otra cosa. Saltamos.
   call   SSP_Handler   ;Si. Procesamos el evento. Si se reciben ordenes, quedarán
            ;registradas en "MensajeIn". Se enviarán las ordenes
            ;guardadas en "MensajeOut".
   banksel     PIR1
   bcf   PIR1,SSPIF   ;Limpiamos el flag
   goto   Rest
IntNoSSP                                                   ;Aquí se gestionan interrupciones que no son por SSP
;..........
; En caso de necesitarse, poner aquí la rutina de gestión de interrupciones
; que no sean por bus I2C
;..........

Rest                                                   ;Restauramos las copias de los registros
   movf   BkStatus,W   ;Restaura las copias de registros
   movwf   STATUS      ;registro de estado
   movf   BkW,W      ;registro W
   retfie
;-------------------------------------------------------------------------------
INICIO                                      ;Inicio del cuerpo del programa
   banksel   TRISB      ;Apunta a banco 1
   clrf            TRISB                   ;Salida (Leds)
   banksel   PORTB      ;Apunta a banco 0
   clrf   PORTB      ;Limpia puerto B

   call   init_i2c_Slave   ;Configuración para uso de i2c
   banksel     INTCON
   bsf   INTCON,GIE   ;Activamos las interrupciones

   banksel     MensajeIn
   clrf   MensajeIn
   clrf   MensajeOut
MLoop   
   movlw   0xF0      ;dato cualquiera por I2C que metemos en
   movwf   MensajeOut   ;"MensajeOut" para cuando el Master se lo pida
   movf   MensajeIn,W   ;Muestra por port B (leds)...
   movwf   PORTB      ;...el ultimo valor enviado por el Master
   goto   MLoop
;*********************************************************************************
; SUBRUTINAS
;*********************************************************************************
;-------------------------------------------------------------------------------
init_i2c_Slave                      ;Inicializa valores para uso de I2C en Slave
                         ;Ha de ser llamado tras definir TRISC y un valor para
                         ;ClockValue. Para frecuencia SCL=Fosc/(4x(ClockValue+1))
;-------------------------------------------------------------------------------
                                                   ;Guardamos copia de algunos registros
   movwf   BkW      ;Hace copia de W
   movf   STATUS,W                   ;Hace copia de registro de estado
   banksel   PORTA
   movwf   BkStatus
                                                   ;Configuramos I2C
   banksel     TRISC      ; Pasamos a direccionar Banco 1
   movlw    b'00011000'   ; Establece líneas SDA y SCL como entradas...
   iorwf    TRISC,f      ;..respetando los valores para otras líneas.
   bcf    SSPSTAT,CKE    ; Establece I2C input levels
   bcf    SSPSTAT,SMP    ; Habilita slew rate
   bsf   SSPCON2,GCEN   ; Habilita direccionamiento global
   movlw   DirNodo      ; Dirección esclavo
   movwf   SSPADD      ;
   banksel     SSPCON       ; Pasamos a direccionar Banco 0
   movlw    b'00110110'   ; Slave mode, SSP enable, velocidad segun...
   movwf    SSPCON       ; ... Fosc/(4x(SSPADD+1))
   bcf   PIR1,SSPIF   ; Limpia flag de eventos SSP
   bcf   PIR1,7      ; Limpia bit. Mandatorio por Datasheet
                                                     ;Configuración para interrupciones por evento I2C
   banksel     PIE1
   bsf   PIE1,SSPIE
   bsf   INTCON,PEIE
                                                           ;Restauramos las copias de los registros
   movf   BkStatus,W   ;Restaura las copias de registros
   movwf   STATUS      ;registro de estado
   movf   BkW,W      ;registro W
   return
; --------------------------------------------------------------------------------------
SSP_Handler   ; Este manejador controla cada evento SSP (I2C) acontecido.
      ; El código que se muestra abajo chequea 5 posibles estados.
      ; Cada uno de los 5 estados SSP son identificados haciendo
      ; XOR de los bits del registro SSPSTAT con mascaras de bits
      ; predeterminadas. Una vez que el estado ha sido identificado
      ; se llevan a cabo las acciones pertinentes. Los estados
      ; indefinidos son considerados como estados de error.

      ; State 1: Operación de escritura I2C, ultimo byte era de dirección.
      ; SSPSTAT bits: S = 1, D_A = 0, R_W = 0, BF = 1

      ; State 2: Operación de escritura I2C, ultimo byte era de datos.
      ; SSPSTAT bits: S = 1, D_A = 1, R_W = 0, BF = 1

      ; State 3: Operación de lectura I2C, ultimo byte era de dirección.
      ; SSPSTAT bits: S = 1, D_A = 0, R_W = 1, BF = 0

      ; State 4: Operación de lectura I2C, ultimo byte era de datos.
      ; SSPSTAT bits: S = 1, D_A = 1, R_W = 1, BF = 0

      ; State 5: Reset lógico del Slave I2C por NACK del master.
      ; SSPSTAT bits: S = 1, D_A = 1, R_W = 0, BF = 0
; --------------------------------------------------------------------------------------
   banksel     SSPSTAT
   movf    SSPSTAT,W    ; Obtiene el valor de SSPSTAT
   andlw    b'00101101'    ; elimina los bits no importantes SSPSTAT.
   banksel   Temp
   movwf    Temp       ; para chequeo posterior.
State1:            ; Operación de escritura, ultimo byte ha sido
   movlw    b'00001001'    ; de dirección, el buffer está lleno.
   banksel   Temp
   xorwf    Temp,W       ;
   btfss    STATUS,Z     ; Estamos en el primer estado?
   goto    State2       ; No, checkeamos siguiente estado
   call    ReadI2C       ; SI. Hacemos un read SSPBUF (para vaciar buffer).
            ; El Hardware se ocupa de mandar Ack
   return
State2:                             ; Operación de escritura, ultimo byte ha sido
   movlw    b'00101001'    ; de datos, el buffer está lleno.
   banksel   Temp
   xorwf    Temp,W
   btfss    STATUS,Z     ; Estamos en el segundo estado?
   goto    State3       ; NO, checkeamos siguiente estado
   call    ReadI2C                    ; SI, Tomamos el byte del SSP.
                                                                ;Aquí tenemos en W el valor del dato recibido
   movwf   MensajeIn
   return
State3:                          ; Operación de lectura, ultimo byte ha sido
   movlw    b'00001100'    ; de dirección, el buffer está vacío
   banksel   Temp
   xorwf    Temp,W
   btfss    STATUS,Z     ; Estamos en el tercer estado?
   goto    State4       ; NO, checkeamos siguiente estado
                                                        ;Aquí debemos poner en W el valor del dato a enviar (solicitado por el master)
   movf   MensajeOut,W
   call    WriteI2C               ; SI, escribimos el byte en SSPBUF
   return
State4:                          ; Operación de lectura, ultimo byte ha sido
   movlw    b'00101100'    ; de datos, el buffer está vacío
   banksel   Temp
   xorwf    Temp,W
   btfss    STATUS,Z     ; Estamos en el cuarto estado?
   goto    State5       ; NO, checkeamos siguiente estado
                                                                ;Aquí debemos poner en W el valor del dato a enviar (solicitado por el master)
   movf   MensajeOut,W
   call    WriteI2C        ; SI, escribimos el byte en SSPBUF
   return
State5:
   movlw    b'00101000'    ; Se ha recibido un NACK mientras se transmitían...
   banksel   Temp
   xorwf    Temp,W       ; ..datos al master. Lo lógica del Slave..
   btfss    STATUS,Z     ; ..se resetea en este caso. R_W = 0, D_A = 1
   goto    I2CErr       ; y BF = 0
   return          ; Si no estamos en State5, entonces es
I2CErr            ; que algo fue mal
    nop         ; Algo fue mal
   return
;---------------------------------------------------------------------
WriteI2C                                                   ;Usada por SSP_Handler para escribir datos en bus I2C
;---------------------------------------------------------------------
   banksel     SSPCON       
   movwf    SSPBUF       ; Escribe el dato en W
   bsf    SSPCON,CKP    ; Libera el reloj
   return

;---------------------------------------------------------------------
ReadI2C                                       ;Usada por SSP_Handler para escribir datos en bus I2C
;---------------------------------------------------------------------
   banksel     SSPBUF
   movf    SSPBUF,W    ; Toma el byte y lo guarda en W
   return
;********************************************* FIN *****************************************************
   END

Desconectado oschupocar

  • PIC10
  • *
  • Mensajes: 4
Re: Problemas con I2C para 1 Maestro con 24 Esclavos (16 PIC y 8 Memorias)
« Respuesta #8 en: 27 de Mayo de 2008, 11:11:09 »
;Master
   LIST       p=16F877A
   INCLUDE      "P16F877A.INC"
      errorlevel 1,-301

   __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_ON & _CPD_OFF
;Definición de constantes

   #define   ClockValue d'49' ;(100khz) valor para cálculo de vel. I2C que pasará a SSPADD

;Definición de variables

   cblock   0x20   
   MensajeIn   ;Contendrá el dato recibido por I2C del slave
   MensajeOut   ;Contendrá el dato a enviar por I2C al slave
   DirSlave   ;Dirección del Slave para escritura
   BkStatus   ;Backup del registro STATUS
   BkW         ;Backup W
   BDel0      ;Usada en retardos. Usada por subr "HacerTiempo"      
   BDel1      ;Usada en retardos. Usada por subr "HacerTiempo"      
   BDel2      ;Usada en retardos. Usada por subr "HacerTiempo"      
   Pausa      ;Pausa en centesima de sg. Usada por subr "HacerTiempo"
   endc      ;Fin de definiciones


   org   0x00
   goto   INICIO
   org   0x04      
;-------------------------------------------------------------------------------
INICIO      ;Inicio del cuerpo del programa
   banksel     PORTA
   CLRF   PORTA
   banksel   TRISB      ;Apunta a banco 1
   clrf   TRISE                       ; Prende led para saber si Tx o Rx
   bsf   TRISA,0
   bsf   TRISA,1
   clrf   TRISD
   movlw   0x06      ;Pone el puerto A digital
   movwf   ADCON1      ;
   movlw   b'00000000'   ;Salida (Leds)
   movwf   TRISB      ;
   banksel   PORTB      ;Apunta a banco 0
   clrf   PORTA      ;Limpia puerto A
   clrf   PORTB      ;Limpia puerto B
   clrf   PORTE                       ;Limpia puerto E
   clrf   PORTD

   call   init_i2c_Master   ;Configuración para uso de i2c

   clrf   MensajeIn
   clrf   MensajeOut

   movlw   d'10'      ;Pausa de 10 centésimas de segundo para que en...
   movwf   Pausa      ;...el arranque de tiempo a los slaves a quedar...
   call   HacerTiempo   ;..configurados adecuadamente.

MLoop   
   ;ENVIO DE UN BYTE AL SLAVE
   ;Se ha de guardar el byte que se quiere transmitir en "MensajeOut" y
   ;la dirección del Slave en "DirSlave". Tras esto solo hay que llamar
   ;a la subrutina "Enviar"
;***********************
   btfsc   PORTA,0   ;***
   goto   $-1      ;***
;***********************
   movlw   0x0A      ;dato cualquiera por I2C que metemos en
   movwf   MensajeOut   ;"MensajeOut" para envío por I2C
   movlw   b'00001000'   ;Establece dirección de envío y escritura.
   Movwf   DirSlave   ;..es decir, dirección del slave
   call   Enviar      ;Envía el dato de "MensajeOut" al Slave
;***********************
   btfss   PORTA,0   ;***
   goto   $-1      ;***
;***********************

;PETICION DE UN BYTE DE DATOS AL SLAVE
   ;Se ha de la dirección del Slave en "DirSlave". Tras esto solo hay que llamar
   ;a la subrutina "Recibir" y se obtendrá el dato en "MensajeIn"
;***********************
   btfsc   PORTA,0   ;***
   goto   $-1      ;***
;***********************
   movlw   b'00001000'   ;Establece dirección de solicitud..
   Movwf   DirSlave   ;..es decir, dirección del slave
   call   Recibir      ;Toma dato del Slave... 
   movf   MensajeIn,W   ;... a través de "MensajeIn"...
   movwf   PORTB      ;...y lo muestra por PORTB (Leds)
;***********************
   btfss   PORTA,0   ;***
   goto   $-1      ;***
   bsf      PORTE,0   ;***
;***********************
;***********************
   btfsc   PORTA,1   ;***
   goto   $-1      ;***
;***********************
   movlw   0x0A      ;dato cualquiera por I2C que metemos en
   movwf   MensajeOut   ;"MensajeOut" para envío por I2C
   movlw   b'00011000'   ;Establece dirección de envío y escritura.
   Movwf   DirSlave   ;..es decir, dirección del slave
   call   Enviar      ;Envía el dato de "MensajeOut" al Slave
;***********************
   btfss   PORTA,1   ;***
   goto   $-1      ;***
;***********************

;PETICION DE UN BYTE DE DATOS AL SLAVE
   ;Se ha de la dirección del Slave en "DirSlave". Tras esto solo hay que llamar
   ;a la subrutina "Recibir" y se obtendrá el dato en "MensajeIn"
;***********************
   btfsc   PORTA,1   ;***
   goto   $-1      ;***
;***********************
   movlw   b'00011000'   ;Establece dirección de solicitud..
   Movwf   DirSlave   ;..es decir, dirección del slave
   call   Recibir      ;Toma dato del Slave... 
   movf   MensajeIn,W   ;... a través de "MensajeIn"...
   movwf   PORTB      ;...y lo muestra por PORTB (Leds)
;***********************
   btfss   PORTA,1   ;***
   goto   $-1      ;***
   bsf      PORTE,1   ;***
;***********************

   goto   MLoop
;*********************************************************************************
; SUBRUTINAS
;*********************************************************************************

;-------------------------------------------------------------------------------
init_i2c_Master      ;Inicializa valores para uso de I2C en Master
               ;Ha de ser llamado tras definir TRISC y un valor para
               ;ClockValue. Para frecuencia SCL=Fosc/(4x(ClockValue+1))
;-------------------------------------------------------------------------------

   ;Guardamos copia de algunos registros
   movwf   BkW         ;Hace copia de W
   movf   STATUS,W   ;Hace copia de registro de estado
   banksel   PORTA
   movwf   BkStatus

   ;Configuramos I2C
   banksel TRISC      ; Pasamos a direccionar Banco 1
   movlw    b'00011000'   ; Establece líneas SDA y SCL como entradas...
   iorwf    TRISC,f      ;..respetando los valores para otras líneas.
   movlw    ClockValue    ; Establece velocidad I2C segun...
   movwf    SSPADD       ; ...valor de ClockValue    
   bcf    SSPSTAT,6    ; Establece I2C input levels
   bcf    SSPSTAT,7    ; Habilita slew rate
   banksel SSPCON       ; Pasamos a direccionar Banco 0
   movlw    b'00111000'   ; Master mode, SSP enable, velocidad segun...
   movwf    SSPCON       ; ... Fosc/(4x(SSPADD+1))
   bcf      PIR1,SSPIF   ; Limpia flag de eventos SSP
   bcf      PIR1,7      ; Limpia bit. Mandatorio por Datasheet
   bcf      PORTC,0
   bcf      PORTC,1
   bcf      PORTC,2

   ;Restauramos las copias de los registros
   movf   BkStatus,W   ;Restaura las copias de registros
   movwf   STATUS      ;registro de estado
   movf   BkW,W      ;registro W
   return
; --------------------------------------------------------------------------------------
Enviar   ;Envía un mensaje (comando) almacenado en "MensajeOut" al Slave cuya dirección
   ;se ha de encontrarse en la variable "DirSlave"
;---------------------------------------------------------------------------------------

   ;Guardamos copia de algunos registros
   movwf   BkW         ;Hace copia de W
   movf   STATUS,W   ;Hace copia de registro de estado
   banksel   PORTA
   movwf   BkStatus

StEnv
   call   Send_Start   ;Envía condición de inicio
;***************************************
   btfsc   PORTE,0
   goto   apagar
   goto   prender
apagar
   bcf      PORTE,0
   goto   continuar
prender
   bsf      PORTE,0
continuar
;***************************************
   call   CheckIdle   ;Espera fin evento
   bsf      PORTE,1
   banksel   DirSlave
   movf   DirSlave,W   ;Dirección esclavo
   call   Send_Byte   ;Envía dirección y orden de escritura
   call   CheckIdle   ;Espera fin evento
   call   WrtAckTest   ;Verifica llegada ACK
   banksel SSPCON2    
   bcf      SSPCON2,ACKSTAT   ;limpia flag ACK
   xorlw   .1
   btfsc   STATUS,Z   ;Chequea si llegó ACK
   goto   StEnv      ;No. Reintentamos envío
   banksel MensajeOut   ;Si. Seguimos con envío dato
   movf   MensajeOut,W   ;Lo deja en W para que la subrutina Send_Byte lo envíe

   call   Send_Byte   ;envía por i2c
   call   CheckIdle   ;Espera fin evento
   call   Send_Stop   ;Envia condición de parada
   call   CheckIdle   ;Espera fin evento


   ;Restauramos las copias de los registros
   movf   BkStatus,W   ;Restaura las copias de registros
   movwf   STATUS      ;registro de estado
   movf   BkW,W      ;registro W

   return

; --------------------------------------------------------------------------------------
Recibir   ;Solicita dato al Slave cuya dirección ha de encontrarse en la variable
   ;"DirSlave" y lo mete en "MensajeIn".
;---------------------------------------------------------------------------------------

   ;Guardamos copia de algunos registros
   movwf   BkW      ;Hace copia de W
   movf   STATUS,W   ;Hace copia de registro de estado
   banksel   PORTA
   movwf   BkStatus

StRec   call   Send_Start   ;Envía condición de inicio
   call   CheckIdle   ;Espera fin evento
   banksel   DirSlave
   movf   DirSlave,W   ;Dirección esclavo
   iorlw   b'00000001'   ;con orden de lectura
   call   Send_Byte   ;Envía dirección y orden de lectura
   call   CheckIdle   ;Espera fin evento
   call   WrtAckTest   ;Verifica llegada ACK
   banksel SSPCON2    
   bcf      SSPCON2,ACKSTAT   ;limpia flag ACK
   xorlw   .1
   btfsc   STATUS,Z   ;Chequea si llegó ACK
   goto   StRec      ;No. Reintentamos envío
            ;Si. Leemos dato
   call   Rec_Byte   ;Recibe dato por i2c y lo mete en "MensajeIn"
   call   CheckIdle   ;Espera fin evento
   call   Send_Nack   ;Envía Nack para finalizar recepción
   call   CheckIdle   ;Espera fin evento
   call   Send_Stop   ;Envía condición de stop
   call   CheckIdle   ;Espera fin evento

   ;Restauramos las copias de los registros
   movf   BkStatus,W   ;Restaura las copias de registros
   movwf   STATUS      ;registro de estado
   movf   BkW,W      ;registro W
   return

; --------------------------------------------------------------------------------------
Send_Start   ;Envía condición de start
;---------------------------------------------------------------------------------------

   banksel SSPCON2       
   bsf    SSPCON2,SEN    ; Envía Start
   return

; --------------------------------------------------------------------------------------
Send_Ack   ;Envía Ack
;---------------------------------------------------------------------------------------
   banksel SSPCON2    
   bcf    SSPCON2,ACKDT    ; acknowledge bit state to send (ack)
   bsf    SSPCON2,ACKEN    ; Inicia secuencia de ack
   return

; --------------------------------------------------------------------------------------
Send_Nack   ;Envía Nack para finalizar recepción
;---------------------------------------------------------------------------------------

   banksel SSPCON2    
   bsf    SSPCON2,ACKDT    ; acknowledge bit state to send (not ack)
   bsf    SSPCON2,ACKEN    ; Inicia secuencia de nack
   return

; --------------------------------------------------------------------------------------
Send_Stop   ;Envía condición de stop
;---------------------------------------------------------------------------------------

   banksel SSPCON2   
   bsf   SSPCON2,PEN   ;Activa secuencia de stop
   return            

; --------------------------------------------------------------------------------------
Send_Byte   ;Envía el contenido de W por i2c
;---------------------------------------------------------------------------------------

   banksel SSPBUF       ; Cambia a banco 0
   movwf    SSPBUF       ; inicia condicion de escritura
   return   

; --------------------------------------------------------------------------------------
Rec_Byte   ;Recibe dato por i2c y lo mete en "MensajeIn"
;---------------------------------------------------------------------------------------

   banksel SSPCON2       ; Cambia a banco 1
   bsf    SSPCON2,RCEN    ; genera receive condition
   btfsc    SSPCON2,RCEN   ; espera a que llegue el dato
   goto    $-1
   banksel SSPBUF         ; Cambia a banco 0
   movf    SSPBUF,w       ; Mueve el dato recibido ...
   movwf    MensajeIn       ; ...  a MensajeIn
   return

; --------------------------------------------------------------------------------------
CheckIdle   ;Chequea que la operación anterior termino y se puede proceder con
         ;el siguiente evento SSP
;---------------------------------------------------------------------------------------

   banksel SSPSTAT         ; Cambia a banco 1
   btfsc    SSPSTAT, R_W    ; Transmisión en progreso?
   goto    $-1
   movf    SSPCON2,W       
   andlw    0x1F          ; Chequeamos con mascara para ver si evento en progreso
   btfss    STATUS, Z
   goto    $-3          ; Sigue en progreso o bus ocupado. esperamos
   banksel PIR1         ; Cambia a banco 0
   bcf    PIR1,SSPIF      ; Limpiamos flag
   return

;---------------------------------------------------------------------------------------
WrtAckTest   ;Chequea ack tras envío de dirección o dato
         ;Devuelve en W 0 o 1 dependiendo de si llegó (0) o no (1) ACK
;---------------------------------------------------------------------------------------

   banksel SSPCON2    ; Cambia a banco 1   
   btfss    SSPCON2,ACKSTAT ;Chequea llegada ACK desde slave
   retlw   .0      ;llegó ACK
   retlw   .1      ;no llegó ACK

;---------------------------------------------------------------------------------------
HacerTiempo   ;realiza una pausa del numero de centesimas de segundo especificadas en "Pausa"
;---------------------------------------------------------------------------------------

      movf   Pausa,W      ;Coloca el valor de pausa en BDel2...
      movwf   BDel2      ;...para no alterar su contenido
   
;............................................................
; Generado con PDEL ver SP  r 1.0  el 24/02/03 Hs 18:31:22
; Descripcion: Delay 10000 ciclos (1 centésima de segundo)
;............................................................
BCiclo  movlw     .8        ; 1 set numero de repeticion  (B)
        movwf     BDel0     ; 1 |
BLoop1  movlw     .249      ; 1 set numero de repeticion  (A)
        movwf     BDel1     ; 1 |
BLoop2  nop                 ; 1 nop   
        nop                 ; 1 ciclo delay
        decfsz    BDel1, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      BLoop2    ; 2 no, loop
        decfsz    BDel0,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      BLoop1    ; 2 no, loop
BDelL1  goto BDelL2         ; 2 ciclos delay
BDelL2  nop                 ; 1 ciclo delay
;............................................................
      decfsz   BDel2,F      ;Repite tantas veces el ciclo de una decima de segundo...
      goto   BCiclo      ;..como se lo indique ADel2
        return              ; 2+2 Fin.

;******************************************************************************

   END

Desconectado oschupocar

  • PIC10
  • *
  • Mensajes: 4
Re: Problemas con I2C para 1 Maestro con 24 Esclavos (16 PIC y 8 Memorias)
« Respuesta #9 en: 27 de Mayo de 2008, 11:38:36 »
Bueno Ales le explico con detalles, El maestro tiene dos pulsadores que los pusimos para que realizara las tareas de Tx Y Rx detalladamente para guiarnos y saber y que lo estaba haciendo bien, el RA0 es el pulsador que realiza la comunicacion con el esclavo 1 y la bandera que indica que si lo hizo bien es el LED en RE0, de la misma manera con el esclavo 2 y el pulsador en RA1 y el led en RE1. Los esclavos tienen el mismo codigo lo único que los diferencia es la dirección y el dato que le envian al maestro.Lo que hemos hecho es..... Nos comunicamos con el esclavo 1 enviandole un dato cualquiera que lo visualiza por el puerto B de este mismo y a su vez envia un dato al maestro que lo visualiza tambien en el puerto B del Maestro, lo siguiente es enviar un dato al esclavo 2 para visualizarlo en el puerto B y este tambien debe enviar un dato diferente al maestro para visualizar por el puerto B del maestro. 
La comunicacion con el esclavo 1 funciona muy bien, pero cuando le doy pulso a RA1 para que realice la conumicacion con el esclavo 2 creemos que pierde la sincronización por lo que nos muestra la simulacion en proteus 7.2 y nunca enciende el led (bandera) que nos dice si terminó o no la comunicación.

Le envio a su correo el pantallazo que utilizamos en proteus además del archivo.

Gracias espero su respuesta.

Desconectado ales

  • PIC10
  • *
  • Mensajes: 33
Re: Problemas con I2C para 1 Maestro con 24 Esclavos (16 PIC y 8 Memorias)
« Respuesta #10 en: 02 de Junio de 2008, 11:45:15 »
Hola, bueno le envíe un correo explicándole algunos detalles del I2C, pero de todas formas le comunico por aqui que cada esclavo tiene que tener obligatoriamente una dirección única, y que si los esclavos tienen el mismo programa entonces la identificación (ID) tienes que ponersela por hardware, o sea, para dos esclavos en principio necesitas 1 solo bit porque sería 0 o 1 cada esclavo, pero la comunicación I2C que de hecho es un estándar de Phillips utiliza la dirección 0 para enviar información a todos los esclavos a la vez, por lo que necesitarás 2 pines del micro para la ID de cada esclavo. Pones una sencilla lógica en el mismo puerto de cada esclavos que represente un número y al principio del programa lo lees y entonces ya cada programa tendrá de diferente ese número que le pasas a la I2C como identificación del esclavo.

Saludos. :-)

Desconectado bombero757

  • PIC10
  • *
  • Mensajes: 1
Re: Problemas con I2C para 1 Maestro con 24 Esclavos (16 PIC y 8 Memorias)
« Respuesta #11 en: 18 de Noviembre de 2008, 19:36:07 »
Hola a todos,
 Veo que pudieron conectar varios pic por i2c. Yo tengo el problema de que no puedo hacer funcionar el pic como esclavo, tengo las configuraciones hechas en ccs y simulo en proteus 7.1 (en hardware sucede lo mismo q en proteus), he hecho el seguimiento de las variables y al parecer el problema está en la función i2c_isr_state();, veo el valor que lee esta función con unos led en el puerto b y siempre es cero, por lo que no puedo llamar al pic esclavo con el maestro. Recordemos que cuando el maestro llama al esclavo la función i2c_isr_state(); es 0x80 y aumenta cada vez que se solicita un nuevo dato. En fin, si alguien ha podido solucionar este problema se lo agradeceria.

adjunto los archivos utilizados en ccs, no varian mucho de los ejemplo. He buscado información por varios lugares y no he podido dar solucion a este problema. si se fijan el esclavo es sólo una memoria con valores asignadas por una función y el maestro solo lee al esclavo, no es gran cosa pero me tiene cmplicado.

 Si alguien puede ayudarme gracias!!!

Gracias

Desconectado wellsu

  • PIC10
  • *
  • Mensajes: 5
Re: Problemas con I2C para 1 Maestro con 24 Esclavos (16 PIC y 8 Memorias)
« Respuesta #12 en: 17 de Junio de 2009, 11:44:37 »
Disculpa amigo, anteriormente dices que dejas el software y hardware para proteus pero no veo el adjunto , lo podrias recargar.
Gracias


 

anything