 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
jvolk Član



Pridružen-a: Ned 05 Mar 2006 1:14 Prispevkov: 737 Aktiv.: 3.14 Kraj: okolica Divače
|
Objavljeno: Sre Jul 16, 2008 3:46 pm Naslov sporočila: [rešeno]ATmega8 in sleep |
|
|
Z ATmega8 delam binarno uro. Sekunde prištevam v Timer2 overflow prekinitvi. Ker se ura ne rabi izpisovat stalno, želim da bi mikrokontroler vsako sekundo prištel sekundo in šel v sleep mode. Timer2 prekinitev naj bi mikrokontroler zbudila, vendar ga ne. Button1 naj bi omogočil prikaz ure za naslednjih 10 sekund. To tudi deluje, dokler mikrokontroler ne gre v sleep mode. Ima kdo kako izkušnjo s tem?
Še koda:
Koda: |
#include <mega8.h>
#include <delay.h>
#define B1 PORTB.2
#define B2 PORTB.1
#define B4 PORTB.0
#define B8 PORTD.7
#define B16 PORTD.5
#define B32 PORTD.4
#define HOURS PORTD.2
#define MINUTES PORTD.3
#define SECONDS PORTD.6
#define BUTTON1 PIND.1
#define BUTTON2 PIND.0
char sec=0;
char min=0;
char hrs=0;
char cntdown=10;
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
// Place your code here
sec++;
if (cntdown>0) {
cntdown--;
}
if (sec > 59){
min++;
sec = 0;
if (min > 59){
hrs++;
min = 0;
if (hrs > 23){
hrs = 0;
}
}
}
if (!BUTTON1) {
cntdown=10;
}
if (cntdown==0){
B1 = 1;
B2 = 1;
B4 = 1;
B8 = 1;
B16 = 1;
B32 = 1;
SECONDS = 0;
MINUTES = 0;
HOURS = 0;
MCUCR = 0x38; //entering sleeping mode: power save mode
MCUCR |= 0x80;
#asm("sleep")
#asm("nop")
}
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=Out
// State7=T State6=T State5=T State4=T State3=T State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0x07;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=In Func0=In
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=T State0=T
PORTD=0x00;
DDRD=0xFC;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
ASSR=0x08;
TCCR2=0x05;
TCNT2=0x00;
OCR2=0x00;
TIMSK = 0x41; //timer interrupt sources
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// Global enable interrupts
B1 = 1;
B2 = 1;
B4 = 1;
B8 = 1;
B16 = 1;
B32 = 1;
SECONDS = 0;
MINUTES = 0;
HOURS = 0;
#asm("sei")
while (1){
if (cntdown) {
SECONDS=1;
if (sec & 0x01) {B1=0;} else {B1=1;};
if (sec & 0x02) {B2=0;} else {B2=1;};
if (sec & 0x04) {B4=0;} else {B4=1;};
if (sec & 0x08) {B8=0;} else {B8=1;};
if (sec & 0x10) {B16=0;} else {B16=1;};
if (sec & 0x20) {B32=0;} else {B32=1;};
delay_ms(10);
SECONDS=0;
MINUTES=1;
if (min & 0x01) {B1=0;} else {B1=1;};
if (min & 0x02) {B2=0;} else {B2=1;};
if (min & 0x04) {B4=0;} else {B4=1;};
if (min & 0x08) {B8=0;} else {B8=1;};
if (min & 0x10) {B16=0;} else {B16=1;};
if (min & 0x20) {B32=0;} else {B32=1;};
delay_ms(10);
MINUTES=0;
HOURS=1;
if (hrs & 0x01) {B1=0;} else {B1=1;};
if (hrs & 0x02) {B2=0;} else {B2=1;};
if (hrs & 0x04) {B4=0;} else {B4=1;};
if (hrs & 0x08) {B8=0;} else {B8=1;};
if (hrs & 0x10) {B16=0;} else {B16=1;};
if (hrs & 0x20) {B32=0;} else {B32=1;};
delay_ms(10);
HOURS=0;
};
};
}
|
Nazadnje urejal/a jvolk Čet Jul 17, 2008 9:49 am; skupaj popravljeno 1 krat |
|
Nazaj na vrh |
|
 |
jurem Član


Pridružen-a: Tor 02 Dec 2003 15:53 Prispevkov: 408 Aktiv.: 1.72 Kraj: Ljubljana
|
Objavljeno: Sre Jul 16, 2008 9:53 pm Naslov sporočila: |
|
|
Jan,
z Mega168 sem naredil uro, ki troši 15uA... Timer2 zbudi uC, vendar to deluje samo pri Mega168, pri Mega8 ne bo šlo...
Lp
Jure |
|
Nazaj na vrh |
|
 |
igor_k Član

Pridružen-a: Pon 19 Jul 2004 11:44 Prispevkov: 1011 Aktiv.: 4.27 Kraj: Rače
|
Objavljeno: Sre Jul 16, 2008 10:28 pm Naslov sporočila: |
|
|
V spanje ga daj v glavni zanki in ne v prekinitveni rutini! |
|
Nazaj na vrh |
|
 |
Silvo Moderator


 
Pridružen-a: Pon 24 Feb 2003 17:09 Prispevkov: 14673 Aktiv.: 61.93 Kraj: Koroška-okolica Dravograda
|
Objavljeno: Sre Jul 16, 2008 10:40 pm Naslov sporočila: |
|
|
Takole na hitro sem pogledal datasheet (z Atmega8 nisem nikoli delal) Koliko sem razumel ga je potrebno dati v "Power save" mode (ne v Power Down). MCUCR biti SM2-SM0 110 Takrat Tmr2 teče. Zbudi ga owerflow. Vključen mora biti še interrupt Timer2 (TIMSK) ter seveda generalni interrupt (SREG) _________________ lp
Silvo |
|
Nazaj na vrh |
|
 |
spy Član


Pridružen-a: Sre 06 Sep 2006 20:43 Prispevkov: 403 Aktiv.: 1.76 Kraj: Tržič
|
Objavljeno: Sre Jul 16, 2008 11:37 pm Naslov sporočila: |
|
|
Kot ti je napisal igor_k: v spanje pojdi izven prekinitvene rutine. Ob vsaki prekinitvi se ti global interrupt enable bit v SREG briše in postavi spet ob izhodu iz nje. V tvojem primeru greš v spanje preden rutina sprosti interrupt bit.
Če nujno želiš notranje delovanje timerja, potem ti ne preostane drugega kot "idle mode". Če lahko del delovanja prestaviš ven, greš lahko v "power-down", kjer ga na vsake toliko časa zbudiš z INT, ali uporabiš "power-save", kjer imaš zunanji neodvisni oscilator.
Jaz sem reševal podoben problem z zunanjim RTC-jem (npr. DS1307) in I2C povezavo. RTC ti že sam šteje čas (prihranek resourcev procesorja), za delovanje rabi nA, mikrokontroler pa gre lahko v "power-down" mode, ko troši uA. Zbudi ga interrupt RTC-ja na recimo 1 sek, da procesor podela svoje. Pa tudi ura ima "backup" za primer izpada elektrike. |
|
Nazaj na vrh |
|
 |
jvolk Član



Pridružen-a: Ned 05 Mar 2006 1:14 Prispevkov: 737 Aktiv.: 3.14 Kraj: okolica Divače
|
Objavljeno: Čet Jul 17, 2008 9:48 am Naslov sporočila: |
|
|
No hvala vsem. Sem prestavil tisti blok kode za sleep v glavno zanko z malo modifikacije. Stvar deluje tako kot more. Porabi pa 2mA.
Silvo: Saj sem ga stavil v PowerSave mode. 0x3 = 0b011, kar ustreza PowerSave. Verjetno si obrnil bite okoli.  |
|
Nazaj na vrh |
|
 |
jvolk Član



Pridružen-a: Ned 05 Mar 2006 1:14 Prispevkov: 737 Aktiv.: 3.14 Kraj: okolica Divače
|
Objavljeno: Čet Jul 17, 2008 10:06 am Naslov sporočila: |
|
|
Eko še en update.. stvar sem spravil na 2x AAA baterijo. Vmes imam še L6920D (step up iz 0.6-5 V na 5V). V PowerSave stvar porabi 100 A. Če bo koga zanimal step up, je dosegljiv na farnellu, cca 2 eur. (So me pa presenetili, ko so paket dostavili v 27 urah ) |
|
Nazaj na vrh |
|
 |
dkone Član

Pridružen-a: Sre 07 Mar 2007 18:53 Prispevkov: 2116 Aktiv.: 9.51 Kraj: Krško
|
Objavljeno: Ned Sep 20, 2009 12:20 pm Naslov sporočila: |
|
|
Pozdravljeni!
Zanima me,če je kdo naredil isti primer,samo da je uporabil Bascom? Naredil bi tako,da se po določenem času procesor preide v power down,zbudim ga pa z tipko. gledal sem power save ukaz,pa ne funkcijonira najbolje,v sleep gre,zbuditi ga pa ne znam. Tisti določen čas bo pa štel timer.(naprimer 2min) _________________ Denis |
|
Nazaj na vrh |
|
 |
dkone Član

Pridružen-a: Sre 07 Mar 2007 18:53 Prispevkov: 2116 Aktiv.: 9.51 Kraj: Krško
|
Objavljeno: Ned Sep 20, 2009 2:28 pm Naslov sporočila: |
|
|
Evo,nekaj sem se igral in mi je nekako ratalo to kar sem si zamislil. Vse je še tako po kavbojsk napisano
V helpu od IDLE,sem prebral,da se ga zbuditi tudi z ADC-je. Kdo ve kako? Ker INT0 in INT1(zunanja prekinitvena priključka),bom uporabil za enkoder,zato bi mi prav prišel drug način "wakeup-a".
Koda: |
Config Pind.6 = Output
Config Int0 = Low Level
'nastavitev parametrov
On Int0 Tipka
Enable Interrupts
Enable Int0
Config Timer1 = Timer , Prescale = 1024 'at 4 MHz it gives an overflow at 4000000 / (1024*65536)= 16 sec
Enable Timer1
Enable Interrupts
On Timer1 Prekinitev_timer
Dim Spanje As Byte
Spanje = 0
Declare Sub Spanje
Cls
'glavni
Do
Set Portd.6
Wait 1
Reset Portd.6
Cls
Locate 1 , 1
Lcd "delam"
Call Spanje
Loop
Tipka:
Cls
Spanje = 0
Start Timer1
Lcd "zbudi se"
Wait 1
Return
Prekinitev_timer:
Cls
Locate 1 , 1
Lcd "in isr"
Spanje = 1
Stop Timer1
'idle can not be used into the ISR !!!
Return
'rutina spanje
Spanje:
If Spanje = 1 Then
Cls
Lcd "spim"
Powersave
End If
Return
End
|
P.S: Ali je bolje novo temo odpreti? _________________ Denis |
|
Nazaj na vrh |
|
 |
LEDuser Član


Pridružen-a: Pon 31 Mar 2008 12:06 Prispevkov: 1104 Aktiv.: 5.27 Kraj: Ljubljana
|
Objavljeno: Ned Okt 03, 2010 2:14 pm Naslov sporočila: |
|
|
Imam problem z mego8 v bascomu! Ko spravim mego v powerdown, se mi noče več zbuditi, v programu uporabljam INT0 in INT1. Edino kar prebudi m8 je reset.
Mogoče kdo ve kaj bi bil lahko problem?
Spodaj testni program... ki ne deluje
Koda: |
...
Config Int0 = Falling
On Int0 Toffon
Config Int1 = Falling
On Int1 Tonon
Enable Int0
Enable Int1
Enable Interrupts
....
'************
Tonon:
Incr C
Shdn = 1
Print "ON"
Return
'************
Toffon:
Shdn = 0
Print "OFF"
Return
|
_________________ Razsvetljujemo od leta 1920! |
|
Nazaj na vrh |
|
 |
LEDuser Član


Pridružen-a: Pon 31 Mar 2008 12:06 Prispevkov: 1104 Aktiv.: 5.27 Kraj: Ljubljana
|
Objavljeno: Ned Okt 03, 2010 2:35 pm Naslov sporočila: |
|
|
Si bom sam odgovoril sem na srečo našel rešitev...
Citiram: |
This
will set the external interrupt INT0 to trigger on a LOW level. When using “Powerdown”
mode the AVR can only be woken up by LOW LEVEL trigger |
V nekem datašitu sem prebral zgoraj napisano... to pa pomeni, da tisti moj uporabljeni "Config INT0 = Falling" ni mogoč! No sedaj mi pokvari program... mogoče celo dizajn.
Sedaj pa iščem rešitev kako bi kljub interruptu na low level interupt rutino uporabil samo enkrat (kot falling)? _________________ Razsvetljujemo od leta 1920! |
|
Nazaj na vrh |
|
 |
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 494 dni
Powered by phpBB © 2001, 2005 phpBB Group
|