Autor Tema: 16F876 maestro y esclavo I2C  (Leído 3000 veces)

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

Desconectado patolinec

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 206
16F876 maestro y esclavo I2C
« en: 01 de Marzo de 2006, 13:12:00 »
Hola, he no se si alguien a conectado un micrcontrolador como esclavo de otro utiliazndo el bus i2C, si alguien tiene algun ejemplo que pueda revisar o sabe de alguna direccion de donde poder bajar informacion, utilizo el picBasic Pro para programarlos

Espero sus respuestas
Casi me maté pero ahora estoy de nuevo vivo

Desconectado Artifox

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 455
    • Quadbot
RE: 16F876 maestro y esclavo I2C
« Respuesta #1 en: 02 de Marzo de 2006, 09:43:00 »
Hola, yo he hecho lo que necesitas conectar un pic maestro y varios pic"s esclavos. El codigo lo hice en PBP utlilizando las interrupciones por assembler. Dejame buscarlas y en la noche te las pongo, pues ahorita estoy en el trabajo.

Un abrazo.

Por cierto use un 16F877 y dos 16F876
Video Quadbot
Saludos desde mi querido Perú.
Si realmente queremos que el mundo cambie debemos empezar por nosotros mismos... ;)

Desconectado Artifox

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 455
    • Quadbot
RE: 16F876 maestro y esclavo I2C
« Respuesta #2 en: 02 de Marzo de 2006, 22:27:00 »
Bueno, aca esta lo prometido.... Primero que nada te pongo un resumen del codigo del Master que era un 16F877

define  OSC         4               " Utilizando un Cristal de 4MHz
define  I2C_SLOW    0               " Velocidad de I2C de 400KHz
SDA     VAR     PORTC.4            " Data
SCL     VAR     PORTC.3            " Clock
Angulo  var     byte[12]
Dir_S1  con     $02
Dir_S2  con     $04
..........
.........
TxI2C:
    I2CWrite SDA,SCL,dir_s1,[angulo[0],angulo[1],angulo[2],angulo[3],angulo[4],angulo[5]],error
    pauseus 10                                
    I2CWrite SDA,SCL,dir_s2,[angulo[6],angulo[7],angulo[8],angulo[9],angulo[10],angulo[11]],error
   return


Como veras para el envio estoy usando solo el comando de envio I2CWRITE. A continuacion esta el codigo para el SLAVE que es un 16F876

define OSC 4                       " Utilizando un Cristal de 4MHz
" Variables para la interrupcion
wsave   var     byte $20 system     " Variable que guarda el registro W
ssave   var     byte bank0 system   " Variable que guarda el registro STATUS
psave   var     byte bank0 system   " Variable que guarda el registro PCLATH
"*********** Variables de los valores de entrada****************************
SM01   VAR     BYTE $31 system
SM02   VAR     BYTE $32 system
SM03   VAR     BYTE $33 system
SM04   VAR     BYTE $34 system
SM05   VAR     BYTE $35 system
SM06   VAR     BYTE $36 system
"***************************************************************
SCL     VAR     PORTC.3             " I2C clock input
SDA     VAR     PORTC.4             " I2C data input

Index   var     byte                " Variable para el direccionamiento indirecto
tmp     var     byte            
i       var     byte
I2Caddress CON   $04                 " Direccion del esclavo es 0x04

goto Inicio
"********************* Vector de Interrupcion******************
define INTHAND Int_Vector           " Handler de Interrupcion
asm
Int_Vector
    movwf   wsave                   ; Guardamos el registro W
    movf    STATUS,W
    clrf    STATUS                  ; Guardamos el registro STATUS
    movwf   ssave
    movf    PCLATH,W                ; Guardamos el registro PCLATH
    movwf   psave
    clrf    PCLATH
;*****************Código de interrupción**********************
    banksel PIR1
    btfss   PIR1,SSPIF              ; Pregunta si hay interrupcion de I2C
    goto    End_Int                 ; No, entonces salir de la interrupcion
    bcf     PIR1,SSPIF              ; Borramos el flag de interrupcion
I2C_Int    
    banksel SSPSTAT
    btfsc   SSPSTAT,R_W             ; Preguntamos si es lectura o escritura
    goto    End_Int                 ; Si es Lectura salir de la interrupcion
    btfss   SSPSTAT,BF              ; Revisamos si el Buffer tiene o no tiene dato
    goto    End_Int                 ; Si esta vacio entonces salir
    btfss   SSPSTAT,D_A             ; Preguntamos si el ultimo dato recibido fue un dato
    goto    I2C_Dir                 ; Si es direccion entonces ir a I2CDir
    banksel SSPBUF
    incf    _Index,F
    movlw   0x30    
    addwf   _Index,W
    movwf   FSR
    banksel SSPBUF
    movf    SSPBUF,W                ;<<<<<<<<-------- Cargamos el vamor del Buffer al registro
    movwf   INDF
    goto    End_Int
I2C_Dir
    banksel SSPBUF
    movf    SSPBUF,W
    xorlw   _I2Caddress             ; Comparamos el valor en el buffer con la Direccion del Slave
    btfss   STATUS,Z
    goto    End_Int
    clrf    _Index
End_Int
    clrf    STATUS
    movf    psave,W
    movwf   PCLATH                  ; Restauramos el registro PCLATH
    movf    ssave,W
    movwf   STATUS                  ; Restauramos el registro STATUS
    swapf   wsave,F
    swapf   wsave,W                 ; Restauramos el registro W
    retfie
endasm
"************************Inicio del Programa*************************
Inicio:
    ADCON1=$06  : TRISA=$00
    TRISB=$00
    TRISC=%00011000             " RC.3 y RC.4 config como entradas
"******* Inicializamos el modo I2C slave*****************************
    SSPADD = I2Caddress         " Cargamos la direccion(0x02) del Slave
    SSPCON2 = 0              " Reseteamos el registro de control del I2C
    SSPCON = %00110110          " Configuramos en modo Slave
    PIE1 = %00001000            " Habilitamos la interrupcion por I2C
    PIR1=0                      " Limpiamos los flags de interrupcion
    INTCON = %11000000          " Configuramos las Interrupciones por I2C
Inicio:
......................
goto Inicio
end


La mejor forma de atender la interrupcion es en ASM, como podras ver estoy guardando los 6 valores que llegan por I2C en la interrupcion por ASM.

Para accesar a als variale lo puede hacer directamente en Basic...

Pero que entiendas el codigo... sino cualquier cosa preguntas

Nos vemosRebotadoRebotadoRebotado
Video Quadbot
Saludos desde mi querido Perú.
Si realmente queremos que el mundo cambie debemos empezar por nosotros mismos... ;)

Desconectado Jose_Miramontes

  • PIC10
  • *
  • Mensajes: 10
Re: 16F876 maestro y esclavo I2C
« Respuesta #3 en: 09 de Abril de 2007, 16:18:26 »
alguien podria decirme s puedo acerlo sin utilizar el asm,

Desconectado Jose_Miramontes

  • PIC10
  • *
  • Mensajes: 10
Re: 16F876 maestro y esclavo I2C
« Respuesta #4 en: 12 de Abril de 2007, 14:06:42 »
HOLA, utilic tu codigo en asm, le envio un dato con i2cwrite y si me responde no me    manda a error pero el dato como ke no llega bien siguiente te adjunto el codigo:

define OSC 20 ' Utilizando un Cristal de 4MHz
DEFINE HSER_BAUD 9600  'PARA USAR HSERIN Y HSEROUT
' Variables para la interrupcion
wsave var byte $20 system ' Variable que guarda el registro W
ssave var byte bank0 system ' Variable que guarda el registro STATUS
psave var byte bank0 system ' Variable que guarda el registro PCLATH
'*********** Variables de los valores de entrada****************************
BREAK3 VAR BYTE $31 system
BREAK2 VAR BYTE $32 system
BREAK1 VAR BYTE $33 system
BATERY VAR BYTE $34 system
SM05 VAR BYTE $35 system
SM06 VAR BYTE $36 system

BREAK3=00
BREAK2=00

'***************************************************************
SCL VAR PORTC.3 ' I2C clock input
SDA VAR PORTC.4 ' I2C data input

Index var byte ' Variable para el direccionamiento indirecto
I2Caddress CON $07 ' Direccion del esclavo es 0x04
define INTHAND Int_Vector ' Handler de Interrupcion
goto Inicio
'********************* Vector de Interrupcion******************

asm
Int_Vector
movwf wsave ; Guardamos el registro W
movf STATUS,W
clrf STATUS ; Guardamos el registro STATUS
movwf ssave
movf PCLATH,W ; Guardamos el registro PCLATH
movwf psave
clrf PCLATH
;*****************Código de interrupción**********************
banksel PIR1
btfss PIR1,SSPIF ; Pregunta si hay interrupcion de I2C
goto End_Int ; No, entonces salir de la interrupcion
bcf PIR1,SSPIF ; Borramos el flag de interrupcion
I2C_Int
banksel SSPSTAT
btfsc SSPSTAT,R_W ; Preguntamos si es lectura o escritura
goto End_Int ; Si es Lectura salir de la interrupcion
btfss SSPSTAT,BF ; Revisamos si el Buffer tiene o no tiene dato
goto End_Int ; Si esta vacio entonces salir
btfss SSPSTAT,D_A ; Preguntamos si el ultimo dato recibido fue un dato
goto I2C_Dir ; Si es direccion entonces ir a I2CDir
banksel SSPBUF
incf _Index,F
movlw 0x30
addwf _Index,W
movwf FSR
banksel SSPBUF
movf SSPBUF,W ;<<<<<<<<-------- Cargamos el vamor del Buffer al registro
movwf INDF
goto End_Int
I2C_Dir
banksel SSPBUF
movf SSPBUF,W
xorlw _I2Caddress ; Comparamos el valor en el buffer con la Direccion del Slave
btfss STATUS,Z
goto End_Int
clrf _Index
End_Int
clrf STATUS
movf psave,W
movwf PCLATH ; Restauramos el registro PCLATH
movf ssave,W
movwf STATUS ; Restauramos el registro STATUS
swapf wsave,F
swapf wsave,W ; Restauramos el registro W
retfie
endasm
'************************Inicio del Programa*************************
Inicio:


TRISB=$00
TRISC=%00011000 ' RC.3 y RC.4 config como entradas
'******* Inicializamos el modo I2C slave*****************************
SSPADD = I2Caddress ' Cargamos la direccion(0x02) del Slave
SSPCON2 = 0 ' Reseteamos el registro de control del I2C
SSPCON = %00110110 ' Configuramos en modo Slave
PIE1 = %00001000 ' Habilitamos la interrupcion por I2C
PIR1=0 ' Limpiamos los flags de interrupcion
INTCON = %11000000 ' Configuramos las Interrupciones por I2C


if break2=1 then
high PORTB.0
ENDIF

if break2=0 then
low portb.0
ENDIF

goto Inicio
end

con el master le envio un byte

I2CWRITE DPIN,CPIN,$07,[ABREAK3],ERROR

tiene sus resistencias de pull up en el bus


 

anything