Powerdown Tiny26

Interrupthandling

  • 1
  • 2
  • Page 1 of 2
rbr50
 
Avatar
 
Subject:

Powerdown Tiny26

 · 
Posted: 30.09.2011 - 11:57  ·  #1
Hallo,

wahrscheinlich kann ich mal wieder nicht lesen...

Ich schicke einen Tiny26 mit
Code
CPUsleep(MCUCR or %00110000);

schlafen. Funktioniert auch. Aufwachen soll er durch einen 0-Pegel an INT0.
Das funktioniert leider nicht.

Vor der CPUSleep Anweisung kommt ein

Code
DisableInts;
GIFR:= GIFR and %10111111;            // Reset   INT0
GIMSK:= GIMSK or %01000000;         // Bit6 setzten, INT0 Enable
EnableInts;


In der Interruptroutine passiert fast nichts:

Code
Interrupt INT0;
begin
  GIMSK:= GIMSK and %10111111;         // Bit6 löschen, INT0 disable
  GIFR:= GIFR and %10111111;                  // reset   INT0
end;


Ich habe natürlich getestet, ob die Interruptroutine angespungen wird. Dazu habe ich das Sleep rausgenommen und in der ISR INTO eine LED blinken lassen. Also, die Routine wird angesprungen, daran kann es nicht liegen. Ich habe auch geschaut, ob im Sleep-Mode ein HIGH-Pegel am INT0 Pin liegt. Und ob der Pegel auf 0 geht bei Tastendruck. Auch das ist OK.

Warum wacht er nicht auf? Es tut mir leid, ich suche schon seit 8 Stunden, ich muss fragen.

Viele Grüße, Rolf
rbr50
 
Avatar
 
Subject:

Re: Powerdown Tiny26

 · 
Posted: 30.09.2011 - 17:58  ·  #2
Hallo,

endlose Versuche weiter habe ich das Problem etwas eingrenzen können.
Sicher liegt es an einem ganz blöden Denkfehler meinerseits.

Rufe ich testweise vor dem Mainloop das CPUSleep auf, fuktioniert der Sleep mit
anschließendem Aufwachen einwandfrei:

Code
{--------------------------------------------------------------}
{ Main Program }
{$IDATA}

begin
  InitPorts;
  EnableInts;
  SysLEDflashOn(0);
  SwitchPort1_Clear;
  InitPowerDown;
  CPUsleep(MCUCR or %00110000); //geht in den sleep und wacht bei INT0 auf
  loop                       // macht also nach INT0 hier weiter. Alles OK.
    if Inp_Raise1(0) then
      while Inp_Stable1(0)  do
        SendPioneerCMD(lauter);
        mDelay(25);
      endwhile;
      StopTimer1;
    endif;
    if Inp_Raise1(1) then
      while Inp_Stable1(1)  do
        SendPioneerCMD(leiser);
        mDelay(25);
      endwhile;
    endif;
    if Inp_Raise1(5) then
      SwitchPort1_Clear;
      SendSamsungCmd($1AE5 );  // return
    endif;
  endloop;


Setze ich das CPUSleep allerdings wie folgend ein, wacht er nicht wieder auf:

Code
  loop
     [...]
      if Inp_Raise1(5) then
        SwitchPort1_Clear;
        SendSamsungCmd($1AE5 );  // return
        InitPowerDown;
        CPUsleep(MCUCR or %00110000);  //schläft, aber wacht nicht wieder auf
      endif;
  endloop;


Also liegt das Problem daran, wo ich das Sleep aufrufe. Nur, ich sehe es leider nicht.
Kann mir bitte jemand die Augen öffnen?

Danke und viele Grüße, Rolf
rh
Administrator
Avatar
Gender:
Location: Germany
Age: 24
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: Powerdown Tiny26

 · 
Posted: 30.09.2011 - 21:25  ·  #3
Hallo Rolf,

liegt das Switchport auf dem gleichen Port wie INT0?
Vielleicht hilft hier das Warten bis die auslösende Taste inaktiv wird bevor das Sleep ausgeführt wird.

rolf
Gunter
Administrator
Avatar
Gender:
Location: Frankfurt Main / Germany
Posts: 1697
Registered: 02 / 2003
Subject:

Re: Powerdown Tiny26

 · 
Posted: 30.09.2011 - 21:53  ·  #4
Hallo,

ich habe einen anderen Verdacht:
wenn ich es richtig sehe, wird das "SwitchPort1_Clear;" erst im nächsten
Systick wirksam.
Wegen der "loop" kommt aber sofort wieder eine "CPUsleep" bevor der
nächste Systick drankommt und Zeit hat, den SwitchPort rückzusetzen.
Somit ist dann auch noch "Inp_Raise1(0)" noch aktiv.

Gruß
Gunter
rbr50
 
Avatar
 
Subject:

Re: Powerdown Tiny26

 · 
Posted: 01.10.2011 - 08:20  ·  #5
Hallo Rolf,


Quote by rh

liegt das Switchport auf dem gleichen Port wie INT0?


nein, Switchport ist PortA, INT0 liegt auf PortB.

Rolf
rbr50
 
Avatar
 
Subject:

Re: Powerdown Tiny26

 · 
Posted: 01.10.2011 - 10:09  ·  #6
Hallo Gunter,


Quote by Gunter

ich habe einen anderen Verdacht:
wenn ich es richtig sehe, wird das "SwitchPort1_Clear;" erst im nächsten
Systick wirksam.
Wegen der "loop" kommt aber sofort wieder eine "CPUsleep" bevor der
nächste Systick drankommt und Zeit hat, den SwitchPort rückzusetzen.
Somit ist dann auch noch "Inp_Raise1(0)" noch aktiv.


ich glaube auch, das Problem liegt an der loop-Schleife.
Folgender Code ist ja fast so wie das SleepTest.pas Beispiel.
Die Routinen InitPowerdown und INT0 sind dem Beispiel entnommen und
nur auf den Tiny26 angepasst (Code der Routinen siehe 1. Post)
Nur, dass hier eine LED getoggelt wird, statt etwas auf die Serielle zu schreiben.
So sollte also dieser Code korrekt laufen. Tut er aber nicht.

Der Effekt ist, dass die CPU nur genau 1x aufwacht.
LED wird getoggelt, CPU schläft wieder ein, aber wacht danach nie wieder auf.


Code
  loop
    InitPowerDown;
    CPUsleep(MCUCR or %00110000);  //schläft ein
    if LED then   //wird nach INTO nur 1x ausgeführt!
      excl(LED);  //geprüft auch mit Oszi am Quarz
    else
      incl(LED);
    endif;
  endloop;


Teste ich das im Simulator, wird alles korrekt ausgeführt.
Aber im echten Controller eben nur genau 1x.

Was mache ich falsch?

Viele Grüße,

Rolf
rbr50
 
Avatar
 
Subject:

Re: Powerdown Tiny26

 · 
Posted: 01.10.2011 - 10:43  ·  #7
Hallo,

jetzt habe ich mal alles Überflüssige aus dem Prog. entfernt., nur noch die Sleep-Funktion.
Es bleibt dabei, die CPU wacht nur 1x auf und togelt die LED, danach schläft sie zwar, aber wacht nie wieder auf. Im Simulator läuft alles richtig.

Mache ich was falsch?

Viele Grüße, Rolf


Code
program Fernbedien;

{$NOSHADOW}
{ $WG}                     {global Warnings off}

Device = tiny26, VCC = 5;
{ $BOOTRST $00C00}         {Reset Jump to $00C00}

Define_Fuses
//  Override_Fuses;
  NoteBook       = A;
  COMport        = USB;
  LockBits0      = [];
  FuseBits0      = [];
  FuseBits1      = [];

Import SysTick;

Define
  ProcClock      = 4000000;       {Hertz}
  SysTick        = 10;             {msec}
  StackSize      = $0034, iData;
  FrameSize      = $0034, iData;

Implementation

{$IDATA}

{--------------------------------------------------------------}
{ Type Declarations }
type

{--------------------------------------------------------------}
{ Const Declarations }
{--------------------------------------------------------------}
{ Var Declarations }
{$IDATA}

var
  LED[@PORTB, 3] : bit;

{--------------------------------------------------------------}

procedure InitPorts;
begin
  PortA:= %11111111; //Pullups von Tasterport an
  DDRA:=  %00000000; // alles als Eingang

  DDRB:=  %00001010;  // PB1, OCR1A und PB3, LED als Ausgang
  PortB:= %01001000;  // LED is LOW-aktiv, also ausschalten mit 1   
                                 // Pullup PB6, INT0 an
  //TCCR1A
  //COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B PWM1A PWM1B
  //  0       1      0      0     0      0    0     0

  OCR1c:= 51;
end InitPorts;
{--------------------------------------------------------------}
procedure InitPowerDown;
begin
  DisableInts;
  GIFR:= GIFR and %10111111;                  // reset   INT0
  GIMSK:= GIMSK or %01000000;         // Bit6 setzten, INT0 Enable
  EnableInts;
end;
{--------------------------------------------------------------}
Interrupt INT0;
begin
  GIMSK:= GIMSK and %10111111;         // Bit6 löschen, INT0 disable
  GIFR:= GIFR and %10111111;                  // reset   INT0
end;
{--------------------------------------------------------------}
{ Main Program }
{$IDATA}

begin
  InitPorts;
  EnableInts;

  loop
    InitPowerDown;
    CPUsleep(MCUCR or %00110000);
    if LED then
      excl(LED);
    else
      incl(LED);
    endif;
  endloop;

end Fernbedien.

rh
Administrator
Avatar
Gender:
Location: Germany
Age: 24
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: Powerdown Tiny26

 · 
Posted: 01.10.2011 - 15:24  ·  #8
Hallo Rolf,

ein Problem scheint zu sein (würde ich nie so machen) dass der INT0 Interrupt mode static low level ist. Ich nehme immer falling edge.
CPUsleep(%00110010);

rolf
  • 1
  • 2
  • Page 1 of 2
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   132   146 · Page-Gen-Time: 0.051389s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI