|
|
View previous topic :: View next topic |
Author |
Message |
Arthur Richards Guest
|
I2C between 16F877s |
Posted: Tue Feb 26, 2002 6:30 pm |
|
|
I wonder if anyone can help with this problem. I have two 16F877s, one master, one slave. I'm trying to get the master to read two bytes from the slave, with no success. The code is attached below.
I've scoped the I2C bus: it runs uite happily when the slave is disconnected, and you can se the master sending out the slave read address byte and clocking in the two bytes (which aren't actually there in this case). The master acks each byte.
Then I attach the slave. I can see the address byte, with the read bit set, gets sent by the master and acked by the slave. The first byte gets read and acked by the master. But the clock pulses for the second byte are never seen. Both PICs lock up: the matser is supposed to keep flashing a LED from its main loop, but that stops. If I unplug things one by one, it looks like the bus is held low by the slave (?). If I take the slave reset line low, the master starts running again and getting FF bytes back as you'd expect.
Whats going on? Why do the clock pulses for the second byte never appear?
Hope someone can help. Thanks,
Arthur
Arthur Richards
MIT
************* MASTER CODE *****************
#if defined(__PCM__)
#include <16f877.h>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
#use i2c(MASTER, sda=PIN_C4, scl=PIN_C3, SLOW)
#include<stdlib.h>
// between transmitted bytes
#define I2CTXPAUSE 50
// between transmitted address and byte read
#define I2CTXRXPAUSE 1000
// between byte reads
#define I2CRXPAUSE 50
// light flash
#define FLASHTIME 50
void main ()
{
byte firstByte; // I2C received bytes
byte secondByte;
// say hello to the world
printf("MSR001.C\n\r");
// initialise interrupts
//enable_interrupts(GLOBAL);
//enable_interrupts(INT_SSP);
while (TRUE) {
// read packet size back from slave
i2c_start();
delay_us(I2CTXPAUSE);
i2c_write(0xb1);
delay_us(I2CTXRXPAUSE);
firstByte = i2c_read(1);
delay_us(I2CRXPAUSE);
secondByte = i2c_read(0);
delay_us(I2CRXPAUSE);
i2c_stop();
delay_us(I2CTXPAUSE);
output_high(PIN_B5);
delay_ms(FLASHTIME);
output_low(PIN_B5);
delay_ms(FLASHTIME);
} //while (TRUE)
}
******************** SLAVE CODE ****************************
#if defined(__PCM__)
#include <16f877.h>
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
#use i2c(SLAVE, sda=PIN_C4, scl=PIN_C3, SLOW, address=0xb0)
#include<stdlib.h>
#define I2CTXPAUSE 10
int i2c_state; // 0 = ready, 1 = got address, 2 = got first command
int reply_state; // 0 = send default, 1 = error, 2 = send buffer byte, 3 = send packet size
byte firstByte; // bytes in I2C message
byte secondByte;
#INT_SSP
void ssp_interupt ()
{
byte gotByte;
if(i2c_poll() == TRUE) {
gotByte = i2c_read(1);
output_b(gotByte);
}
else {
i2c_write('o');
delay_us(I2CTXPAUSE);
i2c_write('k');
delay_us(I2CTXPAUSE);
}
}
void main ()
{
// say hello to the world
printf("Waiting for I2C character\n\r");
// initialise interrupts
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
while (TRUE) {
}
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 2833 |
|
|
Kam Yip Guest
|
Re: I2C between 16F877s |
Posted: Mon Mar 04, 2002 7:20 am |
|
|
:=I wonder if anyone can help with this problem. I have two 16F877s, one master, one slave. I'm trying to get the master to read two bytes from the slave, with no success. The code is attached below.
:=
:=I've scoped the I2C bus: it runs uite happily when the slave is disconnected, and you can se the master sending out the slave read address byte and clocking in the two bytes (which aren't actually there in this case). The master acks each byte.
:=
:=Then I attach the slave. I can see the address byte, with the read bit set, gets sent by the master and acked by the slave. The first byte gets read and acked by the master. But the clock pulses for the second byte are never seen. Both PICs lock up: the matser is supposed to keep flashing a LED from its main loop, but that stops. If I unplug things one by one, it looks like the bus is held low by the slave (?). If I take the slave reset line low, the master starts running again and getting FF bytes back as you'd expect.
:=
:=Whats going on? Why do the clock pulses for the second byte never appear?
:=
:=Hope someone can help. Thanks,
:=
:= Arthur
:=
:=Arthur Richards
:=MIT
:=
:=************* MASTER CODE *****************
:=
:=
:=#if defined(__PCM__)
:=#include <16f877.h>
:=#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
:=#use delay(clock=20000000)
:=#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
:=#use i2c(MASTER, sda=PIN_C4, scl=PIN_C3, SLOW)
:=
:=#include<stdlib.h>
:=
:=// between transmitted bytes
:=#define I2CTXPAUSE 50
:=
:=// between transmitted address and byte read
:=#define I2CTXRXPAUSE 1000
:=
:=// between byte reads
:=#define I2CRXPAUSE 50
:=
:=// light flash
:=#define FLASHTIME 50
:=
:=void main ()
:={
:=
:= byte firstByte; // I2C received bytes
:= byte secondByte;
:=
:= // say hello to the world
:= printf("MSR001.C\n\r");
:=
:= // initialise interrupts
:= //enable_interrupts(GLOBAL);
:= //enable_interrupts(INT_SSP);
:=
:= while (TRUE) {
:=
:= // read packet size back from slave
:= i2c_start();
:= delay_us(I2CTXPAUSE);
:= i2c_write(0xb1);
:= delay_us(I2CTXRXPAUSE);
:= firstByte = i2c_read(1);
:= delay_us(I2CRXPAUSE);
:= secondByte = i2c_read(0);
:= delay_us(I2CRXPAUSE);
:= i2c_stop();
:= delay_us(I2CTXPAUSE);
:=
:= output_high(PIN_B5);
:= delay_ms(FLASHTIME);
:= output_low(PIN_B5);
:= delay_ms(FLASHTIME);
:=
:= } //while (TRUE)
:=}
:=
:=******************** SLAVE CODE ****************************
:=
:=
:=#if defined(__PCM__)
:=#include <16f877.h>
:=#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
:=#use delay(clock=20000000)
:=#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
:=#use i2c(SLAVE, sda=PIN_C4, scl=PIN_C3, SLOW, address=0xb0)
:=
:=#include<stdlib.h>
:=
:=#define I2CTXPAUSE 10
:=
:=int i2c_state; // 0 = ready, 1 = got address, 2 = got first command
:=
:=int reply_state; // 0 = send default, 1 = error, 2 = send buffer byte, 3 = send packet size
:=
:=byte firstByte; // bytes in I2C message
:=byte secondByte;
:=
:=#INT_SSP
:=void ssp_interupt ()
:={
:=
:= byte gotByte;
:=
:= if(i2c_poll() == TRUE) {
:= gotByte = i2c_read(1);
:= output_b(gotByte);
:= }
:= else {
:= i2c_write('o');
:= delay_us(I2CTXPAUSE);
:= i2c_write('k');
:= delay_us(I2CTXPAUSE);
:= }
:=}
:=
:=
:=void main ()
:={
:=
:= // say hello to the world
:= printf("Waiting for I2C character\n\r");
:=
:= // initialise interrupts
:= enable_interrupts(GLOBAL);
:= enable_interrupts(INT_SSP);
:=
:= while (TRUE) {
:= }
:=}
Arthur,
try
1) Setting the tris port C to all input
2) Setting the SSPCON with the slave setting u want ie slave 7bit etc etc.
This should get the slave kicking.
However, if u r serious in writing codes for I2C slave, forget about using the CCS I2C software function. U r in beeter control writing up the routine by yuorself. Just refer to the PIC16C7x datasheets on I2c page, figure 11-27 will guide u on how it works.
Good luck
Kam
___________________________
This message was ported from CCS's old forum
Original Post ID: 2950 |
|
|
Pukar Guest
|
Re: I2C between 16F877s |
Posted: Thu Mar 07, 2002 9:43 pm |
|
|
Hi Arthur,
I am very similar problem between PIC16C73 and an I2C device, where PIC is the Slave. PIC hold the Clock low and does not release it. When the I2C device tries to read from the PIC, the PIC is able to get up to the point where it reads the read address and then chokes.
Please let me know if you find any solution. My e-mail is pmalla1@swarthmore.edu
Thanks.
Regards,
Pukar
:=I wonder if anyone can help with this problem. I have two 16F877s, one master, one slave. I'm trying to get the master to read two bytes from the slave, with no success. The code is attached below.
:=
:=I've scoped the I2C bus: it runs uite happily when the slave is disconnected, and you can se the master sending out the slave read address byte and clocking in the two bytes (which aren't actually there in this case). The master acks each byte.
:=
:=Then I attach the slave. I can see the address byte, with the read bit set, gets sent by the master and acked by the slave. The first byte gets read and acked by the master. But the clock pulses for the second byte are never seen. Both PICs lock up: the matser is supposed to keep flashing a LED from its main loop, but that stops. If I unplug things one by one, it looks like the bus is held low by the slave (?). If I take the slave reset line low, the master starts running again and getting FF bytes back as you'd expect.
:=
:=Whats going on? Why do the clock pulses for the second byte never appear?
:=
:=Hope someone can help. Thanks,
:=
:= Arthur
:=
:=Arthur Richards
:=MIT
:=
:=************* MASTER CODE *****************
:=
:=
:=#if defined(__PCM__)
:=#include <16f877.h>
:=#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
:=#use delay(clock=20000000)
:=#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
:=#use i2c(MASTER, sda=PIN_C4, scl=PIN_C3, SLOW)
:=
:=#include<stdlib.h>
:=
:=// between transmitted bytes
:=#define I2CTXPAUSE 50
:=
:=// between transmitted address and byte read
:=#define I2CTXRXPAUSE 1000
:=
:=// between byte reads
:=#define I2CRXPAUSE 50
:=
:=// light flash
:=#define FLASHTIME 50
:=
:=void main ()
:={
:=
:= byte firstByte; // I2C received bytes
:= byte secondByte;
:=
:= // say hello to the world
:= printf("MSR001.C\n\r");
:=
:= // initialise interrupts
:= //enable_interrupts(GLOBAL);
:= //enable_interrupts(INT_SSP);
:=
:= while (TRUE) {
:=
:= // read packet size back from slave
:= i2c_start();
:= delay_us(I2CTXPAUSE);
:= i2c_write(0xb1);
:= delay_us(I2CTXRXPAUSE);
:= firstByte = i2c_read(1);
:= delay_us(I2CRXPAUSE);
:= secondByte = i2c_read(0);
:= delay_us(I2CRXPAUSE);
:= i2c_stop();
:= delay_us(I2CTXPAUSE);
:=
:= output_high(PIN_B5);
:= delay_ms(FLASHTIME);
:= output_low(PIN_B5);
:= delay_ms(FLASHTIME);
:=
:= } //while (TRUE)
:=}
:=
:=******************** SLAVE CODE ****************************
:=
:=
:=#if defined(__PCM__)
:=#include <16f877.h>
:=#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
:=#use delay(clock=20000000)
:=#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
:=#use i2c(SLAVE, sda=PIN_C4, scl=PIN_C3, SLOW, address=0xb0)
:=
:=#include<stdlib.h>
:=
:=#define I2CTXPAUSE 10
:=
:=int i2c_state; // 0 = ready, 1 = got address, 2 = got first command
:=
:=int reply_state; // 0 = send default, 1 = error, 2 = send buffer byte, 3 = send packet size
:=
:=byte firstByte; // bytes in I2C message
:=byte secondByte;
:=
:=#INT_SSP
:=void ssp_interupt ()
:={
:=
:= byte gotByte;
:=
:= if(i2c_poll() == TRUE) {
:= gotByte = i2c_read(1);
:= output_b(gotByte);
:= }
:= else {
:= i2c_write('o');
:= delay_us(I2CTXPAUSE);
:= i2c_write('k');
:= delay_us(I2CTXPAUSE);
:= }
:=}
:=
:=
:=void main ()
:={
:=
:= // say hello to the world
:= printf("Waiting for I2C character\n\r");
:=
:= // initialise interrupts
:= enable_interrupts(GLOBAL);
:= enable_interrupts(INT_SSP);
:=
:= while (TRUE) {
:= }
:=}
___________________________
This message was ported from CCS's old forum
Original Post ID: 3038 |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
Re: I2C between 16F877s |
Posted: Thu Mar 14, 2002 11:59 am |
|
|
:=I wonder if anyone can help with this problem. I have two 16F877s, one master, one slave. I'm trying to get the master to read two bytes from the slave, with no success. The code is attached below.
:=
:=I've scoped the I2C bus: it runs uite happily when the slave is disconnected, and you can se the master sending out the slave read address byte and clocking in the two bytes (which aren't actually there in this case). The master acks each byte.
:=
:=Then I attach the slave. I can see the address byte, with the read bit set, gets sent by the master and acked by the slave. The first byte gets read and acked by the master. But the clock pulses for the second byte are never seen. Both PICs lock up: the matser is supposed to keep flashing a LED from its main loop, but that stops. If I unplug things one by one, it looks like the bus is held low by the slave (?). If I take the slave reset line low, the master starts running again and getting FF bytes back as you'd expect.
:=
:=Whats going on? Why do the clock pulses for the second byte never appear?
:=
:=Hope someone can help. Thanks,
:=
:= Arthur
:=
:=Arthur Richards
:=MIT
:=
:=************* MASTER CODE *****************
:=
:=
:=#if defined(__PCM__)
:=#include <16f877.h>
:=#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
:=#use delay(clock=20000000)
:=#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
:=#use i2c(MASTER, sda=PIN_C4, scl=PIN_C3, SLOW)
:=
:=#include<stdlib.h>
:=
:=// between transmitted bytes
:=#define I2CTXPAUSE 50
:=
:=// between transmitted address and byte read
:=#define I2CTXRXPAUSE 1000
:=
:=// between byte reads
:=#define I2CRXPAUSE 50
:=
:=// light flash
:=#define FLASHTIME 50
:=
:=void main ()
:={
:=
:= byte firstByte; // I2C received bytes
:= byte secondByte;
:=
:= // say hello to the world
:= printf("MSR001.C\n\r");
:=
:= // initialise interrupts
:= //enable_interrupts(GLOBAL);
:= //enable_interrupts(INT_SSP);
:=
:= while (TRUE) {
:=
:= // read packet size back from slave
:= i2c_start();
:= delay_us(I2CTXPAUSE);
:= i2c_write(0xb1);
:= delay_us(I2CTXRXPAUSE);
:= firstByte = i2c_read(1);
:= delay_us(I2CRXPAUSE);
:= secondByte = i2c_read(0);
:= delay_us(I2CRXPAUSE);
:= i2c_stop();
:= delay_us(I2CTXPAUSE);
:=
:= output_high(PIN_B5);
:= delay_ms(FLASHTIME);
:= output_low(PIN_B5);
:= delay_ms(FLASHTIME);
:=
:= } //while (TRUE)
:=}
:=
:=******************** SLAVE CODE ****************************
:=
:=
:=#if defined(__PCM__)
:=#include <16f877.h>
:=#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
:=#use delay(clock=20000000)
:=#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12
:=#use i2c(SLAVE, sda=PIN_C4, scl=PIN_C3, SLOW, address=0xb0)
:=
:=#include<stdlib.h>
:=
:=#define I2CTXPAUSE 10
:=
:=int i2c_state; // 0 = ready, 1 = got address, 2 = got first command
:=
:=int reply_state; // 0 = send default, 1 = error, 2 = send buffer byte, 3 = send packet size
:=
:=byte firstByte; // bytes in I2C message
:=byte secondByte;
:=
:=#INT_SSP
:=void ssp_interupt ()
:={
:=
:= byte gotByte;
:=
:= if(i2c_poll() == TRUE) {
:= gotByte = i2c_read(1);
:= output_b(gotByte);
:= }
:= else {
:= i2c_write('o');
:= delay_us(I2CTXPAUSE);
:= i2c_write('k');
:= delay_us(I2CTXPAUSE);
:= }
:=}
:=
:=
:=void main ()
:={
:=
:= // say hello to the world
:= printf("Waiting for I2C character\n\r");
:=
:= // initialise interrupts
:= enable_interrupts(GLOBAL);
:= enable_interrupts(INT_SSP);
:=
:= while (TRUE) {
:= }
:=}
You must set the CKP bit in the SSPCON reg to release the clock. You might have to separate the two slave writes. I only read one byte from the PIC when in slave mode so I am unsure if you will get another INT after the first byte is clocked out.
i2c_write('o'); //Make sure that the compiled code is setting *SSPBUF = 'o' and not trying to write out the byte in master mode
bit_set(*SSPCON, CKP); //Release the clock
___________________________
This message was ported from CCS's old forum
Original Post ID: 3229 |
|
|
|
|
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
|