i2c slave using PIC16F88. Need urgent help/opinion.

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Hi all,
  I am using PIC16F88 as an I2C slave. I have attached the code that I
used. From the Microchip MPLAB ICD 2, I find that I am able to detect
the start and stop conditions. But I find that SSPSTAT<BF> is not
getting set. The program is getting stuck in the "gnb" loop. From the
Microchip ICD2, I can see that SSPSTAT<S> and SSPSTAT<P> get set after
the Start and Stop condictions. But not the BF bit. Nothing changes
even if i enable the interrupts. Probably the address was not getting
matched. I am using BL233 to mimic a master. Please let me know what
mistake I am doing.

Thanking you,
Mallik.

    processor    16f88
    include        p16f88.inc
    __CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_ON & _WRT_PROTECT_OFF
& _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_OFF & _WDT_OFF &
_HS_OSC
;
    org    0x00
    nop            ;required for In-Circuit Debugger
;
;    initialize I/O
;
    bsf    STATUS,RP0
    movlw    b'11010010'    ;RB0,RB2,RB3,RB5 are outputs
    movwf    TRISB
    bcf    STATUS,RP0
;
;    Initialize the I2C
;
    clrf    SSPCON
    movlw    0x36        ;SSPEN + CKP + i2c slave mode 7 bit
    movwf    SSPCON

    movlw    0x38        ;slave address for flash loader
    bsf    STATUS,RP0
    movwf    SSPADD

    clrf    SSPSTAT

;    bcf    INTCON,GIE    ;interrupts off (for now)
    bsf    INTCON,GIE    ;interrupts on (for now)
    banksel    PIE1        ; Enable interrupts
    bsf    PIE1,SSPIE
    clrf    STATUS

test:
    call    gnb
    goto    test
;
;    Get Next Byte from I2C
;
;    exit:    C == 1 if Start condition was last received
;        C == 0 if Stop condiction received.
;        Z == 1 if Data was received
;
gnb:    bsf    STATUS,RP0
    btfss    SSPSTAT,BF    ;check buffer full flag
    goto    gnb        ;loop if byte not ready

    btfss    SSPSTAT,5
    bsf    STATUS,Z

    bcf    STATUS,RP0
    bcf    PIR1,SSPIF    ;clear interrupt flag

    movf    SSPBUF,W    ;get byte


    btfsc    SSPSTAT,S    ;check start/repeated start condition
    goto    gnb2        ;jump if start received

    return
;
;    get here if a START was received.
;
gnb2:    
    bsf    STATUS,C
    return

end


Re: i2c slave using PIC16F88. Need urgent help/opinion.

Quoted text here. Click to load it
&
Quoted text here. Click to load it

You should have something like "goto Startup" here to skip over the
interrupt vector at 0x004.  Then put a "Startup" label at the beginning
of your initialize I/O stuff.

Quoted text here. Click to load it

OK so far, but most people recommend using the Banksel macro to select
your active bank.  It's ok here, but later in your code, it's real
confusing as to which bank is currently selected.

Quoted text here. Click to load it

You appear to be in the correct bank at the appropriate times above, but
it was painful for me to figure that out.  I had to use the datasheet
and painstakingly lookup the info.  Please document your bank switching
better, for your own sanity.



Quoted text here. Click to load it

This was a deadly move.  Enabling interrupts with no handler present is
never going to help.  BTW, it's usually better if you enable GIE after
setting up the other xxxxIE flags.  You should also probably clear the
xxxxIF flags before enabling GIE as well.  That way you don't
immediately fly into an interrupt routine because the IF was previously
set.

Quoted text here. Click to load it

Instead of "5", you could use "I2C_DATA" or even "D"

Quoted text here. Click to load it

Instead of "S" you could use "I2C_START"

Quoted text here. Click to load it

I don't see anything obviously wrong with your code, as long as the
device acting as master uses 7 bit addressing and the clock polarity
that you selected.  What are you using for your pull-up resistors?  How
long (physically) is your bus?  I have never used the I2C slave mode of
a PIC, so I can't offer much more help on that.  I would turn of the
interrupts though, that's certainly not going to help without an
appropriate interrupt handler.

I'm guessing that you probably need to be fiddling some bits in SSPSTAT
and SSPCON (like SSPOV for example) after every transmission.  Have you
carefully read the datasheet 10 times yet?  ;-)  You have to read the
entire description of the slave serial port, not just the tidbits about
I2C slave mode.  Your best bet is to find a working example on the net.


Site Timeline