Why can't read the CLKPR register?

Hi.

A buddy and I are playing around with timers, trying to get it to run on an atmega328p for 6 hours (he wants to build a program to automatically turn on low-power LEDs on and off).

I wrote a little program to print the CLKPR register to console (which should be readable based on the datasheet table of CLKPR- p. 37)

The console runs and prints:

CLKPR Before:0
CLKPR After:0
CLKPR Before:0
CLKPR After:0

Why is it 0? I was expecting 3.

#define SET(y,x)   y &= (1 << x) 
#define CLEAR(x,y) y &= ~(1 << x)
#define befaft_print(xdes,x,expr,ydes,y) \
                    Serial.print(xdes " Before:");\
                    Serial.println(x);\
                    expr;\
                    Serial.print(ydes " After:");\
                    Serial.println(y);
void setup() {
  Serial.begin(9600); 

  befaft_print("CLKPR",CLKPR, CLKPR=3 ,"CLKPR",CLKPR);
  befaft_print("CLKPR",CLKPR, SET(CLKPR,3) ,"CLKPR",CLKPR);
}

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

Set should be |= not &=

If you change the CLKPR register, Serial.print() won't work.

Changing that register is not nearly as simple as you have assumed. See the data sheet.

You have to set the CLKPCE bit before you can change the lower bits. If you DO succeed in setting the low order two bits, your prescale will be 8 and your Serial will suddenly be 1200 baud instead of 9600. Maybe you can change the baud rate to 76800 right after you change the prescale so you can receive the text at 9600 baud.

void setup() {
  Serial.begin(9600);

  delay(1000);
  
  Serial.print("CLKPR Before:");
  Serial.println(CLKPR);
  CLKPR = 1<<CLKPCE;
  CLKPR = 3;
  Serial.begin(76800);
  Serial.print("CLKPR After:");
  Serial.println(CLKPR);
}

void loop() { }