sv_shady
Joined: 07 Mar 2008 Posts: 28
|
I2C - reading from slave problem |
Posted: Sun Jun 15, 2008 4:31 am |
|
|
Hi, this is probably my third topic on i2c problems... I have no problems with writing to slave, but now I have to read from slave and of course it doesn't work...
The master is PIC18F4620 and here is its source code:
Code: |
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#use delay(clock=40000000)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3, force_hw)
#define LED PIN_B5
#define I2C_SCL PIN_C3
#define I2C_SDA PIN_C4
#define XBEE 0xAA
#define MOTORS 0XBA
#define WRITE 0x00
#define READ 0x01
#define SEND_DATA 0x01
// n - number of bytes
// n bytes
void Init()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
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_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
}
int value_X = 0, value_Y = 0;
void main()
{
Init();
i2c_start();
i2c_write(XBEE|READ);
value_X = i2c_read();
value_Y = i2c_read(0);
i2c_stop();
/*i2c_start();
i2c_write(XBEE|WRITE);
i2c_write(SEND_DATA);
i2c_write(0x02);
i2c_write(0x15);
i2c_write(0x20);
i2c_stop();*/
} |
The slave is PIC16F88, and the source:
Code: |
#include <16F88.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz)
#FUSES PUT //Power Up Timer
#FUSES MCLR //Master Clear pin enabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOPROTECT //Code not protected from reading
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOIESO //Internal External Switch Over mode disabled
#use delay(clock=20000000)
#use rs232(baud = 9600, parity = N, xmit = PIN_B5, rcv = PIN_B2, bits = 8)
#use i2c(Slave, sda=PIN_B1, scl=PIN_B4, address = 0xAA, force_hw)
#define I2C_SDA PIN_B1
#define I2C_SCL PIN_B4
#define LED PIN_B0
//-------------i2c instructions-------------------------------------------------
#define SEND_DATA 0x01
int c;
int value_X = 128, value_Y = 128;
int instruction = 0;
int nbytes = 0;
int data[16] = {0};
int data_indx = 0;
#int_SSP
void SSP_isr(void)
{
int incoming = 0, state;
output_bit(LED, 1);
state = i2c_isr_state(1);
if(0 < state && state < 0x80)
{
incoming = i2c_read();
if(state == 1) instruction = incoming;
if(state >= 2)
{
switch(instruction)
{
case SEND_DATA:
{
if(state == 2)
{
nbytes = incoming;
data_indx = 0;
}
else data[data_indx++] = incoming;
break;
}
default:;
}
}
}
if(state >= 0x80)
{
if(state == 0x80) i2c_write(value_X);
if(state == 0x81) i2c_write(value_Y);
}
output_bit(LED, 0);
}
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
output_bit(LED, 0);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
for(;;)
{
if(nbytes == data_indx && nbytes != 0)
{
printf("%u%u", data[0], data[1]);
data_indx = 0;
}
}
}
|
When the master writes to the slave everything is OK, but when the master is reading from the slave it hangs at the first i2c_read() statement, and the slave hangs at the i2c_write() statement. When this happens the clock is low. I have tried with software i2c functions for the slave and then the master reads 255... Also I have tried with delay times between the master commands, but nothing... I suppose that the slave stretches the clock but have no idea why. I would be thankful for any help or suggestions. |
|