Forum: Mikrocontroller und Digitale Elektronik sleep modus wird durch can-befehl nur einmal ausgeführt


von Johannes (Gast)


Lesenswert?

Hi,
ich hatte hier Beitrag "sleep-modus fragen" schon 
einmal eine frage gestellt, da ich aber ein zusätzliches problem 
bekommen habe und ich das eh nachfragen wollte, habe ich ein neues Thema 
eröffnet

zunächst mein Code
1
...
2
unsigned char sleep = 0;
3
int main (void) {
4
...
5
...
6
while(1){
7
if(sleep==1){
8
}
9
Sleep();
10
sleep = 0;
11
}
12
...
13
...
14
return 0;
15
}
16
17
void __attribute__((interrupt, no_auto_psv)) _INT1Interrupt(void) {
18
    sleep = 1;
19
    IFS1bits.INT1IF = 0; // Clear INT1 interrupt flag
20
}
21
22
23
void __attribute__((interrupt, no_auto_psv)) _C2Interrupt(void) {
24
    if (C2INTFbits.RX0IF) {
25
    if(CAN2_Identifier == 0xFFF){ // sleep
26
        sleep = 1;
27
    }
28
    C2RX0CONbits.RXFUL = 0; // Clear the Buffer RXFUL to receive new messages
29
    C2INTFbits.RX0IF = 0; //If the Interrupt is due to Receive0 of CAN1 Clear the Interrupt
30
    }
31
    IFS2bits.C2IF = 0; //Clear interrupt flag
32
}


Also, entweder ich drücke eine Taste, oder eine Nachricht mit dem 
Identifier 0xFFF kommt herein, schicke ich meinen PIC (dspic30f6011a) 
schlafen.
durch einer anderen Nachricht, oder anderen Tastendruck wecke ich den 
wieder auf.
Nun zu meinem Problem.
Wenn ich die Taste erneut drücke, geht der pic wieder schlafen. Bei 
einer neuen NAchricht aber ncicht. Die Nachricht kommt herein und sleep 
wird gleich 1 gesetzt. Somit geht der Controller auch in die Abfrage, ob 
sleep=1 ist, führt den Befehl Sleep(); aber nicht erneut aus.
kurz gesagt, mit der Taste kann ich den pic so oft ich möchte schlafen 
legen, mit der can-nachricht aber nur einmal.
hat dazu jemand einen rat, wieso das so ist? im späteren Betrieb 
kommuniziere ich nur noch über can und komme an der Taste nicht mehr 
heran.

Johannes

von Chris L. (kingkernel)


Lesenswert?

Deklariere die Variable Sleep mal als volatile. Besser wäre hier eine 
der Typ bool, da der für Wahrheitszustände gedacht ist

Hast du mit dem Debugger mal geschaut, ob sleep beim zweiten durchlauf 
wirklich auf 1 gesetzt wird. Oder ob der Controller überhaupt in die 
if-Abfrage springt

: Bearbeitet durch User
von Irgendwer (Gast)


Lesenswert?

Johannes schrieb:
> unsigned char sleep = 0;

volatile bool sleep

von Johannes (Gast)


Lesenswert?

mit dem debugger habe ich das überprüft. er ist auch in die routine 
reingegangen. führt den Befehl jedoch nicht aus.
Wenn ich über CAN den befehl schicke sich schlafen zu legen, 
funktioniert dies genau einmal. beim zweiten mal wird der 
schlafen-befehl nicht mehr ausgeführt. dann wird der befehl auch auf 
tastendruck nicht mehr ausgeführt.


taste a -> schlafen
taste b -> aufwachen
taste a -> schlafen
taste b -> aufwachen
...
...
CAN-befehl -> schlafen
anderer CAN-befehl oder taste -> aufwachen
CAN-befehl -> nichts passiert
taste a -> ncihts passiert

von Johannes (Gast)


Lesenswert?

Es muss irgendetwas damit zu tun haben, dass ich den mit einer 
CAN-Nachricht wieder wecken möchte.
ich kann den mit einer CAN-Nachricht immer schlafen legen, solange ich 
den mit der taste wieder wecke. aber sobald ich den mit der einer 
can-nachricht wecke, funktioniert es nicht mehr.
der läuft beim wecken die routine durch und fängt dann hinter dem 
Sleep() wieder an.

bool funktioniert bei mir irgendwie nicht
'unable to resolve identifier bool'
aber habe es auf volatile umgestellt. gab aber keine verbesserung

von Chris L. (kingkernel)


Lesenswert?

Spring er denn beim zweiten CAN-Befehl in die Sleep-Routine? blockiert 
bei der CAN-Übertragung vielleicht schon was.
Entferne mal alles aus deinem Projekt, was nichts mit dem eigentlichen 
Problem zu tun hat. Dann müssten nur noch CAN und Sleep vorhanden sein 
und gehe dem Problem auf den Grund. Lass zusätzlich zum Aufruf von 
Sleep() auch mal eine LED toggeln.
Ich bin jetzt niht der PIC-Experte, aber das sind die schritte, um den 
Fehler einzugrenzen. Vielleicht gibt es auch ein generelles Problem mit 
dem Sleep. Hast du den entsprechenden Sleep-Modus auch richtig gesetzt?

[EDIT] Eben deinen neuen Post gelesen. Ergründe mal, was denn genau beim 
Aufwachen passiert. Stören sich die Interrupts vielleicht?

: Bearbeitet durch User
von Johannes (Gast)


Lesenswert?

Hatte vorher schon alles auskommentiert was nichts damit zu tun hat. 
auch das mit der LED habe ich gemacht. er geht definitiv darein. Wenn 
ich mit dem debugger dadurch gehe, bleibt er auch bei Sleep() hängen und 
geht erst weiter, wenn ich pause drücke und dann nächsten schritt mache. 
nur im normalen modus funktioniert es nicht.

Chris L. schrieb:
> Hast du den entsprechenden Sleep-Modus auch richtig gesetzt?

in der p30f6011a.h
1
#define Sleep()  {__asm__ volatile ("pwrsav #0");}
ich habe in meinem Code nichts weiteres dazu stehen, nur dass ich 
Sleep() aufrufe.

von Johannes (Gast)


Lesenswert?

habe es rausgefunden.
beim can muss ich noch das WAKIF-BIT löschen.
Wieso ich dieses bit nur löschen muss, wenn ich über can den sleep-modus 
verlassen möchte, ist mir allerdings noch unklar.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.