1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

i2c slave using PIC16F88. Need urgent help/opinion.

Discussion in 'Embedded' started by mallik_kommaraju, Oct 13, 2005.

  1. 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
     
    mallik_kommaraju, Oct 13, 2005
    #1
    1. Advertisements

  2. 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.
    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.
    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.


    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.
    Instead of "5", you could use "I2C_DATA" or even "D"
    Instead of "S" you could use "I2C_START"
    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.
     
    Anthony Fremont, Oct 14, 2005
    #2
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.