Because the operation may not be atomic, i.e. an interrupt could cause a change to the value of the register between reading, and writing back the new value
An sei() at the end of the function would turn on the interrupts whether they were initially enabled or not. This would result in a pinMode call enabling interrupts even if initially disabled. SREG contains a Global Interrupt Enable bit(cli() and sei() clear and set this bit) By saving the value of SREG and restoring it at the end of the function you only enable the interrupts if they were enabled to begin with.
void setup() {
Serial.println("This is my favorite sketch");
}
void loop() {
Serial.println("I'm entering a time-sensitive part of the program!");
noInterrupts();
digitalWrite(4, HIGH);
delayMicroseconds(1000);
Interrupts();
}
Good thing digitalWrite doesn't enable interrupts, or this wouldn't work*
GoForSmoke:
So it's probably much better to save SREG before cli() and restore SREG later than to just throw cli() and sei() in as needed?
3 steps instead of 2, for better code.
You sarcasm isn't helpful.
You are not understanding that interrupts are not always enabled and so you can't simply blindly mask
them and blindly turn them on.
If you were to do that then interrupts would be turned on when they were disabled before this function were
called.
ISR routines are allowed to call functions like pinMode() and digitalWrite().
Libraries like the servo library, and IRremote call these functions from their ISR.
The issue is that given the way the core code is currently implemented, it uses a |= operation using non compile
time constants, which means it has to mask interrupts to protect the updates that an ISR may do to a port bit
from the foreground port bit updates.
It also has to save and restore the interrupt mask in the status register to ensure that it
doesn't accidentally re-enable interrupts when they are disabled.
Given the way the core code is implemented, there is no way around this.