1 | extern char gPowerSaveTimer; // external Counter from "RTC.c"
|
2 | char PowerSaveTimeout = 5;
|
3 | char PowerSave = FALSE;
|
4 |
|
5 | int main( void )
|
6 | {
|
7 | char str[] = "12345";
|
8 |
|
9 | clock_init_8MHz();
|
10 | USART_Init(103); // 9600bps by 8MHz
|
11 | RTC_init();
|
12 |
|
13 | __enable_interrupt();
|
14 |
|
15 | for(;;) // main loop
|
16 | {
|
17 | if (!PowerSave)
|
18 | {
|
19 | uart_put_string(str);
|
20 | PowerSave = TRUE; // enter sleep mode
|
21 | gPowerSaveTimer = 0;
|
22 | }
|
23 |
|
24 | else
|
25 | {
|
26 | SMCR = (3<<SM0) | (1<<SE); // Enable Power-save mode
|
27 | __sleep(); // Go to sleep
|
28 | }
|
29 | SMCR = 0; // Just woke, disable sleep
|
30 | }
|
31 | }
|
32 |
|
33 | void clock_init_8MHz(void)
|
34 | {
|
35 | CLKPR = (1<<CLKPCE); // set Clock Prescaler Change Enable
|
36 |
|
37 | // set prescaler = 8, Inter RC 8Mhz / 1 = 8Mhz
|
38 | CLKPR = 0;
|
39 | }
|
40 |
|
41 | void Delay(unsigned int millisec)
|
42 | {
|
43 | int i;
|
44 |
|
45 | while (millisec--)
|
46 | for (i=0; i<125; i++);
|
47 | }
|
48 |
|
49 | void USART_Init(unsigned int baudrate)
|
50 | {
|
51 | // Set baud rate
|
52 | UBRR0H = (unsigned char)(baudrate>>8);
|
53 | UBRR0L = (unsigned char)baudrate;
|
54 |
|
55 | // Enable 2x speed
|
56 | UCSR0A = (1<<U2X0);
|
57 |
|
58 | // Enable receiver and transmitter
|
59 | UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(0<<RXCIE0)|(0<<UDRIE0);
|
60 |
|
61 | // Async. mode, 8N1
|
62 | UCSR0C = (0<<UMSEL0)|(0<<UPM00)|(0<<USBS0)|(3<<UCSZ00)|(0<<UCPOL0);
|
63 | }
|
64 |
|
65 | void Usart_Tx(char data)
|
66 | {
|
67 | UCSR0A = UCSR0A; // clear TXC0 !!!
|
68 | UDR0 = data;
|
69 | while (!(UCSR0A & (1<<TXC0)));
|
70 | }
|
71 |
|
72 | void uart_put_string (char *data_string)
|
73 | {
|
74 | while(*data_string) Usart_Tx(*(data_string++));
|
75 | }
|
76 |
|
77 | /******************************************************************************
|
78 | *
|
79 | * Function name: RTC_init
|
80 | *
|
81 | * returns: none
|
82 | *
|
83 | * parameters: none
|
84 | *
|
85 | * Purpose: Start Timer/Counter2 in asynchronous operation using a
|
86 | * 32.768kHz crystal.
|
87 | *
|
88 | *******************************************************************************/
|
89 | void RTC_init(void)
|
90 | {
|
91 | Delay(1000); // wait for 1 sec to let the Xtal stabilize after a power-on,
|
92 |
|
93 | __disable_interrupt(); // disabel global interrupt
|
94 |
|
95 | cbi(TIMSK2, TOIE2); // disable OCIE2A and TOIE2
|
96 |
|
97 | ASSR = (1<<AS2); // select asynchronous operation of Timer2
|
98 |
|
99 | TCNT2 = 0; // clear TCNT2A
|
100 | TCCR2A |= (1<<CS22) | (1<<CS20); // select precaler: 32.768 kHz / 128 = 1 sec between each overflow
|
101 |
|
102 | while((ASSR & (0x01 | 0x04))); // wait for TCN2UB and TCR2UB to be cleared
|
103 |
|
104 | TIFR2 = 0xFF; // clear interrupt-flags
|
105 | sbi(TIMSK2, TOIE2); // enable Timer2 overflow interrupt
|
106 |
|
107 | OCR2A = 200; // set timer2 compare value
|
108 |
|
109 | __enable_interrupt(); // enable global interrupt
|
110 | }
|
111 |
|
112 | /******************************************************************************
|
113 | *
|
114 | * Timer/Counter2 Overflow Interrupt Routine
|
115 | *
|
116 | * Purpose: Increment the real-time clock
|
117 | * The interrupt occurs once a second (running from the 32kHz crystal)
|
118 | *
|
119 | *******************************************************************************/
|
120 | #pragma vector = TIMER2_OVF_vect
|
121 | __interrupt void TIMER2_OVF_interrupt(void)
|
122 | {
|
123 | gPowerSaveTimer++;
|
124 | if (gPowerSaveTimer >= PowerSaveTimeout)
|
125 | {
|
126 | gPowerSaveTimer = 0;
|
127 | PowerSave = FALSE;
|
128 | }
|
129 | }
|