Autor Tema: COMUNICACION BUS I2C ENTRE MICROS 16F873 (ESCLAVO) Y 16F874 (MASTER) CON CRISTALES DE 4MHZ  (Leído 2765 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Dario-Mza

  • PIC10
  • *
  • Mensajes: 4

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

Desconectado pikman

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 682
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


   
   
saludos
PikMan


 

anything