TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: Dario-Mza en 16 de Abril de 2004, 14:47:00
-




COMUNICACION BUS I2C ENTRE MICROS 16F873 (ESCLAVO) Y 16F874 (MASTER) CON CRISTALES DE 4MHZ
HOLA A TODOS, HACE TIEMPO QUE PROGRAMO Y TRABAJO CON MICROCONTROLADORES PIC, PERO ULTIMAMENTE NO HE PODIDO COMUNICARME MEDIANTE EL BUS I2C QUE TIENEN INCORPORADO ESTOS PIC PARA HACERLOS TRABAJAR HABLANDOSE ENTRE ELLOS EN ESTE PROTOCOLO.EL PROBLEMA FUNDAMENTAL EN MIS PROGRAMAS ES QUE NO HE PODIDO DETECTAR UN EVENTO MEDIANTE EL CHEQUEO DEL SSPIF DESPUES DEL BYTE DE DIRECCION QUE LE MANDA EL MASTER AL ESCLAVO, CREO QUE ES PORQUE NO SE PONE EN FUNCIONAMIENTO EL CLOCK POR PARTE DEL MASTER, NO SE EN QUE ME ESTOY OLVIDANDO PERO ME PARECE QUE NO HAY RELOJ.DESDE YA APRECIARIA MUCHISIMO UNA AYUDA Y RECOMPENSARE CON CUALQUIER TIPO DE AYUDA QUE PUEDA DAR EN MICROS PIC, PROGRAMAS ETC....
DESDE YA MUCHAS GRACIAS A TODOS
Mi correo: darioeoliva26@hotmail.com
-
Hola DARIO, NO entiendo bien tu pregunta, pero si puedo recomendarte algo, yo hace tiempo que uso el MSPP de los 16F87x, ultimamente noe s tanto problema porque he abandonado el ASM, he migrado al C, como consejo te digo que deberias ( en el esclavo ) activar la interrupcion que produce el MSPP, y una vez que se produca esta revisar quien la causo, yo al proncipio desarrolle la rutina que te pongo mas abajo sin interrupciones y realmente es complicado, pero funciona, si no usas interrupciones en el esclavo vas a tener que hacer polling sobre el PIR1,SSPIF todo el tiempo, lo que se hace mas complicado que en el master pues si te fijas en la rutina lo hace cada vez que hace algo para esperar por el fin del evento, la rutina que te paso es un master para manejar un DS1307, que es un reloj de tiempo real, es el ejemplo mas claro que tengo, que es lo mismo que el otro pic porque es para esclavos con direccion maxima de 8 bits.
espero que te sirva.
saludos
Pikman
TITLE "MSSP Y DS1307"
LIST P=PIC16F877
INCLUDE "P16F877.INC"
;===========================================
; Manejo de RTC DS1307 con MSSP del PIC16F877
; Fecha de realizacion : 07/04/01
; Fecha Ultima actualizacion : 11/05/01
; Esta rutina puede ser usada con memorias
; 24LCxx o cualquier dispositivo slave I2C
; con direccion de hasta 8 bits
;===========================================
; Definicion de registros de RAM
CBLOCK 0x20
ADDR
TXBUF
CONTA
TEMP3
TEMP4
SLAVE
ENDC
;ESTE ES EL SETEO DEL MODULO
I2C_SETUP
bsf STATUS,RP0 ; Selecciona el Bank 1
movlw 0x09 ; Carga 0x09 para baud rate 100KHZ@4MHZ
movwf SSPADD ; Inicializa velocidad de transferencia
bcf SSPSTAT,6 ; Selecciona niveles para bus I2C
bsf SSPSTAT,7 ; disable slew rate speed mode 100 KHZ
movlw b"00011000" ; Programa las lineas afectadas a I2C
iorwf TRISC,F ; como entradas.
bcf STATUS,RP0 ; Selecciona el BANk 0
movlw b"00101000" ; Programa el modulo SSP
movwf SSPCON ; Master mode, SSP enable I2C
; LECTURA DEL DS1307 Y TE LO PONE EN LA RAM
READ_RTC_I2C ; Lectura del DS1307 y se carga en RAM
movlw 0x0D ; Carga el numero de Bytes a leer
movwf CONTA ;
clrf ADDR ; Primera posision de memoria
movlw B"11010000" ; Direccion de esclavo del DS 1307
movwf SLAVE
call READ_I2C_INI ; Inicializa el modulo I2C para lectura
movlw 0x50 ; Direccion inicial de RAM para transferir
movwf FSR ; a la RAM del micro en modo indirecto
RBYTE_RTC
call READ_I2C_PAGE ; Inicia lectura secuencial del DS1307
movfw SSPBUF ;
movwf INDF ; Y lo transfiere a un registro de la RAM del micro
incf FSR ; Incrementa 1 el puntero de direccion indirecta
decfsz CONTA ; Verifica si lleyo todos los BYTES
goto RBYTE_RTC ; Si no lee otro BYTE
call READ_I2C_PAGE_BSTOP
return
; PONE EN HORA EL DS1307 DESDE UNA TABLA
clrf CONTA
movlw b"11010000"
movwf SLAVE
movlw 0x00
movwf ADDR
call WRITE_I2C_BYTE_INI
LOOP_WRITE
movfw CONTA
call TABLA
movwf TXBUF
call WRITE_I2C_BYTE
call WAIT1
incf CONTA
movfw CONTA
xorlw .8
btfss STATUS,Z
goto LOOP_WRITE
call WRITE_I2C_BSTOP
return
; TABLA DE DATOS PARA PUESTA EN HORA Y FUNCIONAMIENTO DEL DS1307
addwf PCL,F
DT 0x00,0x37,0x22,0x06,0x27,0x04,0x01,0x90
; SEGUNDOS,MINUTOS,HORA,DIA DE LA SEMANA, DIA DEL MES, MES, AÑO, CONFIGURACION
; Retardo de 5 milisegundos para escritura, no es muy critico para el DS1307
; pues es como como RAM, si tener cuidado con las memorias.
WAIT1 movlw .5
WAIT ; Retardo de W milisegundos
movwf TEMP3
TOP2 movlw .110
movwf TEMP4
TOP nop ; sit and wait
nop
nop
nop
nop
nop
decfsz TEMP4,F ; inner loop done?
goto TOP ; no, go again
decfsz TEMP3,F ; outer loop done?
goto TOP2 ; no, go again
return
; RUTINAS USANDO MSSP
; Ejemplo para escrbir paginas direccion 8 bits
WRITE_I2C_BYTE_INI
call I2C_BSTART ; Genera el bit de START
movfw SLAVE ; Direccion del esclavo en modo escritura
movwf SSPBUF ; y al cargarlo en SSPBUF lo transmite
call WAIT_I2C_INT ; Espera por interrupcion del modulo
call I2C_ACK ; Verifica si hubo ACK del esclavo
movfw ADDR ; Direccion de memoria a grabar
movwf SSPBUF ; Al cargar SSPBUF se inicia la transmision
call WAIT_I2C_INT ; Espera por interrupcion del modulo
call I2C_ACK ; Verifica si hubo ACK del esclavo
return ; Y retorna
WRITE_I2C_BYTE
movfw TXBUF ; Carga en W el dato a Grabar
movwf SSPBUF ; y al cargarlo en SSPBUF lo transmite
call WAIT_I2C_INT ; Espera por interrupcion del modulo
call I2C_ACK ; Verifica si hubo ACK del esclavo
return ; Y retorna
WRITE_I2C_BSTOP
call I2C_BSTOP ; Genera el bit de STOP
return ; Y retorna
; Ejemplo de lectura secuencial de paginas direccion 8 bits
READ_I2C_INI
call I2C_BSTART ; Genera el bit de START
movfw SLAVE ; Direccion del esclavo en modo escritura
movwf SSPBUF ; y al cargarlo en SSPBUF lo transmite
call WAIT_I2C_INT ; Espera por interrupcion del modulo
call I2C_ACK ; Verifica si hubo ACK del esclavo
movfw ADDR ; Direccion de memoria a grabar
movwf SSPBUF ; Al cargar SSPBUF se inicia la transmision
call WAIT_I2C_INT ; Espera por interrupcion del modulo
call I2C_ACK ; Verifica si hubo ACK del esclavo
call I2C_RSTART ; Repite la generacion de la condicion de start
bsf SLAVE,0 ; Selecciona el modo lectura del esclavo
movfw SLAVE ; Pasa el valor de SLAVE a W
movwf SSPBUF ; y al cargarlo en SSPBUF lo transmite
call WAIT_I2C_INT ; Espera por interrupcion del modulo
call I2C_ACK ; Verifica si hubo ACK del esclavo
call I2C_RX ; Inicia recepcion I2C
return
READ_I2C_PAGE
bsf STATUS,RP0 ; select SFR bank
bcf SSPCON2,ACKDT ; Setea el estado del bit a enviar (si ack)
bsf SSPCON2,ACKEN ; Incia la secuencia de ACK master a esclavo
btfsc SSPCON2,ACKEN ; ack cycle complete?
goto $-1 ; no, so loop again
bsf SSPCON2,RCEN ; generate receive condition
bcf STATUS,RP0 ; select SFR bank
call WAIT_I2C_INT ; Espera por interrupcion del modulo
return ; Y retorna
READ_I2C_PAGE_BSTOP
bsf STATUS,RP0 ; select SFR bank
bsf SSPCON2,ACKDT ; Setea el estado del bit a enviar (not ack)
bsf SSPCON2,ACKEN ; Incia la secuencia de ACK master a esclavo
bcf STATUS,RP0 ; select SFR bank
call WAIT_I2C_INT ; Espera por interrupcion del modulo
call I2C_BSTOP ; Genera el bit de STOP
return ; Y retorna
;==================RUTINAS AUXILIARES PARA I2C===============================
I2C_BSTART
bsf STATUS,RP0 ; select SFR bank
bsf SSPCON2,SEN ; initiate I2C bus start condition
btfsc SSPCON2,SEN
goto $-1
bcf STATUS,RP0 ; select SFR bank
return
I2C_RSTART
bsf STATUS,RP0 ; select SFR bank
bsf SSPCON2,RSEN ; initiate I2C bus start condition
btfsc SSPCON2,RSEN
goto $-1
bcf STATUS,RP0 ; select SFR bank
return
I2C_BSTOP
bsf STATUS,RP0 ; select SFR bank
bsf SSPCON2,PEN ; initiate I2C bus start condition
btfsc SSPCON2,PEN
goto $-1
bcf STATUS,RP0 ; select SFR bank
return
I2C_RX
bsf STATUS,RP0 ; select SFR bank
bsf SSPCON2,RCEN
bcf STATUS,RP0 ; select SFR bank
return
I2C_ACK
bsf STATUS,RP0 ; select SFR bank
btfsc SSPCON2,ACKSTAT ; test for not acknowledge from slave
goto $-1
bcf STATUS,RP0
return
WAIT_I2C_INT ; Espera por señal de interrupcion del
bcf PIR1,SSPIF ; modulo, recordemos que el modulo genera
btfss PIR1,SSPIF ; por cada operacion una interrupcion, en
goto $-1 ; este caso se revisa la bandera a tal fin
return
;=========================FIN RUTINAS AUXILIARES I2C====================
end