I2C Problem with ATMega324

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am trying to get the I2C working on a MEGA324 since the last 2 days to no avail, so, I need to ask here perhaps a much more experienced person may know what is going on.

My first try was to use the libraries from Pascal Stang which I've implemented and tested OK with the ATMEGA168.

I have a board with an ATMEGA324 which uses the FT245 chip FIFO to USB (virtual serial) and as i use USB power I prefererred it over the 168 which requires its own power plus a USB to serial converter.

My first try was a direct copy and paste and I made a new project on AVR Studio using the ATMEGA324.

What I found out is that whenever the send start function is called, the whole program works like a never ending loop for all the instructions above this statement to the beginning of the main().

I replaced Pascal's i2cSendStart() by the explicit instruction from the MEGA324 manual:


TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

Exactly same problem , the main behaves like a never ending loop and executes all instructions above this statement.

Then I've written above as

TWCR = (1<<TWINT)|(1<<TWSTA);
TWCR =(1<<TWEN);

Now at least the loop stopped but of course there are like four or five more calls . So I replaced this on all sendstart() but now any other function like write byte etc is the same. Conclusion: anything related to the I2C produces this.

I then decided to change the whole library and use Peter Fleury's , but EXACT same problem !! the I2C will not work.

I've also changed the CHIP with same result.

The attached i2c_FTDI.c is the program.

Please let me know any addittional details you may need .

Could it be a hardware issue ? could be a problem with the clock Frequency? it is using internal RC at 8 MHZ.

Thanks a million in advance for any clue I keep trying but really running out of options on what to change.

Thanks,

Jose.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am thinking that it could indeed be a hardware problem.

As I mentioned I am taking the power from the USB; could it be that the i2c is taking too much current and the voltage drops and the chips resets and restarts ??

I will check that tomorrow , but this could be a condition like when an i2c function is called , the CHIP resets and then this is consistent with executing all statements up to this instruction.

I will check this tomorrow with an scope. The weird thing is why separating the "ORed" registers it seems to pass?

Thanks again,

Jose

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a high opinion of the Fleury library.
I have a low opinion of the Pascal Stang I2C library. all the others are ok)

Using a trusted library is always wise. You know that any problems are down to your hardware. ( or incorrect use of the library)

I note that you are trying to mix-and-match. This is probably the worst of all worlds.

1. Is your SLAVE_W / SLAVE_R address really 0x3A/0x3B ?
2. You should always use status return values. Then you know what has failed.
3. The most common problem is using the wrong SLAVE address. e.g. a 24Cxx is 0xA0/0xA1 and NOT 0x50/0x51.
4. The second most common problem is that people cannot afford the cost of external pull-up resistors.

So use the library code. Use the return values.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It finally was a hardware issue; SCL had a wire going to Reset... :(

I've also found out some errors on the I2C sequence ; it was an extra byte reading which prevented the accelerometer to work. I've attached the corrected and tested OK code in case anyone may find it useful.

David, thanks for your input ; if you see the code I am using the library but not yet with the return values. I imagine this requires to make something like a variable equal to the i2c function, an then putting an IF in order to flag an error or keep going right ?

Concerning your other points , I agree Pascal's library is overcomplicated plus requires you to use a lot of little functions, header files etc., on the other side Peter's is nice just 4 pages of code with all you need for I2C .

Concerning the addresses they are OK , but this is a common issue with the I2C devices; this is an MMA7455 accelerometer and the manufacturer tells you that the device address is 0x1D . On a figure it tells you this address uses bits 6-0. However, this figure has an extra bit on the right side, so in reality the 0x1D is written on bits 7 - 1 of the whole byte , then bit 0 tells to write or read . In summary, 0x1D ends up on being 0x3A for writing or 0x3B for reading.

Concerning the externals pull up resistors it seems to be it is a must.

Thanks again,

Jose

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes. Everything looks a lot tidier now!
Note that you do NOT need this line. TWIE is 0 at RESET.

                          cbi(TWCR, TWIE); // This is required for the TWI to start !!!

In practice, you only need to test the return value from i2c_start(SLAVE). This is necessary because your device may be busy or not even present on the bus. You would have identified your SCL issue immediately.

You would be surprised how keen people are to avoid paying $0.02 for pull-up resistors!

David.