Does using bitmask rewrite the entire register with ones first?

Can someone please explain what is happening here?

Whenever I manipulate any bit in the ADCSRA register using bitmask, the interrupt flag gets reset to 0.
Datasheet states that the only way to reset the flag is to write a 1 to it.

Moreover. If I rewrite the entire register without bitmask, the interrupt flag remains.. as it should.

The only thing I can think of is that during the process of bitmasking operation the entire register is written with ones.... thus resetting the interrupt flag. Is that true? I don't think so.
So what is the explanation?

See the sketch below.

void setup() {
  // put your setup code here, to run once:
 Serial.begin(57600);
 
 Serial.print("ADCSRA Before aRead = ");Serial.println(ADCSRA,BIN);
 Serial.print("analogRead(A0) = ");Serial.println(analogRead(A0));
 Serial.print("ADCSRA AFTER aRead = ");Serial.println(ADCSRA,BIN);
 
 Serial.println("NOTICE interrupt flag (bit 4) is set.");
 Serial.println("Flag should remain set forever or until a binary 1 is written to it.");

Serial.println();
Serial.println();


Serial.println("Now....let's turn off one bit (bit0) using bit mask MASK");
Serial.println();
Serial.println("ADCSRA &= ~(bit(ADPS0))  Turn off ONLY |ADPS0|");
ADCSRA &= ~(bit(ADPS0));
Serial.print("ADCSRA AFTER bit0 is turned off = ");Serial.println(ADCSRA,BIN);
Serial.println("NOTICE bit0 was turned off BUT interrupt flag was ALSO RESET... WHY??.");

Serial.println();
Serial.println();
Serial.println();
Serial.println();
Serial.println();
Serial.println();

Serial.println("Let's try doing aRead and then directly turning off a bit");
Serial.println("by rewriting the entire register");


 Serial.print("ADCSRA Before aRead = ");Serial.println(ADCSRA,BIN);
 Serial.print("analogRead(A0) = ");Serial.println(analogRead(A0));
 Serial.print("ADCSRA AFTER aRead = ");Serial.println(ADCSRA,BIN);
  Serial.println("NOTICE interrupt flag (bit 4) is set.");
 Serial.println("Flag should remain set forever or until a binary 1 is written to it.");

Serial.println();
Serial.println();
Serial.println("Now....let's turn off one bit (bit1) using bit mask MASK");
Serial.println();
Serial.println("ADCSRA=0b10000100");
ADCSRA=0b10000100;

Serial.print("ADCSRA AFTER bit1 is turned off = ");Serial.println(ADCSRA,BIN);
 
Serial.println("NOTICE bit1 was turned off BUT interrupt flag REMAINS SET AS IT SHOULD");

 
}

void loop() {
  // put your main code here, to run repeatedly:

}

Serial output:

ADCSRA Before aRead = 10000111
analogRead(A0) = 389
ADCSRA AFTER aRead = 10010111
NOTICE interrupt flag (bit 4) is set.
Flag should remain set forever or until a binary 1 is written to it.

Now....let's turn off one bit (bit0) using bit mask MASK

ADCSRA &= ~(bit(ADPS0)) Turn off ONLY |ADPS0|
ADCSRA AFTER bit0 is turned off = 10000110
NOTICE bit0 was turned off BUT interrupt flag was ALSO RESET... WHY??.

Let's try doing aRead and then directly turning off a bit
by rewriting the entire register
ADCSRA Before aRead = 10000110
analogRead(A0) = 384
ADCSRA AFTER aRead = 10010110
NOTICE interrupt flag (bit 4) is set.
Flag should remain set forever or until a binary 1 is written to it.

Now....let's turn off one bit (bit1) using bit mask MASK

ADCSRA=0b10000100
ADCSRA AFTER bit1 is turned off = 10010100
NOTICE bit1 was turned off BUT interrupt flag REMAINS SET AS IT SHOULD

You quoted and even highlighted the passage in the datasheet that says that if you do a read-modify-write when an interrupt is pending, the pending interrupt will be cleared. That's because you read 10010111 from the register, '&' it with 11111110 to get 10010110 and write it back. That writes a 1 to bit 4, clearing the pending interrupt.

1 Like

Oh, so that is what "read-modify-write" means?

So when I just write
ADCSRA=0B.......;
it does not use any bitwise operations so then flag remains 1. Correct?

Note that it states "a pending interrupt CAN be disabled" (ambiguous). Does not state WILL reset the flag. Why? Does not always happen?

I think that this should read "can be cleared". If the interrupt flag is set then it's written back as 1 what will reset the flag. The flag will not be cleared only if a 0 is written back to it.

So what's with the CAN it either will or won't.
And why "disable interrupt".
Should state reset flag.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.