Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: jca en 15 de Noviembre de 2007, 18:32:06
Título: comunicacion i2c entre dos pic
Publicado por: jca en 15 de Noviembre de 2007, 18:32:06
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 :mrgreen:
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
;************************************************************* ;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
Título: Re: comunicacion i2c entre dos pic
Publicado por: jca en 17 de Noviembre de 2007, 12:35:08
Que raro... nadie sabe nada de esto? nadie me dice nada? :( 1Saludo
Título: Re: comunicacion i2c entre dos pic
Publicado por: maunix en 17 de Noviembre de 2007, 13:33:40
No me he puesto a ver tu código pero si he visto que quieres usar I2C para domotizar tu casa? qué distancia tendrán los dispositivos entre si?
El i2c fue concebido para ser utilizado con integrados en un mismo PCB, la capacidad máxima de la línea no debe superar los 400pF. Si tienes un largo de cable importante, ya te estarás yendo de normal, ni hablar si encima tienes contaminacion por ruido de 50/60 Hz.
Título: Re: comunicacion i2c entre dos pic
Publicado por: jca en 19 de Noviembre de 2007, 15:28:33
Hola maunix gracias por lo menos por decirme algo...., si es un proyecto domótico, pero el i2c lo quiero para comunicar dos pic que estan en una misma placa, y aqui sigo, dandole vueltas y todavía no funciona.....
1Saludo.....
Título: Re: comunicacion i2c entre dos pic
Publicado por: stk500 en 20 de Noviembre de 2007, 05:26:55
Hola maunix gracias por lo menos por decirme algo...., si es un proyecto domótico, pero el i2c lo quiero para comunicar dos pic que estan en una misma placa, y aqui sigo, dandole vueltas y todavía no funciona.....
1Saludo.....
Hola amigo! pero habia que ver como tu ha implementado el Slave! :x
Título: Re: comunicacion i2c entre dos pic
Publicado por: jca en 20 de Noviembre de 2007, 16:15:55
Hola stk el slave? como expliqué ahi arriba pensé en poner los dos como maestros y que funcionasen por interrupción, por lo tanto no hay programa para el esclavo, es el mismo programa para los dos....
1Saludo....
Título: Re: comunicacion i2c entre dos pic
Publicado por: alogic.on en 21 de Noviembre de 2007, 07:42:59
Hola no me hagas mucho caso, te cuento por si te da alguna idea. Si tienes los dos como master, "yo" gestionaria la llegada de datos activando la interrupcion del i2c, cada vez que uno de los pic se hace con el bus como master y envia un byte, cuando ha terminado de recibirlo en SSPBUF el segundo, este salta al vector 04 del programa y atiende al dato recibido por ej mostrandolo en un puerto para hacer pruebas prueba habilitando la interrupcion y poniendo algo parecido a esto o lo que necesites que haga cuando llega un dato
Código: ASM
ORG 0X04;VECTOR DE INTERRUPCION
goto INTERUUPCION
INTERRUPCION
MOVWF W_TEMP
SWAPF STATUS,W
CLRF STATUS
MOVWF STATUS_TEMP
MOVF PCLATH,W
MOVWF PCLATH_TEMP
CLRF PCLATH
BTFSC PIR1,SSPIF
GOTO INT_SSP
GOTO FIN_INT
INT_SSP
BCF STATUS,RP0
MOVF SSPBUF,W
MOVWF PORTD
GOTO FIN_INT
FIN_INT CLRF PIR1
CALL CONFIG_INTERRUPTS ;call que activa el tipo de intrrupciones y limpia los flags
MOVF PCLATH_TEMP,W
MOVWF PCLATH
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
RETFIE
espero te de alguna idea un saludo
Título: Re: comunicacion i2c entre dos pic
Publicado por: Khael en 24 de Noviembre de 2007, 13:42:55
Hola brother ... mira yo soy nuevo en esto de los pics perome toco hacer algo parecido a lo que tu quieres hacer asi que esto es lo que me salio... Son dos programas diferentes , uno para el esclavo y otro para el master ... la idea es que se teclee en un pic una letra , se displaye y luego se envie para que el otro lo reciba... ami manera de ver he tratado de seguir los datos de la hoja de datos , (valga la redundancia) , pero no me resulta al simularlo en proteus... a ver si opinas algo ps...
"Este es el código del master"
list p=16f877A ; list directive to define processor #include <p16f877A.inc> ; processor specific variable definitions include <MacrosJOM.inc>
; '__CONFIG' directive is used to embed configuration data within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word.
;***** VARIABLE DEFINITIONS PORTB EQU 0X06 ; w_temp EQU 0x7D ; variable used for context saving status_temp EQU 0x7E ; variable used for context saving pclath_temp EQU 0x7F ; variable used for context saving indice EQU 0X70 ; Indice de la tabla data1 EQU 0x21 direccion EQU b'00000001'
ADDWF PCL,F RETLW 0xC0 ; 0 en código 7 segmentos RETLW 0xF9 ; 1 en código 7 segmentos RETLW 0xA4 ; 2 en código 7 segmentos RETLW 0xB0 ; 3 en código 7 segmentos RETLW 0x99 ; 4 en código 7 segmentos RETLW 0x92 ; 5 en código 7 segmentos RETLW 0x82 ; 6 en código 7 segmentos RETLW 0xF8 ; 7 en código 7 segmentos RETLW 0x80 ; 8 en código 7 segmentos RETLW 0x90 ; 9 en código 7 segmentos RETLW 0x88 ; 10 en código 7 segmentos RETLW 0x83 ; 11 en código 7 segmentos RETLW 0xC6 ; 12 en código 7 segmentos RETLW 0xA1 ; 13 en código 7 segmentos RETLW 0x86 ; 14 en código 7 segmentos RETLW 0x8E ; 15 en código 7 segmentos
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END ; directive 'end of program'
"Este es el código del slave"
list p=16f877 ; list directive to define processor #include <p16f877.inc> ; processor specific variable definitions include <MacrosJOM.inc> ; macros adicionales
;***** DEFINICIÓN DE VARIABLES w_temp EQU 0x71 ; variable used for context saving status_temp EQU 0x72 ; variable used for context saving pclath_temp EQU 0x73 ; variable used for context saving direccion EQU b'01111111'
; CÁLCULOS TOMADOS EN CUENTA PARA ESTE PROGRAMA: ;********************************************************************** ; Cálculo del TMR0 = 4x(Tosc)x(255-ValorTMR0)xPrescaler ; En nuestro caso = 4x(0.1x10e-6)x(255-158)x256 ~ 10 mseg ;**********************************************************************
ORG 0x000 ; processor reset vector clrf PCLATH ; ensure page bits are cleared nop goto PRINCIPAL ; go to beginning of program
; Vector Interrupción: ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register movf PCLATH,w ; move pclath register into w register movwf pclath_temp ; save off contents of PCLATH register
goto Servicio_Int ; ir a la subrrutina de interrupción
Salir_Interrupcion: movf pclath_temp,w ; retrieve copy of PCLATH register movwf PCLATH ; restore pre-isr PCLATH register contents movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt
Título: Re: comunicacion i2c entre dos pic
Publicado por: jca en 26 de Noviembre de 2007, 09:53:53
Buenas otra vez en principio darte las gracias alogic.con por tu consejo, he programado la interrupción pero nada, esto sigue sin funcionar, lo único que se me ocurre que pueda ser es intentar poner algunos retardos en la comunicación haber si consigo ajustarlos... es que ya no se que hacer..... Y khael no confies mucho en el proteus que hay veces que se hace la picha un lio, yo mis programas los pruebo siempre encima de las placas que es donde realmente van a estar....