TODOPIC
Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado 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
-
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
-
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 vemos

-
alguien podria decirme s puedo acerlo sin utilizar el asm,
-
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