Hola a todos, despues de tanto tiempo sin escribir he vuelto... jeje, espero no daros mucha guerra con mis preguntas...
Bueno al lio... estoy embarcado en un proyecto un poco grandecillo, pretendo domotizar mi casa con los pic, ya tengo todo planeado y mas o menos diseñado pero ya veis me he quedado pillao aqui en el I2C, la cosa es que quiero comunicar dos pic por este metodo pq el usart lo tengo reservado para otra cosa, haber...yo programo en asm, la verdad siempre me ha gustado este método aunque reconozco que al final me tendré que poner a aprender otro pq la comunicacion usb creo que es un poco trabajo de chinos.
Aqui os cuelgo el codigo que he hecho que claro esta no funciona, pero vamos que mi fin es que poniendo dos pulsadores en PORTA0 y PORTA1 en ambos pic al dar al primer o al segundo pulsador de uno mande un codigo al otro y viceversa, el código es que si pulsas el boton1 manda un uno y el otro pic devería represntarlo en el PORTB, supongo que sería el mismo programa para los dos solo que cambiando la supuesta dirección que le pongo a cada uno, creo que esta bastante bien explicado lo que voy haciendo en el código de todas formas si hay alguna duda ya sabeis....
He pensado en ponerlos a los dos como maestro y que funcionen por interrupción, aunque no se muy bien donde poner el código para controlar si hay colisión de datos, en fin vosotros direis...espero no haberos cansado con mi explicación y gracias de antemano!! jeje
List p=16F876A
#include "p16F876A.inc"
__CONFIG _XT_OSC & _WDT_OFF & _PWRTE_OFF & _BODEN_ON & _CP_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF
direc_escl equ 0x30
dato1 equ 0x31
org 0x00
goto Inicio
org 0x04
Inicio
clrf PORTB
clrf PORTC
bsf STATUS,RP0 ;Selecciona banco 1
bcf STATUS,RP1
clrf TRISB
movlw b'00000110'
movwf ADCON1 ;puerto A digital
movlw b'11111111'
movwf TRISA ;puerto A como entrada
movlw b'00011000'
movwf TRISC ;SDA y SCL como entradas
movlw b'10000000' ;velocidad estardar con
movwf SSPSTAT ;niveles I2C
movlw 0x09 ;velocidad del bus I2C
movwf SSPADD ;100KHz
bcf STATUS,RP0 ;Selecciona banco 0
;configuracion del modo MSSP en modo Master I2C
movlw b'00101000' ;modulo MSSP en on
movwf SSPCON
esperando
bsf STATUS,RP0
btfsc SSPSTAT,S ;detecta si esta el bit de inicio activado
goto llamada
bcf STATUS,RP0
btfsc PORTA,0 ;miro tecla1
goto orden1
btfsc PORTA,1 ;miro tecla2
goto orden2
goto esperando
llamada
bcf STATUS,RP0
call read_b ;lee dato que venga por I2C
movwf direc_escl
movlw 0x01
subwf direc_escl,0 ;se lo resto a dato
btfss STATUS,2 ;si es 1 es que no me direccionan ami y sigo esperando
goto esperando
leer_dato
call read_b ;si soy yo, leo el siguiente dato
movlw dato1
bsf STATUS,RP0
btfss SSPSTAT,P ;detecta si esta el bit el bit de parada activo
bcf STATUS,RP0
movwf PORTB
goto esperando
orden1
btfsc PORTA,0
goto orden1
call start ;condicion de inicio
movlw 0x02 ;dirección del esclavo
call send_b
movlw 0x01
call send_b
call stop
goto esperando
orden2
btfsc PORTA,1
goto orden2
call start ;condicion de inicio
movlw 0x02 ;dirección del esclavo
call send_b
movlw 0x02
call send_b
call stop
goto esperando
;*************************************************************
;Envio de condicion de inicio
start
bcf PIR1,SSPIF ;restaura el flag de MSSP
bsf STATUS,RP0 ;selecciona banco1
bcf STATUS,RP1
bsf SSPCON2,SEN ;activa secuencia de inicio
bcf STATUS,RP0 ;banco0
start_w
btfss PIR1,SSPIF ;a terminado?
goto start_w ;no, esperar
return
;**************************************************************
;envio de la secuencia de parada
stop
bcf PIR1,SSPIF ;restaura el flag de MSSP
bsf STATUS,RP0 ;selecciona banco1
bcf STATUS,RP1
bsf SSPCON2,PEN ;activa secuencia de inicio
bcf STATUS,RP0 ;banco0
stop_w
btfss PIR1,SSPIF ;a terminado?
goto stop_w ;no, esperar
return
;*************************************************************
;envio del byte que se encuentra en w vía I2C
;la rutina finaliza cuando se recibe un ACK
send_b
bcf PIR1,SSPIF ;restaura flag
movwf SSPBUF ;lleva byte a buffer de salida
send_b_w
btfss PIR1,SSPIF ;recibido ACK?
goto send_b_w ;no, esperar
return
;***************************************************************
;lee un byte procedente del dispositivo I2C y lo pone en W
;a continuación genera y transmite un ACK
read_b
bcf PIR1,SSPIF ;restaura el flag de MSSP
bsf STATUS,RP0 ;selecciona banco1
bcf STATUS,RP1
bsf SSPCON2,RCEN ;activa modo receptor
bcf STATUS,RP0 ;banco0
read_w
btfss PIR1,SSPIF ;a terminado?
goto read_w ;no, esperar
bcf PIR1,SSPIF ;restaura el flag de MSSP
bsf STATUS,RP0 ;selecciona banco1
bcf STATUS,RP1
bcf SSPCON2,ACKDT ;bit ACK a 0
bsf SSPCON2,ACKEN ;activa generacion ACK
bcf STATUS,RP0 ;banco0
ack_w
btfss PIR1,SSPIF ;a terminado?
goto ack_w ;no, esperar
movf SSPBUF,W ;si, lee el byte recibido
return
END