Datasheet
34
7728G–AVR–06/10
ATtiny87/ATtiny167
It is strongly recommended to run this sequence only once the interrupts have been disabled.
The user (code) is responsible for the correct implementation of the clock switching sequence.
Here is a “light” C-code that describes such a sequence of commands.
Warning:
In the ATtiny87/167, only one among the three external clock sources can be enabled at a
given time. Moreover, the enables of the external clock and of the external low-frequency
oscillator are shared with the asynchronous timer.
4.3.8 Clock Monitoring
A safe system needs to monitor its clock sources. Two domains need to be monitored:
- Clock sources for peripherals,
- Clocks sources for system clock generation.
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
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;
}