  | 
	  | 
		 
	 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		
			aressa Guest
 
 
 
 
  
			
			
			
			
			
			
			
			
			
			
  
		  | 
		
			
				| PIC16F877 as I2C Slave | 
			 
			
				 Posted: Tue Nov 05, 2002 2:34 pm     | 
				     | 
			 
			
				
  | 
			 
			
				I am attempting to set up a PIC16F877 as an I2C Slave device.  The more I read from these boards and linked articles I have a feeling I am fighting a losing battle.  This is pretty much my only option as that is the way my hardware was designed.
 
 
__First the specs__
 
Rabbit 2000 Series Processor as Master
 
PIC16F877 / PLCC44  as Slave
 
PCM 3.094
 
MPLAB 5.62.00 -> ICE2000
 
 
FACTS:
 
The Rabbit2000 communicates flawlessly with two other off-the-shelf slave devices (a RAM and a EEPROM) so I know that it is not the source of any issues.  But when I try to address the PIC I do not get an ACK all the time, in fact I get an ACK only about once every few seconds.  The PIC is set up to do just a simple “flash lights” on interrupt.
 
I have used an o-scope to verify all of the behavior.
 
I am not currently using a watchdog, and when I did test that it made no difference (there is not a lockup condition currently).
 
 
PROBLEM:
 
The PIC flashes lights with each cycle of my "i2c test" routine, but only pulls down ACK about every two seconds.  It has never ACKed the second byte in the case that it ACKed the first.
 
I’d like to set up the PIC as a reliable slave device, but am unsure if that is possible at this point.
 
 
 
Any idea what I am doing wrong or advice on how to proceed? Thanks in advance.
 
 
Andrew
 
 
-------============ TRIMMED CODE =================--------
 
** MASTER (Not a PIC) **
 
int test_i2c()
 
{
 
auto unsigned char cnt;
 
auto short int err;
 
LS_putc('*');
 
if (err=i2c_startw_tx())
 
{
 
i2c_stop_tx();
 
sprintf(msgBuffer, "too long stretching\r\n"); LS_puts(msgBuffer);
 
}
 
else if (err=i2c_write_char(0xE0))
 
{
 
i2c_stop_tx();
 
sprintf(msgBuffer, "no ack on slave\r\n"); LS_puts(msgBuffer);
 
}
 
else if (err=i2c_write_char(0x0A))
 
{
 
i2c_stop_tx();
 
sprintf(msgBuffer, "no ack on command\r\n"); LS_puts(msgBuffer);
 
}
 
i2c_stop_tx();
 
return 0;
 
}
 
 
 
** SLAVE PIC16F877 **
 
#include <16F877.h>
 
#fuses HS,WDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT	
 
#use delay(clock=20000000) 
 
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xE0, FORCE_HW)
 
 
#INT_SSP
 
void ssp_interupt ()
 
{
 
   byte incoming;
 
 
   if (i2c_poll() == FALSE) {
 
	output_D(0xF0);
 
   }
 
   else {
 
	i2c_read(1);
 
	output_D(0x0F);
 
   }
 
   delay_ms(15);
 
   output_d(0x00);
 
}
 
 
 
void main ()
 
{
 
 
   enable_interrupts(GLOBAL);
 
   enable_interrupts(INT_SSP);
 
 
   while (TRUE) {}
 
}
 
___________________________
 
This message was ported from CCS's old forum
 
	Original Post ID: 8575 | 
			 
		  | 
	 
	
		  | 
	 
	
		
			Mark
 
 
  Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA 
			
			 
			 
			 
			
			
			
			
			
			
  
		  | 
		
			
				| Re: PIC16F877 as I2C Slave | 
			 
			
				 Posted: Tue Nov 05, 2002 3:23 pm     | 
				     | 
			 
			
				
  | 
			 
			
				My advice is to throw away CCS's functions.  Read the datasheet on the PIC and do it yourself.  It is not hard and you have the ability to change the software.  I use them in slave mode without any problems.  In fact, in our design, 17 of them can be on the same bus.
 
 
Regards,
 
Mark
 
 
 
:=I am attempting to set up a PIC16F877 as an I2C Slave device.  The more I read from these boards and linked articles I have a feeling I am fighting a losing battle.  This is pretty much my only option as that is the way my hardware was designed.
 
:=
 
:=__First the specs__
 
:=Rabbit 2000 Series Processor as Master
 
:=PIC16F877 / PLCC44  as Slave
 
:=PCM 3.094
 
:=MPLAB 5.62.00 -> ICE2000
 
:=
 
:=FACTS:
 
:=The Rabbit2000 communicates flawlessly with two other off-the-shelf slave devices (a RAM and a EEPROM) so I know that it is not the source of any issues.  But when I try to address the PIC I do not get an ACK all the time, in fact I get an ACK only about once every few seconds.  The PIC is set up to do just a simple “flash lights” on interrupt.
 
:=I have used an o-scope to verify all of the behavior.
 
:=I am not currently using a watchdog, and when I did test that it made no difference (there is not a lockup condition currently).
 
:=
 
:=PROBLEM:
 
:=The PIC flashes lights with each cycle of my "i2c test" routine, but only pulls down ACK about every two seconds.  It has never ACKed the second byte in the case that it ACKed the first.
 
:=I’d like to set up the PIC as a reliable slave device, but am unsure if that is possible at this point.
 
:=
 
:=
 
:=Any idea what I am doing wrong or advice on how to proceed? Thanks in advance.
 
:=
 
:=Andrew
 
:=
 
:=-------============ TRIMMED CODE =================--------
 
:=** MASTER (Not a PIC) **
 
:=int test_i2c()
 
:={
 
:=auto unsigned char cnt;
 
:=auto short int err;
 
:=LS_putc('*');
 
:=if (err=i2c_startw_tx())
 
:={
 
:=i2c_stop_tx();
 
:=sprintf(msgBuffer, "too long stretching\r\n"); LS_puts(msgBuffer);
 
:=}
 
:=else if (err=i2c_write_char(0xE0))
 
:={
 
:=i2c_stop_tx();
 
:=sprintf(msgBuffer, "no ack on slave\r\n"); LS_puts(msgBuffer);
 
:=}
 
:=else if (err=i2c_write_char(0x0A))
 
:={
 
:=i2c_stop_tx();
 
:=sprintf(msgBuffer, "no ack on command\r\n"); LS_puts(msgBuffer);
 
:=}
 
:=i2c_stop_tx();
 
:=return 0;
 
:=}
 
:=
 
:=
 
:=** SLAVE PIC16F877 **
 
:=#include <16F877.h>
 
:=#fuses HS,WDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT	
 
:=#use delay(clock=20000000) 
 
:=#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xE0, FORCE_HW)
 
:=
 
:=#INT_SSP
 
:=void ssp_interupt ()
 
:={
 
:=   byte incoming;
 
:=
 
:=   if (i2c_poll() == FALSE) {
 
:=	output_D(0xF0);
 
:=   }
 
:=   else {
 
:=	i2c_read(1);
 
:=	output_D(0x0F);
 
:=   }
 
:=   delay_ms(15);
 
:=   output_d(0x00);
 
:=}
 
:=
 
:=
 
:=void main ()
 
:={
 
:=
 
:=   enable_interrupts(GLOBAL);
 
:=   enable_interrupts(INT_SSP);
 
:=
 
:=   while (TRUE) {}
 
:=}
 
___________________________
 
This message was ported from CCS's old forum
 
	Original Post ID: 8577 | 
			 
		  | 
	 
	
		  | 
	 
	
		
			Thomas Blake Guest
 
 
 
 
  
			
			
			
			
			
			
			
			
			
			
  
		  | 
		
			
				| Re: PIC16F877 as I2C Slave | 
			 
			
				 Posted: Tue Nov 05, 2002 3:27 pm     | 
				     | 
			 
			
				
  | 
			 
			
				<font face="Courier New" size=-1>I agree that the F87x (I use an F873) as an I2C slave is pretty feeble.  I followed the asm sample in PIC AN734, and (after a few corrections in the example code) it worked but only at a low link rate ... about 40kb/s max.  This was OK for the project.  The problem, of course, is that you have to lower the rate on your Rabbit., as the slave has nothing to do with the link rate.  If you're using CCSC with the F87x as master it's just as well to dash off a few macros to access and mask SSPCON (0x14) and SSPSTAT(0x91).
 
 
PS >> Mark, I only saw you post after mine was up ... throwing away CCSC is basically what I would advocate if it weren't for client requirements.  AN734 is the best guide.</font>
 
___________________________
 
This message was ported from CCS's old forum
 
	Original Post ID: 8579 | 
			 
		  | 
	 
	
		  | 
	 
	
		
			aressa Guest
 
 
 
 
  
			
			
			
			
			
			
			
			
			
			
  
		  | 
		
			
				| Re: PIC16F877 as I2C Slave | 
			 
			
				 Posted: Tue Nov 05, 2002 5:36 pm     | 
				     | 
			 
			
				
  | 
			 
			
				:=My advice is to throw away CCS's functions.  Read the datasheet on the PIC and do it yourself.  It is not hard and you have the ability to change the software.  I use them in slave mode without any problems.  In fact, in our design, 17 of them can be on the same bus.
 
:=Regards,
 
:=Mark
 
 
Hmmm... thanks.  Do you know of any available source code that has already merged the ASM into a "nice" C front-end?  I have very little experience with ASM and all of my (other) code is currently in C.
 
 
I'm also worried about the ACK being generated by the hardware anyway.  I started reading through the TechNote and it specifically said that the hardware generates the ACK on the address read, or am I reading something wrong?  I guess I need to understand the ASM a bit more.
 
 
Just a bit frustrated at this point.
 
 
Thanks.
 
___________________________
 
This message was ported from CCS's old forum
 
	Original Post ID: 8586 | 
			 
		  | 
	 
	
		  | 
	 
	
		
			Kenny
 
 
  Joined: 07 Sep 2003 Posts: 173 Location: Australia 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| Re: PIC16F877 as I2C Slave | 
			 
			
				 Posted: Tue Nov 05, 2002 7:40 pm     | 
				     | 
			 
			
				
  | 
			 
			
				:=:=My advice is to throw away CCS's functions.  Read the datasheet on the PIC and do it yourself.  It is not hard and you have the ability to change the software.  I use them in slave mode without any problems.  In fact, in our design, 17 of them can be on the same bus.
 
:=:=Regards,
 
:=:=Mark
 
:=
 
:=Hmmm... thanks.  Do you know of any available source code that has already merged the ASM into a "nice" C front-end?  I have very little experience with ASM and all of my (other) code is currently in C.
 
 
There's a C version of AN734 at:
 
 <a href="http://www.pic-c.com/forum/general/posts/7662.html" TARGET="_blank">http://www.pic-c.com/forum/general/posts/7662.html</a>
 
 
Regards
 
Kenny
 
 
:=
 
:=I'm also worried about the ACK being generated by the hardware anyway.  I started reading through the TechNote and it specifically said that the hardware generates the ACK on the address read, or am I reading something wrong?  I guess I need to understand the ASM a bit more.
 
:=
 
:=Just a bit frustrated at this point.
 
:=
 
:=Thanks.
 
___________________________
 
This message was ported from CCS's old forum
 
	Original Post ID: 8587 | 
			 
		  | 
	 
	
		  | 
	 
	
		
			Thomas Blake Guest
 
 
 
 
  
			
			
			
			
			
			
			
			
			
			
  
		  | 
		
			
				| Re: PIC16F877 as I2C Slave | 
			 
			
				 Posted: Wed Nov 06, 2002 1:19 pm     | 
				     | 
			 
			
				
  | 
			 
			
				:=There's a C version of AN734
 
 
I did a double-take when I saw that!! It's almost identical to the way I translated it at first.  Thanks for the confidence boost!  Do you actually have this working at the "slow" speed of 100kb/s?  I could only ever get about half that with AN734, although to be fair I am using a slow system clock ... video subcarrier frequency, about 3.58 MHz.
 
___________________________
 
This message was ported from CCS's old forum
 
	Original Post ID: 8619 | 
			 
		  | 
	 
	
		  | 
	 
	
		
			Kenny
 
 
  Joined: 07 Sep 2003 Posts: 173 Location: Australia 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| Re: PIC16F877 as I2C Slave | 
			 
			
				 Posted: Wed Nov 06, 2002 5:45 pm     | 
				     | 
			 
			
				
  | 
			 
			
				<font face="Courier New" size=-1>:=:=There's a C version of AN734
 
:=
 
:=I did a double-take when I saw that!! It's almost identical to the way I translated it at first.  Thanks for the confidence boost!  Do you actually have this working at the "slow" speed of 100kb/s?  I could only ever get about half that with AN734, although to be fair I am using a slow system clock ... video subcarrier frequency, about 3.58 MHz.
 
 
Glad that you too had success with the translation into C.
 
My version is asm-ish but readable and easily modified for a particular application I think.
 
 
Yes, the i2c clock speed is 100kb/s. I don't see any problem with your system clock of 3.58MHz on the master. Since i2c clocking is done by the master, the slave system clock speed is only relevant re overall throughput.
 
On the master, the SSPADD register contains the reload value for the BRG Down Counter (on the slave it contains the device i2c address instead). 
 
 
The clock for the baud rate generator (BRG Down Counter) is Fosc/4. (the minimum reload value would be 1 so 400kHz system clock would be the minimum, of course all other processing would be slowed down too much in this case).
 
 
BTW The 1k pullups shown in the CCS manual are incorrect. PCM Programmer has posted excellent comments and links recently on this forum. 2k2 is within spec. and still gives a strong pullup. 
 
 
Regards
 
Kenny
 
 
 
 
 
</font>
 
___________________________
 
This message was ported from CCS's old forum
 
	Original Post ID: 8637 | 
			 
		  | 
	 
	
		  | 
	 
	
		
			Tommy Guest
 
 
 
 
  
			
			
			
			
			
			
			
			
			
			
  
		  | 
		
			
				| Re: PIC16F877 as I2C Slave--Sample code attached | 
			 
			
				 Posted: Fri Nov 29, 2002 12:56 am     | 
				     | 
			 
			
				
  | 
			 
			
				:=:=My advice is to throw away CCS's functions.  Read the datasheet on the PIC and do it yourself.  It is not hard and you have the ability to change the software.  I use them in slave mode without any problems.  In fact, in our design, 17 of them can be on the same bus.
 
:=:=Regards,
 
:=:=Mark
 
:=
 
:=Hmmm... thanks.  Do you know of any available source code that has already merged the ASM into a "nice" C front-end?  I have very little experience with ASM and all of my (other) code is currently in C.
 
:=
 
:=I'm also worried about the ACK being generated by the hardware anyway.  I started reading through the TechNote and it specifically said that the hardware generates the ACK on the address read, or am I reading something wrong?  I guess I need to understand the ASM a bit more.
 
:=
 
:=Just a bit frustrated at this point.
 
:=
 
:=Thanks.
 
 
Hello, aressa:
 
 
Here's an UNTESTED sample, assy. lang. function that might help you. The program's comments, and the PIC18CXX8 datasheet should help you understand what's happening.
 
 
Caution: This function is based on MicroChip examples and might have bugs. However, I plan to use it in my project.
 
 
Feel free to e-mail me questions if you have any.
 
 
Best regards,
 
Tom
 
 
 
;; File: i2cRead.asm
 
;; Reads one byte from i2c Slave
 
;;
 
;; Rev. History:
 
;;
 
;;
 
;; Assumptions:
 
;; i2cSTART and i2cSlaveATTN (R/_W bit cleared), has successfully executed)
 
;; Targeted slave is now "awake" expecting a read from it
 
;;
 
;; Input:
 
;;
 
;; Output: RDDAT holds rec'd byte from slave
 
;;
 
;; Processor: PIC18C658
 
;;
 
;
 
i2cRead	CODE
 
	movlw	i2cSTATUS	; Flag we're reading
 
	iorlw	i2cRDDAT
 
	movwf	i2cSTATUS
 
;
 
	bcf	PIR1, SSPIF	; Clear intr. flag
 
	bsf	SSPCON2, RCEN	; Enable recv. mode
 
	call	initTMR0	; Reset and start the timer
 
	btfss	PIR1, SSPIF	; Wait 'till MSSP intr. (time-out or done reading)
 
	goto	$-2		;
 
	bcf	T0CON, TMR0ON	; Stop the timer
 
;
 
; ACK Rec’d data:
 
	bsf	SSPCON2, ACKDT
 
	bsf	SSPCON2, ACKEN
 
;
 
	call	initTMR0	; Reset and start the timer
 
	btfsc	SSPCON2, ACKEN	; Has MSSP ACKed yet?
 
	goto	$-2		; No, keep checking
 
	bcf	T0CON, TMR0ON	; Yes, stop the timer
 
;
 
	movff	SSPBUF, i2cDATA	; Save byte we just read
 
;
 
	movlw	i2cSTATUS	; Flag we're done reading
 
	xorlw	i2cRDDAT
 
	movwf	i2cSTATUS
 
	return
 
___________________________
 
This message was ported from CCS's old forum
 
	Original Post ID: 9614 | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
  | 
   
 
  
Powered by phpBB © 2001, 2005 phpBB Group
  
		 |