Datasheet
36
7728G–AVR–06/10
ATtiny87/ATtiny167
Here is a “light” C-code of a clock switching function using automatic clock monitoring.
C Code Example
void ClockSwiching (unsigned char clk_number, unsigned char sut) {
#define CLOCK
_RECOVER 0x05
#define CLOCK
_ENABLE 0x02
#define CLOCK_SWITCH 0x04
#define CLOCK_DISABLE 0x01
#define WD
_ARL_ENABLE 0x06
#define WD
_2048CYCLES 0x07
unsigned char previous
_clk, temp;
// Disable interrupts
temp = SREG; asm ("cli");
// Save the current system clock source
CLKCSR = 1 << CLKCCE;
CLKCSR = CLOCK
_RECOVER;
previous_clk = CLKSELR & 0x0F;
// Enable the new clock source
CLKSELR = ((sut << 4 ) & 0x30) | (clk
_number & 0x0F);
CLKCSR = 1 << CLKCCE;
CLKCSR = CLOCK
_ENABLE;
// Wait for clock validity
while ((CLKCSR & (1 << CLKRDY)) == 0);
// Switch clock source
CLKCSR = 1 << CLKCCE;
CLKCSR = CLOCK
_SWITCH;
// Wait for effective switching
while (1){
CLKCSR = 1 << CLKCCE;
CLKCSR = CLOCK
_RECOVER;
if ((CLKSELR & 0x0F) == (clk
_number & 0x0F)) break;
}
// Shut down unneeded clock source
if (previous_clk != (clk_number & 0x0F)) {
CLKSELR = previous
_clk;
CLKCSR = 1 << CLKCCE;
CLKCSR = CLOCK_DISABLE;
}
// Re-enable interrupts
SREG = temp;
}
// Enable the watchdog in automatic reload mode
WDTCSR = (1 << WDCE) | (1 << WDE);
WDTCSR = (1 << WDE ) | WD
_2048CYCLES;
CLKCSR = 1 << CLKCCE;
CLKCSR = WD_ARL_ENABLE;