Testing Pic code for I2C Master/Slave communication New ICD2 (In-Circuit Debugger 2) to program and debug pics!
2007 28 Nov

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:

Pic 16F628 RS232

I have connected my old Psion Series 5MX to the RS232 bus, working as hyper-terminal:

Psion 5MX

Psion Series 5MX

Note that the generated PicC code will send back the parsed data to the Psion via RS232 for debug purpose.

  1. #include <16F628A.h>
  2. #include <stdlib.h>
  3.  
  4. #use delay(clock=4000000)
  5. #use rs232(baud=9600, parity=N, xmit=PIN_B2, rcv=PIN_B1,bits=8,errors)
  6.  
  7. #fuses NOWDT,XT, PUT, NOPROTECT, BROWNOUT, MCLR, NOLVP, NOCPD
  8.  
  9. // PORTB.1 [RB1 pin7]  -> PicRX (RS232 input)
  10. // PORTB.2 [RB2 pin8]  -> PicTX (RS232 output)
  11. // PORTB.4 [RB4 pin10] -> Led Test
  12.  
  13. //————————————————————————————————————————————————————————————
  14. // aux routine
  15. //————————————————————————————————————————————————————————————
  16. struct  CMDDATA {
  17. unsigned int8 id;      // I2C device ID
  18. unsigned int8 type;    // device type
  19. unsigned int8 cmd;     // command
  20. unsigned int8 data0;
  21. unsigned int8 data1;
  22. unsigned int8 data2;
  23. unsigned int8 data3;
  24. unsigned int8 data4;
  25. unsigned int8 data5;
  26. unsigned int8 data6;
  27. unsigned int8 data7;
  28. unsigned int8 data8;
  29. unsigned int8 data9;
  30. unsigned int8 var_usage; // var usage counter (used for structure read/write control)
  31. };
  32.  
  33. struct CMDDATA i2c_data;
  34. int8 rx_buffer[30];
  35. int8 rx_counter = 0;
  36. int1 cmd_init = false;
  37. //————————————————————————————————————————————————————————————
  38. void reset_i2c_data()
  39. {
  40.   i2c_data.id =0;
  41.   i2c_data.type = 0;
  42.   i2c_data.cmd = 0;
  43.   i2c_data.data0 = 0;
  44.   i2c_data.data1 = 0;
  45.   i2c_data.data2 = 0;
  46.   i2c_data.data3 = 0;
  47.   i2c_data.data4 = 0;
  48.   i2c_data.data5 = 0;
  49.   i2c_data.data6 = 0;
  50.   i2c_data.data7 = 0;
  51.   i2c_data.data8 = 0;
  52.   i2c_data.data9 = 0;
  53.   i2c_data.var_usage = 0;
  54. }
  55. //————————————————————————————————————————————————————————————
  56. // sends command back to PC from i2c_data (frame data) - For debug only
  57. void send_received_cmd()
  58. {
  59.   int8 i;
  60.  
  61.   puts("\r\n—————————————————");
  62.   puts("Received Command:");
  63.   for(i=0; i<i2c_data.var_usage; i++)
  64.   {
  65.     switch(i)
  66.     {
  67.       case 0: puts(printf("%u",i2c_data.id));     break;
  68.       case 1: puts(printf("%u",i2c_data.type));   break;
  69.       case 2: puts(printf("%u",i2c_data.cmd));    break;
  70.       case 3: puts(printf("%u",i2c_data.data0));  break;
  71.       case 4: puts(printf("%u",i2c_data.data1));  break;
  72.       case 5: puts(printf("%u",i2c_data.data2));  break;
  73.       case 6: puts(printf("%u",i2c_data.data3));  break;
  74.       case 7: puts(printf("%u",i2c_data.data4));  break;
  75.       case 8: puts(printf("%u",i2c_data.data5));  break;
  76.       case 9: puts(printf("%u",i2c_data.data6));  break;
  77.       case 10: puts(printf("%u",i2c_data.data7)); break;
  78.       case 11: puts(printf("%u",i2c_data.data8)); break;
  79.       case 12: puts(printf("%u",i2c_data.data9)); break;
  80.     }
  81.   }
  82.   puts("—————————————————");
  83. }
  84. //————————————————————————————————————————————————————————————
  85. // receives RS232 frame data and parse it to special object i2c_data
  86. void command_i2d_data()
  87. {
  88.   int8 conversion;
  89.   conversion = atoi(rx_buffer);
  90.  
  91.   if(i2c_data.var_usage > 13) // full
  92.     return;
  93.  
  94.   switch(i2c_data.var_usage)
  95.   {
  96.     case 0: i2c_data.id     = conversion; break;
  97.     case 1: i2c_data.type   = conversion; break;
  98.     case 2: i2c_data.cmd    = conversion; break;
  99.     case 3: i2c_data.data0  = conversion; break;
  100.     case 4: i2c_data.data1  = conversion; break;
  101.     case 5: i2c_data.data2  = conversion; break;
  102.     case 6: i2c_data.data3  = conversion; break;
  103.     case 7: i2c_data.data4  = conversion; break;
  104.     case 8: i2c_data.data5  = conversion; break;
  105.     case 9: i2c_data.data6  = conversion; break;
  106.     case 10: i2c_data.data7 = conversion; break;
  107.     case 11: i2c_data.data8 = conversion; break;
  108.     case 12: i2c_data.data9 = conversion; break;
  109.   }
  110.  
  111.   i2c_data.var_usage = i2c_data.var_usage + 1;
  112.   rx_counter = 0;
  113. }
  114. //————————————————————————————————————————————————————————————
  115. int8 analyse_command(int8 rx_dat)
  116. {
  117.   // checks for init command char
  118.   if(rx_dat == ‘<’ &amp;&amp; cmd_init == false)
  119.   {
  120.     cmd_init = true;
  121.     return -1;
  122.   }
  123.  
  124.   // if command was not initialized will ignore
  125.   if(cmd_init == false)
  126.     return -2;
  127.  
  128.   // check for command end char ‘>’
  129.   if(rx_dat == ‘>’)
  130.   {
  131.     rx_buffer[rx_counter] = \0; // close string
  132.     command_i2d_data(); // converts last command
  133.  
  134.     // test - sends command back to PC (RS232) for debug only
  135.     send_received_cmd();
  136.  
  137.     rx_counter = 0;      // reset new command counter
  138.     cmd_init = false;    // prepare routine for new command
  139.     return 0;
  140.   }
  141.  
  142.   // checks if command is ready to be parsed from frame data to special object
  143.   // (i2c_data -> rx_dat == ‘,’)
  144.   if(rx_dat == ‘,’)
  145.   {
  146.     rx_buffer[rx_counter] = \0; // close string
  147.     rx_counter = rx_counter + 1;
  148.     command_i2d_data(); // converts command
  149.     return 2;
  150.   }
  151.  
  152.   // save char to buffer
  153.   rx_buffer[rx_counter] = rx_dat;
  154.   rx_counter = rx_counter + 1;
  155.   return 1;
  156. }
  157. //————————————————————————————————————————————————————————————
  158. // Main
  159. //————————————————————————————————————————————————————————————
  160. void main()
  161. {
  162.   int8 rx_char, temp;
  163.  
  164.   setup_comparator(NC_NC_NC_NC);
  165.   setup_vref(FALSE);
  166.   set_tris_a(0b11111111);
  167.   set_tris_b(0b11101011);
  168.  
  169.   output_low(PIN_B4);
  170.  
  171.   reset_i2c_data();
  172.  
  173.   while(TRUE)
  174.   {
  175.     if(kbhit())
  176.     {
  177.       rx_char = getc(); // recieve PC char (RS232)
  178.       temp = analyse_command(rx_char);
  179.  
  180.       // recieved end of data frame char ‘>’
  181.       // will blink led for debug purpose
  182.       if(temp == 0)
  183.       {
  184.         output_high(PIN_B4);
  185.         delay_ms(500);
  186.         output_low(PIN_B4);
  187.         delay_ms(500);
  188.       }
  189.     }
  190.   }
  191. }
  192. //————————————————————————————————————————————————————————————

One Response to “Testing Pic code for RS232 and I2C Master communication”

  1. Vibheesh Says:

    Can you send me the comple I2C master code within a day or two ?
    vibheeshbharath@gmail.com

Leave a Reply