New ICD2 (In-Circuit Debugger 2) to program and debug pics! Testing PIC 16F690 PWM 4 multiplexed channels
2008 01 Feb

I have now completed my I2C Master/Slave communication test. Quite happy with the results! Before getting started I needed to refresh my memory on I2C protocol, how Master and Slave devices would communicate, how data flow between devices. Found this nice tutorial on the web: http://www.best-microcontroller-projects.com/i2c-tutorial.html

Has I referred on previous posts, the PIC 16F690 will now support I2C protocol by hardware for the slave device, meaning that Interrupt Service Routine will be available, serving I2C Master whenever necessary without the necessity to pool the I2C bus. This also will permit Slave PIC to run other tasks like acquiring data from Analog-to-Digital inputs, control outputs, read inputs, etc, and still server PIC Slave without causing any delay on I2C bus. Unfortunately I2C Master is not supported by hardware for this PIC. Not a problem, Master PIC will receive commands from PC (Via RS232 interface - serial communication) that will be stored on buffer to be processed whenever possible!

For the test I’ve used 2 PICs 16F690 @ 4Mhz and 1 RS232 interface for debug. Master PIC will connect to Lab PC by RS232 (COM1) for debugging purpose and to Slave PIC by I2C bus.

PIC I2C Master/Slave communication

Just picked some examples for I2C communication and found the most common example ‘how to communicate with IC2 eeprom’ and decided to simulate this with my PICs. For my test the Master PIC will send 16 bytes of data to Slave PIC that will store in memory for later request. Before sending data Master PIC need to ‘address’ the bus with the Slave ID and after this will send the 2 bytes. The 1st byte will be interpreted by Slave PIC has ‘internal memory address’ and the 2nd byte has generic data. This process will be repeated 16 times with different ‘internal memory address’ and data. The next step Master PIC will request 1 byte to Slave PIC of a specific ‘internal memory address’. Please check code to see how easy it is!

Master PIC:

  1. #include <16F690.h>
  2. #use delay(clock=4000000)
  3. #fuses NOWDT, HS, PUT, NOPROTECT, BROWNOUT, MCLR, NOCPD
  4. //————————————————————————————————————————————————————————————
  5. #use i2c(Master, sda=PIN_C2, scl=PIN_C3) // I2C by software
  6. //————————————————————————————————————————————————————————————
  7. #use rs232(baud=9600, parity=N, xmit=PIN_B7, rcv=PIN_B5, bits=8, errors)
  8. //————————————————————————————————————————————————————————————
  9. // PORTC.2 [RC2 pin14]  -> I2C SDA (I2C Serial Data)
  10. // PORTC.3 [RC3 pin7]   -> I2C SCL (I2C Serial Clock)
  11. //————————————————————————————————————————————————————————————
  12. // PORTB.5 [RB5 pin12]  -> PicRX (RS232 input)
  13. // PORTB.7 [RB7 pin10]  -> PicTX (RS232 output)
  14. //————————————————————————————————————————————————————————————
  15. int x;
  16.  
  17. BYTE result;void main()
  18. {
  19.   delay_ms(200); // power up delay
  20.   setup_adc_ports(NO_ANALOGS | VSS_VDD);
  21.   setup_comparator(NC_NC_NC_NC);
  22.   setup_oscillator(OSC_4MHZ);
  23.   set_tris_a(0b11111111);
  24.   set_tris_b(0b01111111 ); // Port B 00110000 ( Bit5/7 - RS232- Rx/tx)
  25.   set_tris_c(0b10110011);
  26.  
  27.   while(1)
  28.   {
  29.     printf("\r\nI2C Master - Started!\r\n"); // debug to PC serial port - RS232
  30.     output_low(PIN_C6); // Led for visual debug
  31.     delay_ms(500);
  32.     delay_ms(500);
  33.     delay_ms(500);
  34.     delay_ms(500);
  35.     delay_ms(500);
  36.     output_high(PIN_C6);
  37.     delay_ms(500);
  38.     delay_ms(500);
  39.     delay_ms(500);
  40.     delay_ms(500);
  41.     delay_ms(500);
  42.     output_low(PIN_C6);
  43.  
  44.     for(x=0;x<=15;x++)
  45.     {
  46.       i2c_start ();        // init I2C protocol
  47.       i2c_write (0xA0); // slave device address
  48.       i2c_write (x);      // slave ‘internal memory address’ [0;15]
  49.       i2c_write(15-x);  // data
  50.       i2c_stop();         // stop communication with slave
  51.       delay_ms(50);
  52.       i2c_start ();       // init I2C protocol
  53.       i2c_write (0xA1); // slave device address
  54.       result = i2c_read(0); // read slave last received data
  55.       i2c_stop ();        // stop communication with slave
  56.       printf("Result[%d]=%d\r\n",x,result); // debug data
  57.       delay_ms(50);
  58.     }
  59.  
  60. // test
  61.       i2c_start ();
  62.       i2c_write (0xA0);
  63.       i2c_write (5); // request slave ‘internal memory address’ 0×05
  64.       i2c_stop();
  65.       delay_ms(50);
  66.       i2c_start ();
  67.       i2c_write (0xA1);
  68.       result = i2c_read(0); // read slave data
  69.       i2c_stop ();
  70.       printf("ReadAddress(5)=%d\r\n",result);
  71.       delay_ms(50);
  72.    }
  73. }
  74. //————————————————————————————————————————————————————————————

 

Slave PIC:

  1. #include <16F690.h>
  2. #use delay(clock=4000000)
  3. #fuses NOWDT, HS, PUT, NOPROTECT, BROWNOUT, MCLR, NOCPD
  4. //————————————————————————————————————————————————————————————
  5. #use i2c(SLAVE, SDA=PIN_B4, SCL=PIN_B6, address=0xA0, FORCE_HW) // I2C by Hardware
  6. //————————————————————————————————————————————————————————————
  7. // PORTC.2 [RC2 pin14]  -> I2C SDA (I2C Serial Data)
  8. // PORTC.3 [RC3 pin7]   -> I2C SCL (I2C Serial Clock)
  9. //————————————————————————————————————————————————————————————
  10. BYTE incoming, state; // I2C vars
  11. BYTE address, buffer[0×10]; // Address and Array of Bytes
  12.  
  13. #INT_SSP
  14. void ssp_interupt ()
  15. {
  16.   state = i2c_isr_state();
  17.  
  18.   if(state < 0×80) //Master is sending data
  19.   {
  20.     if(state == 0)
  21.     {
  22.     }
  23.     if(state == 1)  //First received byte is address
  24.     {
  25.       incoming = i2c_read();
  26.       address = incoming;
  27.     }
  28.     if(state == 2)  //Second received byte is data
  29.     {
  30.       incoming = i2c_read();
  31.       buffer[address] = incoming;
  32.     }
  33.   }
  34.   if(state == 0×80)  //Master is requesting data
  35.   {
  36.     i2c_write (buffer[address]);
  37.   }
  38. }
  39. //————————————————————————————————————————————————————————————
  40. void main()
  41. {
  42.   delay_ms(200); // power up delay
  43.   setup_comparator(NC_NC_NC_NC);
  44.   setup_vref(FALSE);
  45.   set_tris_A ( 0b11111111 );      // Port A 11111111
  46.   set_tris_B ( 0b01111111 );      // Port B 00110000 ( Bit5/7 - RS232- Rx/tx)
  47.   set_tris_C ( 0b11111111 );      // Port C 11111111
  48.  
  49.   enable_interrupts(INT_SSP);
  50.   enable_interrupts(GLOBAL);
  51.  
  52.   while(TRUE)
  53.   {
  54.     // main code here …
  55.   }
  56. }
  57. //————————————————————————————————————————————————————————————

 

PC Serial Port output - Master PIC Debug

  1. I2C Master - Started!
  2. Result[0]=15
  3. Result[1]=14
  4. Result[2]=13
  5. Result[3]=12
  6. Result[4]=11
  7. Result[5]=10
  8. Result[6]=9
  9. Result[7]=8
  10. Result[8]=7
  11. Result[9]=6
  12. Result[10]=5
  13. Result[11]=4
  14. Result[12]=3
  15. Result[13]=2
  16. Result[14]=1
  17. Result[15]=0
  18. ReadAddress(5)=10

 

After this successfully test only need to make one more before getting the modules all together. Still need to test how to make PWM pulse available on 2 distinct outputs to control H-Bridge. I need to switch between outputs in order to change engine direction …

  [1,999 views]
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

4 Responses to “Testing Pic code for I2C Master/Slave communication”

  1. Luc Bonnet Says:

    Hi,
    Very nice design!
    Please give me a description of your software development setup, so I will try to get the same tools as you.
    Until now, I use 8051 with Keil compiler, and I want to use PIC’s as I2C slaves.
    Thanks in advance.

    Luc

  2. Nelson Neves Says:

    Hi Luc,

    thank you for your post! You can check for my software development setup in this post: http://www.botdream.com/blog/2007/11/16/softwarehardware-that-ill-use-to-work-with-microchip-pics/

    and I’ve just acquired a new PIC programmer/debugger :
    http://www.botdream.com/blog/2007/11/16/softwarehardware-that-ill-use-to-work-with-microchip-pics/

    Please notice that the PIC C compiler is not free, there are some good tools that are free, but I am more comfortable to work with this tool (CCSinfo) because I found it easy and quick to develop. They have a big community and you can check some problems and solutions in their forum! (you can find lots off source code there, it helps to see how things work)

    Also used 8051 some years ago, and really loved to work with it, but found that Microchip pics are very chip and don’t require much of external components to make it work.

    Please feel free to check other opensource and free PIC C compilers! There are very good tools out there! I haven’t had time to test it :(

  3. Ben Says:

    Hi Nelson,
    First, congratulation for your blog. It’s clear and practical.
    By the other hand, I have searched what type of C have you used for the PICs. I think that could be MikroC, but you are using function that are not implemented with the MikroC. Could do you say me what Pic C are you using in your projects? (at the pwm, and i2c projects)
    Thanks!
    Ben.

  4. Nelson Neves Says:

    Hi Ben,

    thank you for your interest! The C compiler that I am using is CCSInfo PICC PCWH Compiler 4.016. Unfortunately it is a payed tool, but very well supported and have a very good library. Most of the functions in my code are from the tool’s library. Please check my Lab tools to get more info: http://www.botdream.com/blog/2007/11/16/softwarehardware-that-ill-use-to-work-with-microchip-pics/

    I finally decided to use PIC 16F690 for the PWM and I2C support. You can find more details on PIC datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/41262E.pdf

    I have another post that explains why I have changed from PIC 16F628A to 16F690 due to issues with PWM and H-Bridge interface:
    http://www.botdream.com/blog/2008/02/02/testing-pic-16f690-pwm-4-multiplexed-channels/

    I’m quite busy at the moment doing other projects but hope to get back to my robot ASAP. ;)

Leave a Reply