|
|
View previous topic :: View next topic |
Author |
Message |
blo
Joined: 11 May 2009 Posts: 22
|
[I2C] pic slave routine doesn't work (ex_slave.c) |
Posted: Wed Oct 06, 2010 7:05 am |
|
|
I'm trying to implement a communication between two pic using the I2C protocol. I'm using the routine of ccs ex_slave.c but i can't read and write in to the slave pic.
the master code:
Code: | #include <30F3013.h>
#include "master.h"
#use rs232(UART2,baud=115200,parity=N,bits=8,xmit=PIN_F5,rcv=PIN_F4,TIMEOUT=1000)
#use i2c(Master,Fast,sda=PIN_F2,scl=PIN_F3,I2C1, FORCE_SW)
#zero_ram
void write_ext_eeprom(BYTE address, BYTE data);
BYTE read_ext_eeprom(BYTE address);
void main()
{
int8 a, i, lettura;
setup_timer2(TMR_DISABLED);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_wdt(WDT_on);
setup_timer1(TMR_DISABLED);
printf("inizalizzazione in corso..\n\r");
while(1)
{
output_bit(LED_OK,0);
for (i=0;i<=10;i++)
{
printf("scrivo %u valore\n\r" i);
write_ext_eeprom(i, i);
delay_ms(10);
}
for(i=0;i<=10;i++)
{
lettura=read_ext_eeprom(i);
printf("valore %u: %u\n\r" i, lettura);
delay_ms(5);
}
delay_ms (2000);
output_bit(LED_OK,1);
delay_ms(400);
}
}
void write_ext_eeprom(BYTE address, BYTE data) {
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_write(data);
i2c_stop();
}
BYTE read_ext_eeprom(BYTE address) {
BYTE data;
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data=i2c_read(0);
i2c_stop();
return(data);
}
|
master pic read from slave always the value 66.
the slave code:
Code: |
#include <18F8722.h>
#include <slave.h>
#use i2c(Slave,Fast,sda=PIN_C4,scl=PIN_C3,force_hw,address=0xa0)
#use rs232(baud=115200, xmit=PIN_c6,rcv=PIN_c7)
BYTE address, buffer[0x10];
#INT_SSP
void ssp_interupt ()
{
BYTE incoming, state;
state = i2c_isr_state();
printf("stato: %u\n\r" state);
if(state <= 0x80) //Master is sending data
{
incoming = i2c_read();
printf("lettura %u\n\r" incoming);
if(state == 1) //First received byte is address
address = incoming;
if(state == 2) //Second received byte is data
buffer[address] = incoming;
}
if(state == 0x80) //Master is requesting data
{
i2c_write(buffer[address]);
}
}
void main()
{
int i;
setup_adc_ports(AN0|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_16|ADC_TAD_MUL_4);
setup_psp(PSP_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_4(T4_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
set_tris_d(0x00); //port d sono uscite
set_tris_c(0xff); //port c sono ingressi
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
while(1)
{
for(i=0;i<=10;i++)
{
printf("valore %u: %u\n\r" i, buffer[i]);
}
delay_ms (3000);
}
}
|
the i2c_isr_state() return always 0, and the i2c_read() return always 0xA0 (slave adress).
Anyone can help me?
Thanks. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Oct 06, 2010 7:16 am |
|
|
What is your compiler version number? |
|
|
blo
Joined: 11 May 2009 Posts: 22
|
|
Posted: Wed Oct 06, 2010 7:19 am |
|
|
I've got the PCWHD V4.096 |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Wed Oct 06, 2010 9:52 am |
|
|
One quick look and I can see that your slave code has printf() statements in the ISR routines, which will take up HUGE amounts of time. All while your master code is just plugging along at top speed, sending each command one after another. Odds are, your slave is still printing after the master is finished sending commands. If you need some kind of visual confirmation that a certain section of your code is being excecuted then just turning on an LED would work. Keep printf() and delays out of interrupts. Also, make sure your master is not sending commands faster than your slave can process each command.
Specifying Fast in your slave #use line does nothing. It's the master that controls the speed of the bus. Setting the tris has no effect without fast_io being specified, as well. I would not set the tris, manually, but allow the compiler control it.
Ronald |
|
|
blo
Joined: 11 May 2009 Posts: 22
|
|
Posted: Thu Oct 07, 2010 5:56 am |
|
|
i've rebuild the project and now the master can write in to the slave, but when the master call the slave for reading, the slave always respond with 0x42.
the new interrupt handler is:
Code: | #INT_SSP
void ssp_interupt ()
{
BYTE incoming, state;
state = i2c_isr_state();
if(state <= 0x80) //Master is sending data
{
incoming = i2c_read();
if(state == 1) //First received byte is address
address = incoming;
if(state == 2) //Second received byte is data
buffer[address] = incoming;
}
if(state == 0x80) //Master is requesting data
{
output_high(led_4);
//i2c_write(buffer[address]);
i2c_write(0b10101010);
}
} |
and the master code:
Code: | void main()
{
int8 data,i;
for (i=0;i<=10;i++)
{
printf("scrivo %u valore\n\r" i);
write_ext_eeprom(i, i); //writing routine goes well
delay_ms(20);
}
// Read from the slave board and display the data.
i2c_start();
i2c_write(0xA0);
i2c_write(0x00);
i2c_start();
i2c_write(0xA1);
data = i2c_read(0);
i2c_stop();
printf("read %u \n\r", data);
while(1);
}
|
|
|
|
blo
Joined: 11 May 2009 Posts: 22
|
|
Posted: Thu Oct 07, 2010 8:47 am |
|
|
I've found the problem:
Code: | BYTE read_ext_eeprom(BYTE address) {
BYTE data;
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_start();
i2c_write(0xa1);
delay_us(10); //without delay it doesn't work!
data=i2c_read(0);
i2c_stop();
return(data);
} |
with the delay it works. |
|
|
|
|
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
|