Forum: Mikrocontroller und Digitale Elektronik MSP430G2452 128ms Tastenentprellung


von Stephan G. (toaran)


Lesenswert?

Hallo zusammen

ich habe bei meinem Projekt einen MSP430G2452 Mikrocontroller und einen 
LTC2951 Pushbutton Controller.

der Pushbutton Controller schaltet auf Knopfdruck einen Raspberry Pi ein 
und fährt den beim nächsten druck wieder runter.  "gleichzeitig" mit dem 
Knopfdruck wird ein anderer Verbraucher eingeschaltet über den MSP... da 
der Pushbutton Controller aber eine fixe einschalt Entprellzeit von 
128ms hat muss ich die auch per software im MSP nachbilden das beide 
Geräte gleichzeitig eingeschaltet werden...

Wie mach ich das am besten?
Per Hardware synchronisieren geht nicht die Hardware ist fix...

ich versuche mit diesem code ein delay von 1ms zu erreichen...
1
void Delay_ms(unsigned int DelayTime)
2
{
3
    unsigned int i=0;
4
    do
5
    {
6
        for(i=0;i<12000;i++)
7
        {
8
            _NOP();
9
        }
10
    }while(DelayTime--);
11
}

Mein Controller läuft mit 12MHz und ich dachte ein _NOP ist ein cycle...
Ich finde auch keine Beschreibung zu no_operation...

Irgendwie schein ich mich da zu verrechnen...

kann mir wer nen Tip geben?

von Felix A. (davinciclaude)


Lesenswert?

Es gibt die Funktion _delay_cycles().
(vllt. beginnend mit 2 Underscores).

von HG (Gast)


Lesenswert?

Stephan G. schrieb:
> Mein Controller läuft mit 12MHz und ich dachte ein _NOP ist ein cycle...
> Ich finde auch keine Beschreibung zu no_operation...

Das Datenblatt des Controllers bzw. die Unterlagen des Compilers sollten 
dazu mehr wissen. Ist die Verzögerungszeit zu lang? In der Schleife 
braucht natürlich auch das inkrementieren von i und die Prüfung der 
Abbruchbedingung ein paar zusätzliche Cycles pro Schleife.

von Christina (Gast)


Lesenswert?

Wie es auf einem MSP430 ist kann ich Dir leider nicht sagen.

Allerdings wurde ich auch davon überrascht, dass ein PIC16 eine 
Anweisung pro vier Takten ausführt. Das stand irgendwo ganz tief im 
Datenblatt.

LG Christina

von Thomas E. (thomase)


Lesenswert?

Stephan G. schrieb:
> ich versuche mit diesem code ein delay von 1ms zu erreichen...

Um das zu erreichen, müsstest du die Schleife ausrollen und das Nop 
12000 Mal hintereinander schreiben, denn die Schleife bekommst du nicht 
umsonst. Die benötigt sogar viel mehr Zeit als das Nop.

: Bearbeitet durch User
von JobstIII (Gast)


Lesenswert?

Stephan G. schrieb:
> kann mir wer nen Tip geben?

Sich mit einem Simulator die Cycles ansehen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Stephan G. schrieb:
> "gleichzeitig" mit dem Knopfdruck wird ein anderer Verbraucher
> eingeschaltet über den MSP..

Wäre es nicht einfacher, den Ausgang des "Pushbutton-Controller" mit dem 
MSP430 zu überwachen? Dann musst Du Dich nicht um die Entprellung 
kümmern ...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Stephan G. schrieb:
> ich versuche mit diesem code ein delay von 1ms zu erreichen...void
> Delay_ms(unsigned int DelayTime)

 Erst einmal kürzer schreiben:
1
 void Delay_ms(unsigned int DelayTime)
2
 {
3
    for(unsigned int i=DelayTime;i>0;i--) {
4
         _NOP();
5
    }
6
 }

 Und dann mit verschiedenen Werten von DelayTime die richtige Zeit
 rausfinden.

 Wenn es wirklich nicht anders geht...

von Stephan G. (toaran)


Lesenswert?

Rufus Τ. F. schrieb:
> Stephan G. schrieb:
>> "gleichzeitig" mit dem Knopfdruck wird ein anderer Verbraucher
>> eingeschaltet über den MSP..
>
> Wäre es nicht einfacher, den Ausgang des "Pushbutton-Controller" mit dem
> MSP430 zu überwachen? Dann musst Du Dich nicht um die Entprellung
> kümmern ...

Das wird leider nix da die Hardware fix ist und der Ausgang vom PBC ist 
nicht mit dem MSP verbunden... leider.

von chris (Gast)


Lesenswert?

Warum hat eigentlich noch niemand die Verwendung eines Timers 
vorgeschlagen?
Es gibt Gerüchte, dass diese extra für Anwendungen wie diese in den 
Mikrocontroller eingebaut wurden.
Und wenns bloß der Systick o.ä. ist, der z.B. einen 1ms Basistakt 
liefert.

von Peter D. (peda)


Lesenswert?

Stephan G. schrieb:
> muss ich die auch per software im MSP nachbilden das beide
> Geräte gleichzeitig eingeschaltet werden

Gleichzeitig geht nicht, da werden immer einige 100ns Unterschied sein.
Der MC mit Quarz kann die 128ms recht genau abbilden. Der Entprell-IC 
wird aber nur einen RC-Oszillator haben, also bestimmt +-10% Abweichung 
zulassen.
Falls Dein Compiler keine Delay-Lib enthält, solltest Du einen Timer 
benutzen. Dann kann man bequem die Zeitformel als Macro hinschreiben und 
den Compiler die gewünschte Zeit ausrechnen lassen.

von Klaus R. (klara)


Angehängte Dateien:

Lesenswert?

Hallo  Stephan,
ich habe im Dezember eine Sleep-Funktion für den MSP430G2553 
geschrieben. Sie arbeitet mit Interrupt.
1
/* SMCLK = 1 MHz
2
 * Divider to 1 -> 1 MHz
3
 * kürzeste Zeitspanne = 1 Takt / 1 MHz  = 1 µs
4
 * längste Zeitspanne  = 65535 Takte / 1 MHz  = 65535 µs = 65,535 ms
5
 * Für grössere Verzögerungen -> Overflow nutzen
6
 * 1000 ms -> 1000000/65536 = 15 mal overflow, Rest = 16960
7
 *
8
 * TA0CCR0 =    1   =  102,0 µs
9
 *             10   =  114,0 µs
10
 *            100   =  200,0 µs
11
 *           1000   =   1,10 ms
12
 *          10000   =   9,80 ms
13
 *          50000   =  49,25 ms
14
 */

Die Zeiten sind ausgemessen (x-mal Schleife) und mit mit einem Oszi 
kontrolliert worden. Ich habe hier mit SMCLK = 1 MHz gearbeitet. Für 
höhere Frequenzen ist entsprechend umzurechnen.

Bei 128 ms Verzögerung kommt man auch schon bei SMCLK = 1 MHz nicht mit 
gewöhnlichen Interrups aus. Da kommt der Overflow ins Spiel. Die 
maximale Verzögerung mit Overflow beträgt 65535 ms bei SMCLK = 1 MHz.

Ich hatte Verständnisprobleme bezüglich der Interrup-Vektoren. Hier dazu 
mein Thread. Mag es Dir hilfreich sein.
Beitrag "MSP430 Timer im Up-Mode für Sleep-Funktion"

mfg klaus

: Bearbeitet durch User
von Stephan G. (toaran)


Lesenswert?

Klaus R. schrieb:
> Hallo  Stephan,
> ich habe im Dezember eine Sleep-Funktion für den MSP430G2553
> geschrieben. Sie arbeitet mit Interrupt.
>
>
1
/* SMCLK = 1 MHz
2
>  * Divider to 1 -> 1 MHz
3
>  * kürzeste Zeitspanne = 1 Takt / 1 MHz  = 1 µs
4
>  * längste Zeitspanne  = 65535 Takte / 1 MHz  = 65535 µs = 65,535 ms
5
>  * Für grössere Verzögerungen -> Overflow nutzen
6
>  * 1000 ms -> 1000000/65536 = 15 mal overflow, Rest = 16960
7
>  *
8
>  * TA0CCR0 =    1   =  102,0 µs
9
>  *             10   =  114,0 µs
10
>  *            100   =  200,0 µs
11
>  *           1000   =   1,10 ms
12
>  *          10000   =   9,80 ms
13
>  *          50000   =  49,25 ms
14
>  */
>
> Die Zeiten sind ausgemessen (x-mal Schleife) und mit mit einem Oszi
> kontrolliert worden. Ich habe hier mit SMCLK = 1 MHz gearbeitet. Für
> höhere Frequenzen ist entsprechend umzurechnen.
>
> Bei 128 ms Verzögerung kommt man auch schon bei SMCLK = 1 MHz nicht mit
> gewöhnlichen Interrups aus. Da kommt der Overflow ins Spiel. Die
> maximale Verzögerung mit Overflow beträgt 65535 ms bei SMCLK = 1 MHz.
>
> Ich hatte Verständnisprobleme bezüglich der Interrup-Vektoren. Hier dazu
> mein Thread. Mag es Dir hilfreich sein.
> Beitrag "MSP430 Timer im Up-Mode für Sleep-Funktion"
>
> mfg klaus

Hallo Klaus

Vielen Dank für den code das schau ich mir mal genauer an.

SG

von JW (Gast)


Lesenswert?

Ein Code für eine Anzahl X Warteschleifen ist etwa so (in Assembler):


mov   #WarteZyklen,R12    // Anzahl der Zyklen (benötigt selbst typ. 2 
Takte)
call  #Wartefunktion


// Hier die Wartefunktion:
// Hinweis: rrum benötigt den CPUX-Kern, ansonsten 2x rra
// Wichtig: Die funktioniert erst ab mind. 23 Takten!
Wartefunktion:
          sub   #19,R12    // 3T Subtrahiere "Eigenverbrauch" der Fkt. 
*)
ChkBit1:  bit   #BIT1,R12  // 1T Bit 2 gesetzt?
          jz    ChkBit0    // 2T
          jmp   $+2        // 2T 2 Takte warten
ChkBit0:  bit   #BIT0,R12  // 1T
          jz    ChkDone    // 2T
          nop              // 1T
ChkDone:  rra     R12      // 1T folgende Schleife hat 4 Takte je 
Durchlauf
          rra     R12      // 1T
Loop:     dec     R12      // 2T
          jnz     Loop     // 2T
          ret              // 4T Fertig!

// *) Eigenverbrauch sind call=4T, ret=4T, sub, 2 x rra, 2 x bit- und 2 
x jz.

von JW (Gast)


Lesenswert?

Korrektur: nach "dec R12" kommt noch ein "nop"

von Mickael (Gast)


Lesenswert?

JW schrieb:
> eine Anzahl X Warteschleifen ist etwa so (in Assembler)

Warum sollte man sich das antun?

Der MSP hat einen Watchdog-Timer. Wird der Watchdog nicht benötigt, kann 
man ihn gut als Zeitreferenz nutzen und Zähler mit der Genauigkeit des 
Taktgebers erstellen, inkrementieren/dekrementieren.

Beitrag #5070395 wurde von einem Moderator gelöscht.
von JW (Gast)


Lesenswert?

@ Mikael:
Der WDT ist kein normaler Counter, den man beliebig einstellen kann - 
man kann ihn anhalten, rücksetzen und sich ein Interupt-Flag bei CLK/64, 
CLK/512, CLK/8192 oder CLK/32768 ausgeben lassen, sonst nix.

von Mickael (Gast)


Lesenswert?

JW schrieb:
> sonst nix

Der WDT kann als einfacher Timer mit eigener ISR genutzt werden.

Mein guter Freund, bevor du hier Weisheiten vom Stapel läßt: RFM!

von Mickael (Gast)


Lesenswert?

@JW
Hier ein Demo für den WDT als Zeitreferenz
Beitrag "Re: MSP430 Low Power Mode wechseln?"

@all
sorry cross posting!

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.