Forum: Mikrocontroller und Digitale Elektronik MSP430F149 Sleep Mode


von Mike (Gast)


Lesenswert?

Hallo zusammen

Ich möchte folgendes bewerkstelligen.

Mein MSP430F149 läuft über ein separates Netzteil. Ich habe eine 5 Volt
speisung für das LCD und eine 3,3Volt Speisung, welche für den MSP ist.
Wird nun der Netzschalter gedrückt und das Netzteil abgeschaltet, läuft
der MSP über eine Back Up Batterie weiter. Um nun den minimalen Strom
zu beziehen, will ich den MSP in den LowPowerMode schalten. Dies soll
über einen Spannungsteiler der 5Voltleitung auf einen Pin des MSP
geschehen. Dies heisst, dass wenn das Netzteil läuft, habe ich an
diesem Pin ein High und sobald das Netzteil abgeschalten wird, habe ich
an dem besagten Pin ein low.
Der MSP muss nun also mithilfe eines Interrupts oder der gleichen
merken, dass er bei einem low am Pin in den LowPowerMode muss und
sobald die Spannung wieder high ist wieder voll aktiv sein soll.
Hat jemand codebeispiele in c oder weiss einen guten Link?? oder habt
Ihr noch andere Ideen. Bitte helft mir!!!!!!!


Gruss Mike

von Sebastian (Gast)


Lesenswert?

Hi,

Wenn du hardwaremäßig schon so weit bist, dass tatsächlich high an
einem beliebigen IO-Pin anliegt, wenn das Netzteil da ist und low, wenn
nicht, dann sollte das einfach so gehen:

if (!(P6IN & 0x40))  // musst du natürlich auf deinen Pin anpassen
{
  _BIS_SR(LPM0_bits + GIE);   // ab in den LPM0 mit Interrupts
}

That's it. Wenn der MSP430 jetzt was zu tun bekommt, wacht er auf,
merkt aber direkt, dass am Pin ja immer noch low anliegt und geht
wieder schlafen. Erst, wenn am Pin wieder high anliegt, wird er nicht
mehr in den LMP0 gezwungen. Netter Nebeneffekt: So bleibt er wirklich
so lange schlafen, bis es was zu tun gibt, egal, ob ein Netzteil
dranhängt oder nicht. Strom kostet ja schließlich Geld. ;-)

Bessere Lösungen fallen mir auf Anhieb auch keine ein.

Grüße, Sebastian

von Mike (Gast)


Lesenswert?

Danke für deinen Tip. Kannst du mir den Ausdruck in der Klammer
(!(P6IN & 0x40))  noch ausschreiben, habe immer mühe mit diesen
kurzschreibweisen. Danke
brauche ich für den Interrupt den kein #pragma oder so was. Ich habe es
eben so gelernt.


gruss mike

von Sebastian (Gast)


Lesenswert?

Hi,

if (!(P6IN & 0x40)) bedeutet nix anderes als if ((P6IN & 0x40) == 0),
also die Prüfung, ob der Pin low ist. Wenn deine Logik anders herum
wäre, musst du natürlich das Ausrufezeichen weglassen oder auf '1'
prüfen, nicht auf '0'.

Das #pragma kommt ja vor den Interrupt-Handler selbst. Den muss es
natürlich noch irgendwo anders geben. Dazu bräuchte ich aber mehr
Infos. Was machst du denn überhaupt? Bzw. wann genau sollte der MSP430
wieder aufwachen? Ein USART-Interrupt geht anders als ein
A/D-Wandler-Interrupt ...

Grüße, Sebastian

von Mike (Gast)


Angehängte Dateien:

Lesenswert?

Danke, dass du dir einwenig zeit für mich nimmst.
Ich bin an meiner Diplomarbeit als Elektronik Techniker TS.
Dort kann man über eine Matrix Tastatur einen Drink wählen, welche auf
einem LCD angezeigt werden. Die entsprechende Mechanik mischt dan den
gewählten Cocktail. Ich habe eben das Problem, dass ich den Füllstand
der Flaschen kontrollieren will. Ich initialisiere eine static Variabel
mit z.Bsp. dem Wert 75 für jede der 8 Flaschen. Dies soll heissen,dass
die volle Flasche 75cl hat. Wird nun z.Bsp. ein Vodka Orange gewählt,
soll von der Vodkaflasche 4cl abgezogen werden und von der
Orangensaftflasche 12cl. ist nun ein minimum der Flaschen erreicht,
kommt eine Meldung auf dem Display um die Flasche zu wechseln. Das
Problem ist nun, dass der Wert der Flaschen beim Powerdown verloren
geht, da diese Variablen im RAM gespeichert werden. Darum habe ich mir
überlegt, den MSP mit einer Batterie zu stützen, wenn das Netzteil bei
nichtgebrauch mittels des Netzschalters abgeschalten wird.
Sagen wir also, der Drink ist fertig und die Mechanik ist wieder in der
Startposition. Auf dem Display wird nun wieder nach einem Neuen Drink
gefragt. Das Programm bleibt solange in dieser Routine, bis eine Taste
gedrückt wird. Wenn ich nun abschalte (Netzschalter), soll der MSP über
den besagten Pin merken, dass er in den LowPowerMode gehen soll. Wird
das Netzteil wieder eingeschalten, soll er wieder an diesem Pin merken,
dass er wieder aktiv sein soll.
Brauchst du noch mehr infos? Im Anhang habe ich dir noch eine CAD
Zeichung angehängt, damit du eine Ahnung hast, wie die Maschine mal
aussehen soll.

Gruss MIke

von OldBug (Gast)


Lesenswert?

Hallo zusammen!

>Ein USART-Interrupt geht anders als ein A/D-Wandler-Interrupt ...

Tatsächlich?

Für den gcc ist die Deklaration gleich:

interrupt (INT_VECTOR) void INT_VECTOR_isr(void)
{
  /* viel code... */
}

Einfach nur noch "INT_VECTOR" durch den entsprechenden ersetzen!

>>if (!(P6IN & 0x40))  // musst du natürlich auf deinen Pin anpassen
>>{
>>  _BIS_SR(LPM0_bits + GIE);   // ab in den LPM0 mit Interrupts
>>}

>Kannst du mir den Ausdruck in der Klammer
>(!(P6IN & 0x40))  noch ausschreiben, habe immer mühe mit diesen
>kurzschreibweisen.

Wie man hier sieht, hat Jörg Wunsch völlig recht, wenn er sich über
"Magic Numbers" beschwert!

if (!(P6IN & BIT6)) wäre schon deutlich lesbarer,

#define LPMACTIVATED (!(P6IN & BIT6))
[..]
if (LPMACTIVATED)[..]

wäre sogar noch halbwegs Portabel.

Gruß,
Patrick...

von OldBug (Gast)


Lesenswert?

>Das Problem ist nun, dass der Wert der Flaschen beim Powerdown
>verloren geht, da diese Variablen im RAM gespeichert werden.

Warum nicht einfach ins Infomem schreiben? Dann steht der aktuelle
Inhalt im Flash...

Gruß,
Patrick...

von Sebastian (Gast)


Lesenswert?

Hi,

>>Ein USART-Interrupt geht anders als ein A/D-Wandler-Interrupt ...
>Tatsächlich?

Ich denke schon. :-) Ein USART-Interrupt geht über

#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx (void) {...}

Ein A/D-Interrupt hat bestimmt andere Bezeichner. :-)

>Wie man hier sieht, hat Jörg Wunsch völlig recht, wenn er sich über
>"Magic Numbers" beschwert!
>if (!(P6IN & BIT6)) wäre schon deutlich lesbarer

Tschuldigung, wenn ich mir nicht die Mühe mache, bei meinem Posting
eine 100%ig perfekte Form zu wählen. ICH bekomme jedenfalls kein Geld
dafür, dass ich hier was schreibe ...

Grüße, Sebastian

von Mike (Gast)


Lesenswert?

ich bin einfach nicht mit dem Hardwaremanual des MSP430 vertraut, und da
mich die ganze arbeit schon so sehr viel zeit kostet, habe ich einfach
keine lust mich mit flashvariablen und sonsiges zu beschäftigen. dazu
kommen noch die ganzen drinkrezepte, welche konfigurierbar sein sollen.
darum müsste ich diese auch noch ins flash schreiben. ich glaube die
lösung mit der speicherbatterie kommt einfach mit weniger mühe zu
stande.
hat jetzt jemand eine konkrete lösung für mein problem??? als euch
gegenseitig über die schreibweisen zu beklagen, könntet ihr mir lieber
eine schöne lösung präsentieren ;O)

von OldBug (Gast)


Lesenswert?

Huiui...
Nicht gleich angemacht fühlen!

Ich bekomme da auch kein Geld für, aber Summier doch mal bitte die
Anzahl der Zeichen und vergleiche auf <=>... na!?!? ;-)

Da hier niemand ausser mir schreibt, mit welchem Compiler ihr arbeitet
(es wird kein gcc sein, da man dort keine #pragma's für interrupts
benötigt), weis ich auch nicht, wie "anders" bei euch jeder Interrupt
aussieht! Bei mir sehen alle deklarationen, bis auf die Angabe des
Vektors, gleich aus.

interrupt (UART0RX_VECTOR) void isr_USART0RX(void) {...}
interrupt (PORT1_VECTOR) void isr_PORT1(void) {...}
interrupt (TIMERA1_VECTOR) void isr_TimerA1(void) {...}

Die Prototypen sehen dann so aus:

void isr_USART0RX(void);
etc. pp.

Gruß,
Patrick...

von OldBug (Gast)


Lesenswert?

>als euch gegenseitig über die schreibweisen zu beklagen,
>könntet ihr mir lieber eine schöne lösung präsentieren ;O)

Wo bleibt denn da der Spaß an der Diplomarbeit?
Ich kann Dir gerne die Flash-Access-Routinen zur Verfügung stellen...

Gruß,
Patrick...

von Sebastian (Gast)


Lesenswert?

Hast ja recht. :-) Mag es nur nicht, wenn ich mir hier Mühe mache uns
'ne halbe Stunde tippe und dann dumm angemacht werde, nur weil ich
einen Zahlenwert nicht durch sein define ersetzt habe, was wohl in den
Augen Mancher unschön ist ...

Aber was die konkrete Frage angeht, muss ich gestehen, dass das so
trivial ist, dass ich gar nicht weiss, ob das geht -- dass ein normaler
IO-Event den MSP430 aufweckt?!

Den MSP430 in den LPM0 zu schicken ist simpel, aber irgendwas muss ihn
ja wieder aufwecken. Sowas habe ich bis jetzt eben nur bei Interrupts
von extern gemacht, wie z.B. Daten vom USART. Notfalls müsste man sich
eben da was ausdenken. Die Erkennungsschaltung an den USART0 hängen und
so den USART "missbrauchen" ...

Grüße, Sebastian

von Mike (Gast)


Lesenswert?

habe eben von der USART leitung keinen Pin mehr frei, da ich schon alles
für standart I/O verbracht habe. An P1 habe ich noch 2 Pins frei, sonst
müsste ich die ganze Belegung über den haufen werfen.
Da P1 interrupt tauglich ist, muss es doch irgendwie möglich sein, bei
einer fallenden Flanke am Pin den msp schlafen lassen und sobald die
Flanke wieder steigend ist, ihn wieder aufzuwecken.
Keine IDee???

von Sebastian (Gast)


Lesenswert?

Hi,

>Huiui...
>Nicht gleich angemacht fühlen!

Nene, ist ja schon gut ... :-)

> Da hier niemand ausser mir schreibt, mit welchem Compiler ihr
> arbeitet (es wird kein gcc sein, da man dort keine #pragma's für
> interrupts benötigt)

Ich benutze IAR. Der gcc wurde mir zu unkomfortabel, ist andauernd
abgeschmiert.

> interrupt (PORT1_VECTOR) void isr_PORT1(void) {...}

Das sieht ja schon ganz gut aus. Der MSP430 kann also einen IR
generieren, wenn sich ein ganz normaler IO-Pin ändert? (von low auf
high oder umgekehrt). Sowas simples habe ich bis jetzt noch nie benutzt
... ;-)

Grüße, Sebastian

von Mike (Gast)


Lesenswert?

Ich arbeite mit dem Tool ICC430

von Sebastian (Gast)


Lesenswert?

Hi,

> Da P1 interrupt tauglich ist, muss es doch irgendwie möglich sein,
> bei einer fallenden Flanke am Pin den msp schlafen lassen und
> sobald die Flanke wieder steigend ist, ihn wieder aufzuwecken.

Argh. Patsch. Ich ziehe meine dämliche IR-Frage zurück. Klar, der
MSP430 war ja IR-fähig. Auf Port 1 und 6, oder wie war das noch mal?
Ich muss glaube ich noch mal das Datasheet raussuchen ...

Grüße, Sebastian

von OldBug (Gast)


Lesenswert?

Der F149 ist auf PORT1 und PORT2 Interruptfähig.
Jeweils alle 8 Pins können Interrupte auslösen, sogar
Flankengetriggert.

Gruß,
Patrick...

von Sebastian (Gast)


Lesenswert?

Hi,

ahja, hab es jetzt auch gefunden. Mike, Seite 9-4 ff. im User's Guide
slau049d.pdf sind dein Freund. :-) Da steht genau erklärt, dass P1 und
P2 IR-fähig sind, welche Register du benutzen musst, um die Flags
auszulesen usw.

Dann sollte es doch jetzt simpel sein, oder? Wenn der Port auf low
geht, schickst du den MSP430 in den LPM0 (mit dem Code, den ich ganz
oben geschrieben habe). Und eine steigende Flanke auf P1.1 weckt ihn
dann wieder auf.

Grüße, Sebastian

von Fritz Ganter (Gast)


Lesenswert?

Ich hab vom MSP430 keine Ahnung, verwende aber den Sleep Mode bei mir.
Ich lass den µC regelmässig durch einen Timer aufwecken der von einem
externen 32kHz getaktet wird.
Meine Werte schreib ich ins EEPROM, geht ganz einfach, aber anscheinend
hat der MSP430 sowas nicht, sonst wärs erwähnt worden.

von Mike (Gast)


Lesenswert?

danke sebastian
ich habe eben mit interrupt noch garkeine erfahrung und das
hardwaremanual ist ziemlich schwierig für einen anfänger geschrieben.
Kannst du mir einwenig unter die arme greifen und mir helfen?
Wenn du einwenig zeit hast, wäre das wirklich toll, geht auch übers
normale mail. C ist ja eigentlich nicht schwer, jedoch sobald es in die
Hardware des Prozessors geht, stehe ich einfach schnell an.
P1.0 ist der Pin, an welchen ich das signal anschliessen will.
Signal low auf high=alles läuft normal
Signal high auf low=schlafmodus

danke,mike

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.