i2c problems with a PIC18F26K22

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
bradsprojects
Posts: 28
Joined: Thu Nov 29, 2012 12:29 am
Location: Australia

i2c problems with a PIC18F26K22

Post by bradsprojects » Wed May 21, 2014 1:38 pm

Hi everyone. I have been working on a little project that uses a texas instruments ina220 power measuring chip that interfaces to my 18f26k22 microcontroller by i2c.

The first of my problems is that the standard i2c library will not work for me at all. For example here's some code that talks to the ina220 chip via the i2c bus. It tells it which register to access and then reads 16-bits of data from this register (this is the current data that it is measuring).

Code: Select all

Device = 18F26K22         // Tell the compiler what chip we are using    
Clock = 16                      
Config FOSC = INTIO67
Config MCLRE = INTMCLR

Dim reading As Word

Include "I2C.bas"  
// Start Of Program... 
OSCCON = %01110111                // Sets the internal oscillator for 16Mhz
I2C.Initialize()

// Main Loop 
While True()                            // This creates an infinite loop 
  I2C.Start
    I2C.WriteByte(%10000000)     // point to the ina220 chip and put it in write mode (the LSB as a 0 means write)
    I2C.WriteByte($04)            // sets register pointer to the Current register
  I2C.Restart      
    I2C.WriteByte(%10000001)                                // point to the ina220 chip and put it in read mode (the LSB as a 1 means read)
    reading = I2C.ReadByte(I2C_ACKNOWLEDGE)                 // receive high byte (overwrites previous reading)
    reading = reading << 8                                   // shift high byte to be high 8 bits
    reading = reading Or I2C.ReadByte(I2C_NOT_ACKNOWLEDGE)  // receive low byte as lower 8 bits  
  I2C.Stop                                                  // stop transmitting
Wend

This compiles and uploads to the microcontroller just fine, however when I check the i2c bus with my logic analyser, they are permanently held LOW. I should mention that YES I do have pull-up resistors on the SDA and SCL lines plus, I am using the correct i2c bus within the 18f26k22 (I mention that because there are two).

Now having said that, If I modify the code to si2c instead of just i2c it actually works! Like this:

Code: Select all

Device = 18F26K22         // Tell the compiler what chip we are using    
Clock = 16                      
Config FOSC = INTIO67
Config MCLRE = INTMCLR

Dim reading As Word

Include "SI2C.bas"  
// Start Of Program... 
OSCCON = %01110111                // Sets the internal oscillator for 16Mhz
SI2C.Initialize()

// Main Loop 
While True()                            // This creates an infinite loop 
 SI2C.Start
    SI2C.WriteByte(%10000000)     // point to the ina220 chip and put it in write mode (the LSB as a 0 means write)
    SI2C.WriteByte($04)            // sets register pointer to the Current register
  I2C.Restart      
    SI2C.WriteByte(%10000001)                                // point to the ina220 chip and put it in read mode (the LSB as a 1 means read)
    reading = SI2C.ReadByte(I2C_ACKNOWLEDGE)                 // receive high byte (overwrites previous reading)
    reading = reading << 8                                   // shift high byte to be high 8 bits
    reading = reading Or SI2C.ReadByte(I2C_NOT_ACKNOWLEDGE)  // receive low byte as lower 8 bits  
  I2C.Stop                                                  // stop transmitting
Wend

You can see the results in my logic analyser data:
screen-capture-11.png
screen-capture-11.png (36.65 KiB) Viewed 3307 times
So that is clearly working when I use Si2c instead of i2c. However, even though I can see it all working through the logic analyser, the variable 'reading' never gets updated with any data from the i2c received data.

Does anyone have any thoughts / suggestions as to why the standard i2c.bas won't work and I guess more importantly, why my variable 'reading' does not get updated with data from the i2c read command - even though I can see that the i2c communication is working?

Thanks for any help guys.

User avatar
David Barker
Swordfish Developer
Posts: 1214
Joined: Tue Oct 03, 2006 7:01 pm
Location: Saltburn by the Sea, UK
Contact:

Re: i2c problems with a PIC18F26K22

Post by David Barker » Wed May 21, 2014 1:53 pm

Unfortunately I cant test here so I don't know why the software read is not giving you the correct results. Try assigning to Byte1 and Byte0 to see if that makes a difference. The software routines are basic shift in and out, so check them out to ensure the timings look ok for you.

bradsprojects
Posts: 28
Joined: Thu Nov 29, 2012 12:29 am
Location: Australia

Re: i2c problems with a PIC18F26K22

Post by bradsprojects » Wed May 21, 2014 2:03 pm

Thanks David, I tried using individual bytes and checking their contents but still no dice. It doesn't matter what variable I declare, it will just not store any data in them.

It is really boggling my mind at the moment!

I can even update the contents of the various 'configuration' registers within the ina220 chip and then I can read them back to check their contents. Looking at the logic analyser data, everything is perfect. But for some reason it is just not storing this received data in to my variable when I do a read.

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: i2c problems with a PIC18F26K22

Post by Jerry Messina » Wed May 21, 2014 2:54 pm

For the 26K22, the pins are shared with analog functions... RC3/SCL1 is AN15, and RC4/SDA1 is AN16. Make sure they're set to digital mode using the ANSELC register, otherwise they'll read as '0'.

You might also want to clear the SLRC Slew Rate control bit for PortC (SLRCON.2)

bradsprojects
Posts: 28
Joined: Thu Nov 29, 2012 12:29 am
Location: Australia

Re: i2c problems with a PIC18F26K22

Post by bradsprojects » Thu May 22, 2014 2:02 pm

Thanks for your help Jerry.

I was so focused on looking into my problem in one particular area that I didn't even bother to think of something as straight forward as that!

I changed the settings in the ANSELC register to ensure RC3 and RC4 were set to digital and all is working now! Just for info, it works fine saving the two received bytes into the 'reading' word. I received the high byte first, shift it across to the high byte of the 'reading' word and then I OR it with the second incoming byte which is the low byte.

Thanks again for your help David and Jerry, much appreciated!

Post Reply