Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Waking up an atmega 128 from power save

Status
Not open for further replies.

fateme91

Member level 2
Joined
Nov 18, 2014
Messages
48
Helped
2
Reputation
4
Reaction score
2
Trophy points
18
Location
Iran,Mashad
Activity points
349
Hi dears
I need to wakeup an atmega128 from sleep. for example i turned on a LED with overflow interrupt of Timer0. then it goes to power save. How can i take it out ??

Please help me.....

- - - Updated - - -

I have added an interrupt 1 on pin6. it does not wake micro up. what else should i do ?
 

Disable sleep mode MCUCR &= ~(1<<SE); by resting the SE bit and interrupt should wake up micro controller.You didnt tell what kind of interrupt you have at pin 6 so hard to answer with out code or and other useful information.


**broken link removed**

And one more thing I advice you to read datasheet in details in other of your post most of information you get in there.
 
It is code of interrupt overflow of Timer0:


Code dot - [expand]
1
2
3
4
5
6
7
8
9
10
11
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
PORTD.0=1 ;
delay_ms(100);
PORTD.0=0 ;
delay_ms(100);
 
 
    MCUCR=0b00111000;
    #asm("sleep");
}



I added
MCUCR=0b00011000;
in the void main before while(1).
Bit SE is the 6th bit in the MCUCR Reg. but it did not work too.

What should i do?

TNKS




Disable sleep mode MCUCR &= ~(1<<SE); by resting the SE bit and interrupt should wake up micro controller.You didnt tell what kind of interrupt you have at pin 6 so hard to answer with out code or and other useful information.


**broken link removed**

And one more thing I advice you to read datasheet in details in other of your post most of information you get in there.
 
Last edited by a moderator:

If you look at the example in the link which i posted in earlier post then your code should like this


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
PORTD.0=1 ;
delay_ms(100);
PORTD.0=0 ;
delay_ms(100);
 
 
}
 
void main()
{
 
  timer_inital();  // your timer 0 initialize function here
     sei();   //set interrupt 
 
 MCUCR &= ~((1<<SM1)|(1<<SM0)|(1<<SM2));  //for idel sleep mode
 
while(1)
{
 
   MCUCR=0b00111000;     //set the SE bit
 
  #asm("sleep");
 
MCUCR=0b00011000;     //reseting the SE bit
 
 
 
}
 
}



but what is your interrupt for waking up cpu in my example code interrupt occurred when timer overflows every 250ms and controller wakes up with this interrupt trigger.
 
It is my full code :


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
Chip type               : ATmega128
Program type            : Application
AVR Core Clock frequency: 16.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 1024
*****************************************************/
 
#include <mega128.h>
#include <delay.h>
#include <sleep.h>
 
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
MCUCR =0;
 
PORTD.0=1 ;
delay_ms(1000);
PORTD.0=0 ;
 
}
 
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
MCUCR=0;
PORTD.0=1 ;
delay_ms(100);
PORTD.0=0 ;
 
    
}
 
// Declare your global variables here
 
void main(void)
{
// Declare your local variables here
 
 
PORTA=0x00;
DDRA=0x00;
 
PORTB=0x00;
DDRB=0x00;
 
PORTC=0x00;
DDRC=0x00;
 
PORTD=0x00;
DDRD=0x01;
 
PORTE=0x00;
DDRE=0x00;
 
PORTF=0x00;
DDRF=0x00;
 
DDRG=0x00;
 
// Timer/Counter 0 initialization
ASSR=0x00;
TCCR0=0x05;
TCNT0=0x00;
OCR0=0x00;
 
// Timer/Counter 1 initialization
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;
 
// Timer/Counter 2 initialization
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
 
// Timer/Counter 3 initialization
TCCR3A=0x00;
TCCR3B=0x00;
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;
 
// External Interrupt(s) initialization
// INT0: Off
// INT1: On
// INT1 Mode: Falling Edge
EICRA=0x08;
EICRB=0x00;
EIMSK=0x02;
EIFR=0x02;
 
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
ETIMSK=0x00;
 
        PORTD.0=1 ;
        delay_ms(2000);
        PORTD.0=0 ;
        delay_ms(2000);        
 
 
// Global enable interrupts
#asm("sei")
 
 
while (1)
      {
 
       ASSR=0b00001000;
       MCUCR=0b00111000;// Enable sleep mode
 
       #asm("sleep");
        
      }
}




At first void main operates,then sei so timer 0 ovf , then while (1 ) micro sleeps , then if press button EXT INT operates.
Now it works correctly if i press button i mean if ext INT turns on, My problem is that the timer 0 ovf works just once till i press ext int, I want timer0 ovf works continuously without ext INT as it is written in the datasheet.

Tnks for ur help Now what should i do ?






If you look at the example in the link which i posted in earlier post then your code should like this


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
PORTD.0=1 ;
delay_ms(100);
PORTD.0=0 ;
delay_ms(100);
 
 
}
 
void main()
{
 
  timer_inital();  // your timer 0 initialize function here
     sei();   //set interrupt 
 
 MCUCR &= ~((1<<SM1)|(1<<SM0)|(1<<SM2));  //for idel sleep mode
 
while(1)
{
 
   MCUCR=0b00111000;     //set the SE bit
 
  #asm("sleep");
 
MCUCR=0b00011000;     //reseting the SE bit
 
 
 
}
 
}




but what is your interrupt for waking up cpu in my example code interrupt occurred when timer overflows every 250ms and controller wakes up with this interrupt trigger.

- - - Updated - - -

My crystall is 32768 Hz between pin 18 ,19 . 32768/128 = 256 . it runes each one second.
 
Last edited by a moderator:

you need to set the pre scaler for timer


Code C - [expand]
1
2
// start timer0 with /1024 prescaler
    TCCR0 = (1<<CS02) | (1<<CS00);



for debugging try to make overflow timer in ms seconds first.

Please use code tag or c syntax when you post code so its easy to read your code and answer fast.
 
Last edited:

I made changes but it steel needs ext int.....



you need to set the pre scaler for timer


Code C - [expand]
1
2
// start timer0 with /1024 prescaler
    TCCR0 = (1<<CS02) | (1<<CS00);



for debugging try to make overflow timer in ms seconds first.

Please use code tag or c syntax when you post code so its easy to read your code and answer fast.
 


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Timer 0 overflow interrupt service routine            //your ISR
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
MCUCR=0;
PORTD.0=1 ;
delay_ms(100);
PORTD.0=0 ;
 
 
}
 
// Timer 0 overflow interrupt service routine            //modified ISR
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
MCUCR=0;
PORTD.0=1 ;
delay_ms(2000);
PORTD.0=0 ;
 
 
}



Few things you are controlling the same output with two interrupt and as i posted above there is time delay difference in your two ISR and 100ms less to identify the ISR.

If you use without pre scale then your cpu clock will be your timer clock so try to run the timer slower as I said try to set some time value for overflow timer

One more thing clear MCUCR=0; in while one.And you can use timer in CTC mode.

**broken link removed**

look at above example its not for atmega 128 but i think you can convert it.
 
Last edited:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.3 Standard
Automatic Program Generator
© Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l.
[url]http://www.hpinfotech.com[/url]
 
Project : 
Version : 
Date    : 12/30/2014
Author  : PerTic@n
Company : If You Like This Software,Buy It
Comments: 
 
 
Chip type               : ATmega128
Program type            : Application
AVR Core Clock frequency: 16.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 1024
*****************************************************/
 
#include <mega128.h>
#include <delay.h>
#include <sleep.h>
#include <stdint.h>
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
MCUCR =0;
 
PORTD.0=1 ;
delay_ms(100);
PORTD.0=0 ;
delay_ms(100);
 
PORTD.0=1 ;
delay_ms(100);
PORTD.0=0 ;
delay_ms(100);
 
PORTD.0=1 ;
delay_ms(100);
PORTD.0=0 ;
delay_ms(100);
 
PORTD.0=1 ;
delay_ms(100);
PORTD.0=0 ;
delay_ms(100);
 
PORTD.0=1 ;
delay_ms(100);
PORTD.0=0 ;
delay_ms(100);
 
}
 
 
// Timer 0 overflow interrupt service routine            //modified ISR
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
MCUCR=0;
PORTD.0=1 ;
delay_ms(50);
PORTD.0=0 ;
delay_ms(50);
 
PORTD.0=1 ;
delay_ms(50);
PORTD.0=0 ;
delay_ms(50);
 
 
}
// Declare your global variables here
 
void main(void)
{
// Declare your local variables here
 
 
PORTA=0x00;
DDRA=0x00;
 
PORTB=0x00;
DDRB=0x00;
 
PORTC=0x00;
DDRC=0x00;
 
PORTD=0x00;
DDRD=0x01;
 
PORTE=0x00;
DDRE=0x00;
 
PORTF=0x00;
DDRF=0x00;
 
DDRG=0x00;
 
// Timer/Counter 0 initialization
ASSR=0x00;
TCCR0=0x05;
TCNT0=0x00;
OCR0=0x00;
 
// External Interrupt(s) initialization
// INT0: Off
// INT1: On
// INT1 Mode: Falling Edge
EICRA=0x08;
EICRB=0x00;
EIMSK=0x02;
EIFR=0x02;
 
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
ETIMSK=0x00;
 
        PORTD.0=1 ;
        delay_ms(2000);
        PORTD.0=0 ;
        delay_ms(2000);        
 
 
// Global enable interrupts
#asm("sei")
 
 
while (1)
      {
       
       ASSR=0b00001000;
       MCUCR=0b00111000;// Enable sleep mode
       #asm("sleep");
       
      }
}




My goal is reached. But now i have another problem. When i turn on the micro, it does Timer0 ovf int operation just once . when i press button the EXT int happens and works correctly. Although when i pree reset button the operation works completely correct.
My question is why at the first time the micro does timer0 ovf int just once and needs ext int.
Maybe the fuse bits have problem .. i don't know...

Answer Me PLZ...
Best wishes.



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Timer 0 overflow interrupt service routine            //your ISR
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
MCUCR=0;
PORTD.0=1 ;
delay_ms(100);
PORTD.0=0 ;
 
 
}
 
// Timer 0 overflow interrupt service routine            //modified ISR
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
MCUCR=0;
PORTD.0=1 ;
delay_ms(2000);
PORTD.0=0 ;
 
 
}



Few things you are controlling the same output with two interrupt and as i posted above there is time delay difference in your two ISR and 100ms less to identify the ISR.

If you use without pre scale then your cpu clock will be your timer clock so try to run the timer slower as I said try to set some time value for overflow timer

One more thing clear MCUCR=0; in while one.And you can use timer in CTC mode.

**broken link removed**

look at above example its not for atmega 128 but i think you can convert it.
 

My goal is reached

I think your goal is to make wake up cpu every time timer 0 overflow or ext INT trigger.So I think you set power down sleep mode as i told you to read data sheet page number 45 read the paragraph about power down sleep mode and other sleep mode.only external INT or RESET make CPU wake up.
 

Attachments

  • sleep mode - doc2467.pdf
    30.6 KB · Views: 142
Last edited:

I know i bothers u so much!
No No my mode is power save. MCUCR=0b00111000;// i read the datasheet. power save wakes up with timer0,Ext int,...
Now the problem is why timer0 does not work correctly at the first time? i think timer works but the overflow does not..


.So I think you set power down sleep mode as i told you to read data sheet page number 45 read the paragraph about power down sleep mode and other sleep mode.only external INT or RESET make CPU wake up.
 

I know i bothers u so much!
No No my mode is power save. MCUCR=0b00111000;// i read the datasheet. power save wakes up with timer0,Ext int,...
Now the problem is why timer0 does not work correctly at the first time? i think timer works but the overflow does not..

What is your timer clock settings it must not be asynchronous.
 

Attachments

  • asyncronous mode doc2467.pdf
    29.3 KB · Views: 141
Last edited:

DSC_0728.jpgDSC_0728.jpgThe timer0 clock is from 32768 Hz crystall of Tosc1,2 on pin 18,19.
The value is distributed to 128 that equals 32768/128 = 256 . it runes each one second.

bit AS0=1 ; look there is no problem with waking up when resets. now the problem is that at the begining of operation when i connect DC power action is not complete. just void main happens and micro sleeps .but it does not wake up (or read timer0 ovf) till i reset or disconnect the power and connect immediately.
 
Last edited:

I put a delay_ms (130) after MCUCR in while (1) and the problem solved.
thank you...
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top