Но даже в случае sfr16 или _SFR_IO16 надо помнить о прерываниях. Я в avr_gcc для упрощения записи использую макрос
#define ATOMIC_CODE(_statements_4_atomic_execution_) \
do { \
uint8_t _atomic_saved_sreg_ = SREG; \
cli(); \
{ _statements_4_atomic_execution_ } \
SREG = _atomic_saved_sreg_; \
} while(0)
// ну и дальше так
ATOMIC_CODE( OCR3A += period; );
// или так
ATOMIC_CODE(
bit_set(EECR, EEMWE);
bit_set(EECR, EEWE);
);