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
i2c slave using PIC16F88. Need urgent help/opinion.
Started by ●October 13, 2005
Reply by ●October 14, 20052005-10-14
<mallik_kommaraju@yahoo.co.in> wrote in message news:1129231041.728172.160130@g47g2000cwa.googlegroups.com...> 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 DebuggerYou 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.> ; > ; initialize I/O > ; > bsf STATUS,RP0 > movlw b'11010010' ;RB0,RB2,RB3,RB5 are outputs > movwf TRISB > bcf STATUS,RP0OK 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.> ; > ; 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 SSPSTATYou 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.> ; bcf INTCON,GIE ;interrupts off (for now) > bsf INTCON,GIE ;interrupts on (for now) > banksel PIE1 ; Enable interrupts > bsf PIE1,SSPIEThis 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.> 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,5Instead of "5", you could use "I2C_DATA" or even "D"> bsf STATUS,Z > > bcf STATUS,RP0 > bcf PIR1,SSPIF ;clear interrupt flag > > movf SSPBUF,W ;get byte > > > btfsc SSPSTAT,S ;check start/repeated start conditionInstead of "S" you could use "I2C_START"> goto gnb2 ;jump if start received > > return > ; > ; get here if a START was received. > ; > gnb2: > bsf STATUS,C > return > > endI 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.