i2c slave using PIC16F88. Need urgent help/opinion.

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 is not getting set. The program is getting stuck in the "gnb" loop. From the Microchip ICD2, I can see that SSPSTAT and SSPSTAT 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

Reply to
mallik_kommaraju
Loading thread data ...

&

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.

Reply to
Anthony Fremont

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.