TODOPIC

Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado por: patolinec en 01 de Marzo de 2006, 13:12:00

Título: 16F876 maestro y esclavo I2C
Publicado por: patolinec 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
Título: RE: 16F876 maestro y esclavo I2C
Publicado por: Artifox 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
Título: RE: 16F876 maestro y esclavo I2C
Publicado por: Artifox 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
Título: Re: 16F876 maestro y esclavo I2C
Publicado por: Jose_Miramontes en 09 de Abril de 2007, 16:18:26
alguien podria decirme s puedo acerlo sin utilizar el asm,
Título: Re: 16F876 maestro y esclavo I2C
Publicado por: Jose_Miramontes 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