TWI or I2C : I don't understand how to use the TWINT flag

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

Hi,

 

I am learning how to use TWI (I²C) by reading the documentation and tutorials on the Internet. I have a little problem about how the TWINT flag in the TWSR register is used.

 

Let's talk about the basics : send a START condition. To do it, as the documentation says:

TWEN must be set to enable the 2-wire Serial Interface, TWSTA must be written to one to transmit a START
condition and TWINT must be written to one to clear the TWINT Flag.

Ok. So I write those 3 bits to one : TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

My TWSR register is now : 10100100b (the MSB is TWINT).

 

What I understand is that we clear the TWINT Flag by setting it to 1. So TWINT is a 1.

 

Then, we need to wait that the START condition has been sent. For that, as it is write in the documentation :

After a START condition has been transmitted, the TWINT Flag is set by hardware.

OK, so I need to wait for the TWINT Flag to be set, so equal to 0.

 

To do that, what I would do would be to code a while condition like it: while(TWINT FLAG is equal to 1);

For me, I write it like this : while(TWSR & (1<<TWINT));

 

BUT, EVERYWERE ON THE INTERNET I FIND : while(!(TWSR & (1<<TWINT)));

Even on the AVR documentation.

 

I am on it for hours, maybe that I am missing the obvious... Why does everybody check the opposite?

 

Thank you. :)

This topic has a solution.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, so I need to wait for the TWINT Flag to be set, so equal to 0.

"set" in my dialect means "1" not "0".

 

Sure it is possibly "odd" that to clear flags you write 1 (but there's a good reason for that) but the flag itself is "the right way up". It is 0 when the interrupt hasn't occurred and changes to 1 when it does occur. A short time later the CPU opcode fetching mechanism will notice this change and then vector to ISR handler (if its been enabled).

 

As for clearing the flag. If it is 1 saying "the interrupt recently occurred" and you write 1 to it that actually sets it back to 0. This is where the "odd" bit comes in.

Last Edited: Thu. Feb 26, 2015 - 04:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK so I understand that if I write a 1 to TWINT, then TWINT will become 0. TWINT takes the oposite value of what you write to it. Right ? That would explain why I don't understand...

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

TWINT takes the oposite value of what you write to it. Right ?

It has been a common practice for decades by micros manufacturers to write a 1 to register bits in order to clear them, not Atmel specific.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Setting bits to 0 generally involves IN/AND/OUT to isolate only the bits to be changed. Whereas using 1 bits you can do it in a single write (which is therefore atomic).

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

bobby4078 wrote:
TWINT takes the oposite value of what you write to it. Right ?
No.  Writing '1' will cause the flag to be cleared.  Writing '0' does nothing at all.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]