I2C1_Wr / I2C1_Rd functions hang with MikroC for PIC – Need Timeout

In some cases both the MikroC i2c functions I2C1_Wr() and I2C1_Rd() can hang or lockup indefinitely until the PIC is reset. This can happen if the I2C bus isn’t properly terminated, for example if a connection breaks or similar (broken wire or solder joint etc). Having your PIC lockup during operation is generally not very desirable if your are trying to develop a stable software system – if for some reason an i2c device hasn’t been properly connected your system will just lockup for good!

Different posts discuss this problem and its various causes:


MikroC provided the code to their functions so that software developers (us) could work around the problem, this library implements versions of I2C1_Wr() and I2C1_Rd() that timeout rather than hang, a timeout values is passed as a parameter:

The library doesn’t implement a C version, so inspired by it (thanks Danny!) I have ported the functions into C, and added some comments – use at your own risk, it works well for me on PIC18F family chips but hasn’t been exhaustively tested!

I have declared the timeouts as constants rather than allowing the timeout to be passed in as a parameter – this is so that the functions can be used as drop-in replacements without having to modify client code.

And to Read:

This works for the first i2c device, it is left as an exercise for the reader to convert it for a second i2c device, i.e. I2C2_Wr() and I2C2_Rd()

Setup PIC Timer with Interrupt Example (18F Family, MikroC)

software development on PIC microcontroler

Setting up a PIC timer to the correct frequency can be a tricky business for the uninitiated Software Engineer (i.e. Me). So I was pretty happy when I came across this great on-line tool whereby you just type in your oscillator frequency and desired interrupt rate and it generates the setup code for you!

For example I have an 8Mhz clock and wanted a 1KHz interrupt on Timer0, I punched that in and the tool said I should use this set-up code:

Happy days!

Now there is a little more to defining the software interrupt handler and enabling the interrupt so I have included the code for a slightly more verbose example that configures and enables Timer0 via mikroC on the PIC18F25K22: