Reply by Anthony Fremont●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
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.
> 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
Instead of "5", you could use "I2C_DATA" or even "D"
> goto gnb2 ;jump if start received
>
> return
> ;
> ; get here if a START was received.
> ;
> gnb2:
> bsf STATUS,C
> return
>
> end
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 by ●October 13, 20052005-10-13
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