Searching \ for '[PIC] I2C Routines in a mess !' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/i2cs.htm?key=i2c
Search entire site for: 'I2C Routines in a mess !'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] I2C Routines in a mess !'
2000\06\09@025718 by Andy Stubbins

flavicon
picon face
Hi
Could someone please help me out of a hole I seem to have put myself into? Attached are routines for reading from and writing to a serial EEPROM, and the draw back is that they dont work, and for the life of me I cannot see why. It appears that the read routine works whereas the write does not. I think my problem lies in failing to send the Stop bit, but I am running out of ideas as to what it is that I am doing wrong. If someone has the time to glance over this it would be most appreciated
thanks in advance
Andy



****************
MAIN ROUTINE.
****************
Setup_I2C                                  
       movlw  b'00101000' ;Configure the SSP for master I2C  
movwf  SSPCON          ;Also sets up sda & scl as the source i/o.
       bsf  PORTC,3         ;
       bsf  PORTC,4
       bank1
movlw  b'10000000'
       movwf  SSPSTAT
       movlw  b'01100000'
       movwf  SSPCON2
       movlw  0x18            ;Set for 100khz with a 10Mhz crystal
       movwf  SSPADD  
       bank0
       bcf  PIR1,SSPIF  
return
*************************
READ AND WRITE ROUTINE'S
************************
E_WRITE
           call  Send_StartBit   ; Send the device and slave address+WRITE
           movlw b'10100000'  ;'1010+xxx+x' standard+address+(rd=1/wr=0).    
       call Send_I2_Byte
call Ack_Wait ; Wait for ACK
movfw  Addr_HI_I2C     ; Send the Highbyte of the 16-bit address
call Send_I2_Byte
call Ack_Wait
movfw  Addr_LO_I2C     ; Send the Lowbyte of the 16-bit address
call Send_I2_Byte
call Ack_Wait
movfw INDF  ; Send the value to place in the eeprom
call Send_I2_Byte
call Ack_Wait
call Send_StopBit    ; Send stop
   ;Checks for the rollover from Lo to Hi byte address.
incf Addr_LO_I2C,1 ;Adds one to the LSB register and also
btfsc ZERO  ;tests if reg has rolled over, if so inc MSB.
incf Addr_HI_I2C ;Moves the address location on one place.
incf FSR
decfsz LEN,1  ;LEN= length of bytes to be read from or written to.
goto E_WRITE
return
Ack_Wait
bank1
btfsc SSPSTAT,BF
goto $-1
bank0                   ;bank0 just to be sure
       btfss  PIR1,SSPIF        ;ACK received?
       goto  $-1                
       bcf  PIR1,SSPIF   ;Clear the interrupt flag
return



E_READ  
    call  Send_StartBit ; Send start for a SEQUENTIAL=1/RANDOM=0 read.
       movlw  b'10100000'     ; Send the device and slave address+WRITE
       call Send_I2_Byte
       call Ack_Wait        ; Wait for ACK
       movfw  Ad_Ptr_F2_H     ; Send the Highbyte of the 16-bit address
       call Send_I2_Byte ; Used only in the random read.
       call Ack_Wait        ; Wait for ACK
       movfw Ad_Ptr_F2_L     ; Send the Lowbyte of the 16-bit address
       call Send_I2_Byte
       call Ack_Wait        ; Wait for ACK
call Rpt_Send_I2C ; Send start for a SEQUENTIAL=1/RANDOM=0 read.
       movlw  b'10100001' ;Sets read bit.
call Send_I2_Byte
call Ack_Wait  
E_RD_loop
    call Enable_Rx_I2C   ; set the i2C bus to read
       call Send_I2_Byte    ; Read in the byte from the eeprom
movwf INDF
incf FSR  ;FSR defines registers in RAM to see read data.
decfsz LEN,1
goto E_RD_loop2
call Send_StopBit ; Send stop
return
E_RD_loop2
    call Send_Ack
goto E_RD_loop


Send_I2_Byte   ;Places byte in buffer to be tx'ed
    movwf SSPBUF  ;and traps the write collision error.
    btfss SSPCON,WCOL ;If occurs it wont loop forever.
    return
    bcf SSPCON,WCOL
    goto Send_I2_Byte


Send_StartBit
       bank0             ;bank0 Just to be sure.
       bcf  PIR1,SSPIF          ;Clear the interrupt flag.
bcf  PIR2,BCLIF  ;Clears the bus collision bit.
       bank1                   ;bank1
       bsf  SSPCON2,SEN         ;Send i2c START bit
       bank0                   ;bank0
btfsc PIR2,BCLIF ;Traps the collision bit
goto Send_StartBit
       btfss  PIR1,SSPIF        ;Start bit cycle complete?
       goto  $-1                
bank1
       btfsc SSPCON2,SEN
goto $-1
bank0
return

Send_StopBit
bank0                   ;bank0  just to be sure
       bcf  PIR1,SSPIF          ;Clear the interrupt flag
       bank1                   ;bank0
bsf  SSPCON2,PEN         ;send i2c STOP [P] bit
       bank0                   ;bank0
       btfss  PIR1,SSPIF        ;stop bit cycle completed?
       goto  $-1                
       bcf  PIR1,SSPIF  ;Clear the interrupt flag
return

Rpt_Send_I2C
bank0                   ;bank0  just to be sure
       bcf  PIR1,SSPIF          ;Clear the interrupt flag
       bank1                   ;bank0
       bsf  SSPCON2,RSEN        ;send i2c Repeat send.
       bank0                   ;bank0
       btfss  PIR1,SSPIF        ;stop bit cycle completed?
       goto  $-1                
       return

Enable_Rx_I2C  
       bank1                   ;bank0
       bsf  SSPCON2,RCEN        ;Enable receiving at master 16f877
       bank0                   ;bank0
       bcf  PIR1,SSPIF          ;Clear the interrupt flag
       btfss  PIR1,SSPIF        ;Sspbuf buffer full byte?
       goto  $-1                
return

Send_Ack
bank1
bcf SSPCON2,ACKDT ;i.e.data rx'ed ackn
bsf SSPCON2,ACKEN ;Start the ackn process.
btfsc SSPCON2,ACKEN ;Waits for end of ackn.
goto $-1  
bank0
return

2000\06\10@042711 by Dr. Imre Bartfai

flavicon
face
Hi,

I find at the first look only one point may be bogus: obviously, you
intend to set the TRIS registers in the setup routine; however, you set
bits BEFORE you switch to bank1. Does not make any sense for me...

Regards,
Imre

More... (looser matching)
- Last day of these posts
- In 2000 , 2001 only
- Today
- New search...