Pic to Pic I2C
Pic to Pic I2C
I want to connect a PIC16F88 with a PIC18F4550 with I2C connection, but I cannot find any examples using MikroC with PIC to PIC connection, and I have no idea how to even start.
I want the PIC16F88 to be master, and the PIC18F4550 to be slave.
Also, how would be physical connection (what pin to what pin) between them ?
Thanks
I want the PIC16F88 to be master, and the PIC18F4550 to be slave.
Also, how would be physical connection (what pin to what pin) between them ?
Thanks
Re: Pic to Pic I2C
Like other I2C connection, CLK <--> CLK, SCL <--> SCL, and SDA <-->SDA. You should not have a problem with Master because you can use MikroC routines but you have to work on the Slave side.CVMichael wrote: how would be physical connection (what pin to what pin) between them ?
Thanks
Regards
Nick
[url]http://www.pic_examples.byethost3.com/[/url]
[url]http://www.pic_examples.byethost3.com/[/url]
-
- Posts: 37
- Joined: 25 Jan 2007 14:18
- Location: Sweden, Tågarp
Hi,
Someone posted example code long time ago. Here is the link
http://www.mikroe.com/forum/viewtopic.p ... =i2c+slave
Someone posted example code long time ago. Here is the link
http://www.mikroe.com/forum/viewtopic.p ... =i2c+slave
Nick
[url]http://www.pic_examples.byethost3.com/[/url]
[url]http://www.pic_examples.byethost3.com/[/url]
Hi Nick101,
I finally got the time to try the code in the link. I connected the 2 microcontrollers (PIC18F4550 and PIC16F88).
The problem is that it hangs when it's calling the send function.
I connected SCL to SCL and SDA to SDA, what is the CLK pin you were talking about earlier ?
Anyways, from other sources on the net, I found that only SCL and SDA has to be connected, for example:
http://www.botdream.com/blog/2008/02/01 ... ication-2/
Do the 1K resistors have to be there ? you did not say anything about resistors on the SCL / SDA in the previous post.
Here is my code, I am doing a lot of things in the code, it is actually almost 700 lines of code, but I copied and pasted what I think it is more important. (I am also using interrupts)
As you can see with this code:
LED1 = !LED1;
I2C_SendByte(75);
LED1 = !LED1;
The LED is OFF when the program starts, the first line it turns the LED ON, then it's supposed to send the data "75", and turn the LED OFF, therefore showing me how long it takes to send the data.
But the LED never turns OFF, and everything hangs, i.e. even the interrupts stop...
Can you help me please ?
Thank You
I finally got the time to try the code in the link. I connected the 2 microcontrollers (PIC18F4550 and PIC16F88).
The problem is that it hangs when it's calling the send function.
I connected SCL to SCL and SDA to SDA, what is the CLK pin you were talking about earlier ?
Anyways, from other sources on the net, I found that only SCL and SDA has to be connected, for example:
http://www.botdream.com/blog/2008/02/01 ... ication-2/
Do the 1K resistors have to be there ? you did not say anything about resistors on the SCL / SDA in the previous post.
Here is my code, I am doing a lot of things in the code, it is actually almost 700 lines of code, but I copied and pasted what I think it is more important. (I am also using interrupts)
Code: Select all
// PIC18F4550
void Config(void) {
T0CON = 0b10000000; // Set TMR0 in 8bit mode, assign prescaler to TMR0
TMR0L = 131; // Timer0 initial value
TMR0H = 255;
INTCON = 0b11100000; // Enable TMRO interrupt, and PEIE: Peripheral Interrupt Enable bit
PIE1.RCIE = 1; // enable receive interrupt
PORTA = 0b00000000;
LATA = 0b00000000;
CMCON = 0b00000111; // Turn off Comparator
ADCON0 = 0b00000001; // A/D Converter module is enabled
ADCON1 = 0b00001110; // AN0 Analog, everything else digital
TRISA = 0b11111111; // PORTA is input
// 76543210
PORTB = 0;
LATB = 0b00000000;
TRISB = 0b00000000; // Configure PORTB as output
// 76543210
UCON = 0; // Dissable USB
PORTC = 0;
LATC = 0;
TRISC = 0b00000000; // Configure PORTC as output
// 76543210
PORTD = 0;
LATD = 0;
TRISD = 0b00000000; // Configure PORTD as output
motorz1_enable = 0; // Enable
motorz2_enable = 0; // Enable
motorz_clock = 0; // Clock
motorz_direction = 0; // Direction
motorx_enable = 0; // Enable
motorx_clock = 0; // Clock
motorx_direction = 0; // Direction
motory_enable = 0; // Enable
motory_clock = 0; // Clock
motory_direction = 0; // Direction
//Usart_Init(9600);
Usart_Init(57600);
Pwm1_Init(5000);
Pwm2_Init(5000);
}
const Slave_Addy = 0x69;
void I2C_SendByte(unsigned short send_data){
I2C_Init(100000);
I2C_Start();
I2C_Wr(Slave_Addy);
I2C_Wr(send_data);
I2C_Stop();
}
unsigned short I2C_ReadByte(){
unsigned short read_data;
I2C_Init(100000);
I2C_Start();
I2C_Wr(Slave_Addy + 1);
read_data = I2C_Rd(0);
delay_ms(100);
I2C_Stop();
return read_data;
}
void main(){
long read_count = 0;
long prev_curr_move_pos = 0;
Config();
Pwm1_Start();
Pwm2_Start();
x_power = 110;
y_power = 110;
z_power = 110;
Pwm2_Change_Duty(x_power);
Pwm1_Change_Duty(y_power);
do {
read_count++;
if(cnt >= refresh_interval) { // 20,000 equal to 1 second
cnt -= refresh_interval;
LED1 = !LED1;
I2C_SendByte(75);
LED1 = !LED1;
SendReport(read_count);
read_count = 0;
} else if (buff_len > 0) {
ProcessCommand();
} else if (command_type_done != 0) {
SendReport(read_count);
read_count = 0;
cnt = 0;
CommandComplete();
prev_curr_move_pos = curr_move_pos;
}
} while(1);
}
LED1 = !LED1;
I2C_SendByte(75);
LED1 = !LED1;
The LED is OFF when the program starts, the first line it turns the LED ON, then it's supposed to send the data "75", and turn the LED OFF, therefore showing me how long it takes to send the data.
But the LED never turns OFF, and everything hangs, i.e. even the interrupts stop...
Can you help me please ?
Thank You
Hi, Michael
Your problem may be on the slave side. First, you might check if I2C_Wr was succeed, I2C_Wr return 0 if no error so this is what I come up with.
Assume you have 2 extra LEDs connected to available pins. If you see any of those LED light, the problem is because it's not succeed writen to the slave.
Regards,
I'm sorry about CLK pin, there is no CLK pin for I2C. I was mix up with the SPI. Both SDA and SCL must have pull-up resistors around 4.7K (1K is fine).CVMichael wrote: what is the CLK pin you were talking about earlier ?
Your problem may be on the slave side. First, you might check if I2C_Wr was succeed, I2C_Wr return 0 if no error so this is what I come up with.
Code: Select all
void I2C_SendByte(unsigned short send_data){
I2C_Init(100000); // one time initialize need
I2C_Start();
if (I2C_Wr(Slave_Addy) != 0) LED1 = 1;
if (I2C_Wr(send_data) != 0) LED2 = 1;
I2C_Stop();
}
Regards,
Nick
[url]http://www.pic_examples.byethost3.com/[/url]
[url]http://www.pic_examples.byethost3.com/[/url]
-
- Posts: 2780
- Joined: 25 Dec 2008 15:22
- Location: Scotland
Hi,
i may have missed something by not looking through all the code but...
you are using timer0 as an interrupt source, does the I2C function disable interrupts? if not then you stand the chance of a timer0 int breaking the I2C comm's (unless you disable int's before entry or very carefully time when an I2C communications burst can take place). Similarly if the I2C function where to disable interrupts without your knowledge what effect would that have on your code flow. (i truly cant remember if I2C serial comms library tools disable interrupts on-the-fly and i am on a public PC with no compiler installed to check).
From the schematic... why do you have a pull-up on the PicRx line
i may have missed something by not looking through all the code but...
Code: Select all
LED1 = !LED1;
I2C_SendByte(75);
LED1 = !LED1;
From the schematic... why do you have a pull-up on the PicRx line
The mikroC documentation does not say anything about interrupts in the I2C LibraryMince-n-Tatties wrote:...you are using timer0 as an interrupt source, does the I2C function disable interrupts?
Nick101,
I finally had time to continue working on this project. I did the test you asked me, and it stops at this line:
Code: Select all
if (I2C_Wr(Slave_Addy) != 0) LED1 = 1;
If I comment the I2C_Wr lines, then there are no error, everything is as normal.
Do you have any idea what could be wrong ?
I put a delay after init, but still nothing:
LED4 stays ON, so it means I2C_Wr never returns...
I check the slave code also, it looks right:
I don't know what else to do / check... I am almost giving up. I think I'll have a better change if I make my own protocol comunication between the PICs...
Code: Select all
void I2C_SendByte(unsigned short send_data){
I2C_Init(100000);
delay_ms(50);
LED3 = 1;
I2C_Start();
LED3 = 0;
delay_ms(50);
LED4 = 1;
I2C_Wr(Slave_Addy);
LED4 = 0;
I2C_Wr(send_data);
I2C_Stop();
}
I check the slave code also, it looks right:
Code: Select all
unsigned int cnt = 0;
#define LED1 PORTA.F6
#define LASER PORTA.F7
const Addy = 0x69; // set I2C device address
const Delay_Time = 250; // port check delay
unsigned short j; // just dummy for buffer read
unsigned short rxbuffer;
unsigned short tx_data;
void interrupt(){
if (PIR1.SSPIF == 1){ // I2C Interrupt
if (SSPSTAT.R_W == 1){ // transmit data to master, Read request from master
SSPBUF = tx_data; // Get data to send
SSPCON.CKP = 1; // Release SCL line
j = SSPBUF; // That's it
} else if (SSPSTAT.BF == 0){ // all done,
j = SSPBUF; // Nothing in buffer so exit
} else if (SSPSTAT.D_A == 1){ //recieve data from master, Data [not address]
rxbuffer = SSPBUF; // get data
LED1 = !LED1;
j = SSPBUF; // read buffer to clear flag [address]
} else {
j = SSPBUF; // read buffer to clear flag [address]
PIR1.SSPIF = 0; // reset SSP interrupt flag
}
} else {
TMR0 = 131;
INTCON.TMR0IE = 1;
INTCON.TMR0IF = 0;
//INTCON = 0b00100000; // Set T0IE, clear T0IF
// 76543210
cnt++;
if (cnt > 1000) {
LASER = !LASER;
cnt = 0;
}
}
}
void Config(){
OSCCON = 0b01110000; // Internal 8MHz
//ADCON1 = 0; // All ports set to digital
PORTA = 0;
TRISA = 0b00111111;
// 76543210
TMR0 = 131; // Timer0 initial value
OPTION_REG = 0b10000001; // Assign prescaler to TMR0
// 76543210
PORTB = 0;
TRISB = 0b00000000; // Configure PORTB as output
SSPADD = Addy; // Get address (7bit). Lsb is read/write flag
SSPCON = 0b00110110; // Set to I2C slave with 7-bit address
// 76543210
PIE1.SSPIE = 1; // enable SSP interrupts
INTCON = 0b11100000; // Enable TMRO interrupt AND enable INTCON.GIE
}
void main(){
unsigned int ad0 = 0, ad1 = 0, ad2 = 0, ad3 = 0;
Config();
LED1 = 0;
LASER = 0;
do {
ad0 = Adc_Read(0);
//ad1 = Adc_Read(1);
//ad2 = Adc_Read(2);
//ad3 = Adc_Read(3);
tx_data = ad0 / 4;
Delay_ms(Delay_Time);
} while(1);
}
I did not see the config SCL and SDA as input. Add this in Config() :
Also interrupt flags (SSPIF) need to be clear.
Code: Select all
TRISC |= 0b00011000; // SCL and SDA pins are input
Nick
[url]http://www.pic_examples.byethost3.com/[/url]
[url]http://www.pic_examples.byethost3.com/[/url]
Re: Pic to Pic I2C
Hi,Nick101.Why you suggest this instruction for I2C config;( TRISC |= 0b00011000; // SCL and SDA pins are input )? Why we do not simply write;( TRISC = 0b00011000; )
instead of above instruction?Would you please tell me that?
Thanks,
instead of above instruction?Would you please tell me that?
Thanks,