Still haven’t completed I2C Master/Slave communication test, but will move on!
I’m now defining how PC will communicate with PIC Master, how will the Robot computer send commands and receive data to the Master PIC. The Master PIC will them make the interface between PC and Sensors/Modules trough an I2C bus.
I have decided to send commands in the following format (PC to PIC Master - frame data):
<id, type, cmd, data0, data1, data2, data3, data4, data5, data6, data7, data8, data9>
id = device ID number (Slave or Master)
type = defines type of sensor/module {10=DCmotor, 11-Servo, …}
cmd = command
data0 to data1 = additional data
The Master PIC will receive the command from Robot computer (Via RS232) and parse it into a special object that will be sent to sensors/modules trough the I2C channel. After sending the commands in the I2C channel, the Master PIC will wait for the acknowledge of that command from the sensor/module. PIC Master will then read data from sensors/modules and save data into special object. When receiving the last byte from sensors/modules, PIC Master will them compose frame data and send it back to Robot computer.
For this test I have used the same circuit from RS232 test:
I have connected my old Psion Series 5MX to the RS232 bus, working as hyper-terminal:
Note that the generated PicC code will send back the parsed data to the Psion via RS232 for debug purpose.
-
#include <16F628A.h>
-
#include <stdlib.h>
-
-
#use delay(clock=4000000)
-
#use rs232(baud=9600, parity=N, xmit=PIN_B2, rcv=PIN_B1,bits=8,errors)
-
-
#fuses NOWDT,XT, PUT, NOPROTECT, BROWNOUT, MCLR, NOLVP, NOCPD
-
-
// PORTB.1 [RB1 pin7] -> PicRX (RS232 input)
-
// PORTB.2 [RB2 pin8] -> PicTX (RS232 output)
-
// PORTB.4 [RB4 pin10] -> Led Test
-
-
//————————————————————————————————————————————————————————————
-
// aux routine
-
//————————————————————————————————————————————————————————————
-
struct CMDDATA {
-
unsigned int8 id; // I2C device ID
-
unsigned int8 type; // device type
-
unsigned int8 cmd; // command
-
unsigned int8 data0;
-
unsigned int8 data1;
-
unsigned int8 data2;
-
unsigned int8 data3;
-
unsigned int8 data4;
-
unsigned int8 data5;
-
unsigned int8 data6;
-
unsigned int8 data7;
-
unsigned int8 data8;
-
unsigned int8 data9;
-
unsigned int8 var_usage; // var usage counter (used for structure read/write control)
-
};
-
-
struct CMDDATA i2c_data;
-
int8 rx_buffer[30];
-
int8 rx_counter = 0;
-
int1 cmd_init = false;
-
//————————————————————————————————————————————————————————————
-
void reset_i2c_data()
-
{
-
i2c_data.id =0;
-
i2c_data.type = 0;
-
i2c_data.cmd = 0;
-
i2c_data.data0 = 0;
-
i2c_data.data1 = 0;
-
i2c_data.data2 = 0;
-
i2c_data.data3 = 0;
-
i2c_data.data4 = 0;
-
i2c_data.data5 = 0;
-
i2c_data.data6 = 0;
-
i2c_data.data7 = 0;
-
i2c_data.data8 = 0;
-
i2c_data.data9 = 0;
-
i2c_data.var_usage = 0;
-
}
-
//————————————————————————————————————————————————————————————
-
// sends command back to PC from i2c_data (frame data) - For debug only
-
void send_received_cmd()
-
{
-
int8 i;
-
-
puts("\r\n—————————————————");
-
puts("Received Command:");
-
for(i=0; i<i2c_data.var_usage; i++)
-
{
-
switch(i)
-
{
-
}
-
}
-
puts("—————————————————");
-
}
-
//————————————————————————————————————————————————————————————
-
// receives RS232 frame data and parse it to special object i2c_data
-
void command_i2d_data()
-
{
-
int8 conversion;
-
conversion = atoi(rx_buffer);
-
-
if(i2c_data.var_usage > 13) // full
-
return;
-
-
switch(i2c_data.var_usage)
-
{
-
case 0: i2c_data.id = conversion; break;
-
case 1: i2c_data.type = conversion; break;
-
case 2: i2c_data.cmd = conversion; break;
-
case 3: i2c_data.data0 = conversion; break;
-
case 4: i2c_data.data1 = conversion; break;
-
case 5: i2c_data.data2 = conversion; break;
-
case 6: i2c_data.data3 = conversion; break;
-
case 7: i2c_data.data4 = conversion; break;
-
case 8: i2c_data.data5 = conversion; break;
-
case 9: i2c_data.data6 = conversion; break;
-
case 10: i2c_data.data7 = conversion; break;
-
case 11: i2c_data.data8 = conversion; break;
-
case 12: i2c_data.data9 = conversion; break;
-
}
-
-
i2c_data.var_usage = i2c_data.var_usage + 1;
-
rx_counter = 0;
-
}
-
//————————————————————————————————————————————————————————————
-
int8 analyse_command(int8 rx_dat)
-
{
-
// checks for init command char
-
if(rx_dat == ‘<’ && cmd_init == false)
-
{
-
cmd_init = true;
-
return -1;
-
}
-
-
// if command was not initialized will ignore
-
if(cmd_init == false)
-
return -2;
-
-
// check for command end char ‘>’
-
if(rx_dat == ‘>’)
-
{
-
rx_buffer[rx_counter] = ‘\0‘; // close string
-
command_i2d_data(); // converts last command
-
-
// test - sends command back to PC (RS232) for debug only
-
send_received_cmd();
-
-
rx_counter = 0; // reset new command counter
-
cmd_init = false; // prepare routine for new command
-
return 0;
-
}
-
-
// checks if command is ready to be parsed from frame data to special object
-
// (i2c_data -> rx_dat == ‘,’)
-
if(rx_dat == ‘,’)
-
{
-
rx_buffer[rx_counter] = ‘\0‘; // close string
-
rx_counter = rx_counter + 1;
-
command_i2d_data(); // converts command
-
return 2;
-
}
-
-
// save char to buffer
-
rx_buffer[rx_counter] = rx_dat;
-
rx_counter = rx_counter + 1;
-
return 1;
-
}
-
//————————————————————————————————————————————————————————————
-
// Main
-
//————————————————————————————————————————————————————————————
-
void main()
-
{
-
int8 rx_char, temp;
-
-
setup_comparator(NC_NC_NC_NC);
-
setup_vref(FALSE);
-
set_tris_a(0b11111111);
-
set_tris_b(0b11101011);
-
-
output_low(PIN_B4);
-
-
reset_i2c_data();
-
-
while(TRUE)
-
{
-
if(kbhit())
-
{
-
rx_char = getc(); // recieve PC char (RS232)
-
temp = analyse_command(rx_char);
-
-
// recieved end of data frame char ‘>’
-
// will blink led for debug purpose
-
if(temp == 0)
-
{
-
output_high(PIN_B4);
-
delay_ms(500);
-
output_low(PIN_B4);
-
delay_ms(500);
-
}
-
}
-
}
-
}
-
//————————————————————————————————————————————————————————————
December 4th, 2008 at 4:22 am
Can you send me the comple I2C master code within a day or two ?
vibheeshbharath@gmail.com