LEVENT
Joined: 04 May 2006 Posts: 16
|
sequential i2c_read() problem for master |
Posted: Thu Jan 08, 2009 2:23 am |
|
|
Hi, my CCS C compiler version 4.013
I write project to communicate master PIC and slave PIC via I2C protocol. I send buffer array to slave from master, it is ok. After that, I read array from slave it is ok. But I have a problem like that:
1- I write buffer array to slave from master --> ok
2- I read 1 byte value from slave --> ok
3- I read 2 byte value from slave --> fail
is there any problem with 2 or more sequential reading from slave or did I do anything wrong?
master code:
Code: |
#include <16F877A.h>
#FUSES HS
#FUSES NOPROTECT
#FUSES NOLVP
#use delay(clock=4000000)
#use I2C(master, SDA=PIN_C4, SCL=PIN_C3, force_hw)
#define SLAVE_ADDR 0xC0
#define BUFF_SIZE 10
#define SEND_LEN 10
#define RECV_LEN 10
int8 recv_buffer[BUFF_SIZE],
send_buffer[BUFF_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0A};
static int i2c_master_send(int address, int *send, int send_length)
{
i2c_start();
if(send_length){
if(i2c_write(address) == 1){ // NO ACK from slave
return FALSE;
}
while(send_length--){
i2c_write(*send++);
}
}
i2c_stop();
return TRUE;
}
static int i2c_master_recv(int address, int *recv, int recv_length)
{
i2c_start();
if(recv_length){
if(i2c_write(address+1) == 1){ // NO ACK from slave
return FALSE;
}
recv_length--;
while(recv_length--){
*recv++ = i2c_read();
}
*recv = i2c_read(0);
}
i2c_stop();
return TRUE;
}
void main()
{
int send_result,
recv_result;
// send buffer to I2C Slave
send_result = i2c_master_send(SLAVE_ADDR, send_buffer, SEND_LEN);
// read buffer from I2C Slave
recv_result = i2c_master_recv(SLAVE_ADDR, recv_buffer, 1);
recv_result = i2c_master_recv(SLAVE_ADDR, recv_buffer, 2);
.
.
.
|
slave code:
Code: |
#include <16F877.h>
#FUSES NOWDT
#FUSES NOLVP
#FUSES HS
#use delay(clock=4000000)
#use I2C(slave, sda=PIN_C4, scl=PIN_C3, address=0xC0, FORCE_HW)
#define RECV_SIZE 30
int received_buffer[RECV_SIZE];
int isr_state,
received_data = 0,
received_ok = TRUE;
/*
* SSP interrupt
*/
#int_SSP
void i2c_isr()
{
int write_status;
isr_state = i2c_isr_state(); // get isr state
if((isr_state < 0x80)&&(isr_state > 0)) { // if data send master
received_buffer[isr_state-1] = i2c_read(); // save received data
// received_data++;
}
if(isr_state>=0x80) { // if data want master
write_status = i2c_write(received_buffer[isr_state-0x80]); // send previously saved data
}
}
/*
* main program
*/
void main()
{
int i;
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(1);
}
|
And I have notised that, after any STOP signal dedected, i2c_isr_state will be resetted. If at without any STOP signal, array send or array receiving, i2c_isr_state value increment by 1 normally. |
|