CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC16F877 as I2C Slave

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
aressa
Guest







PIC16F877 as I2C Slave
PostPosted: Tue Nov 05, 2002 2:34 pm     Reply with quote

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

View user's profile Send private message Send e-mail

Re: PIC16F877 as I2C Slave
PostPosted: Tue Nov 05, 2002 3:23 pm     Reply with quote

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
PostPosted: Tue Nov 05, 2002 3:27 pm     Reply with quote

<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
PostPosted: Tue Nov 05, 2002 5:36 pm     Reply with quote

:=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

View user's profile Send private message

Re: PIC16F877 as I2C Slave
PostPosted: Tue Nov 05, 2002 7:40 pm     Reply with quote

:=:=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
PostPosted: Wed Nov 06, 2002 1:19 pm     Reply with quote

:=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

View user's profile Send private message

Re: PIC16F877 as I2C Slave
PostPosted: Wed Nov 06, 2002 5:45 pm     Reply with quote

<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
PostPosted: Fri Nov 29, 2002 12:56 am     Reply with quote

:=:=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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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