Forum: Mikrocontroller und Digitale Elektronik MSP430 Timer Uhr sekundentakt


von Markus (Gast)


Lesenswert?

hallo zusammen,

ich möchte mir mal versuchshalber eine ur mit dem msp430f149 bauen.
gibt es irgendwelche tutorials, die zeigen, wie man einen 1s takt
erzeugen kann?

Gruß
Markus

von Jörg S. (Gast)


Lesenswert?

Am aller einfachsten geht das wohl mit dem Watchdog Timer und einem
32kHz Quarz.
Direkt bei TI gibt es zu jedem Prozessor-Typ Code Beispiele. Da sollte
sich auch zum Watchdog was finden lassen.

von Jörg S. (Gast)


Lesenswert?

Hatte das mal selber programmiert (IAR Compiler!):

// Watchdog einstellen:
WDTCTL = WDTPW + WDTHOLD + WDTCNTCL + WDTTMSEL + WDTSSEL + WDTNMI;   //
Watchdog stop, Timer auf "0", Counter-Mode, ACLK, NMI
IE1 |= WDTIE;               // Watchdog Interrupt Enable
WDTCTL = 0x5A3C ;           // Watchdog Start

_EINT();                    // Interrupt generell an


// ISR:
#pragma vector=WDT_VECTOR
__interrupt void WATCHDOG_ISR (void)  // Wird jede Sekunde ausgeführt
{
  sekunde++;
}

von Markus (Gast)


Lesenswert?

hallo,

vielen dank. ich habe mir mal das codebeispeil von ti zur brust
genommen. (RTC) das funktioniert genz prima,lasse erst einmal als test
eine led im sekundentakt an und ausgehen.




Gruß
Markus

von SupaChris (Gast)


Lesenswert?

Jo, mit dem WDT gehts am einfachsten. Hab für ein prohejt auf Arbeit das
auch so gemacht. Allerdings mit Sync auf UTC vom PC aus und Wecker usw
:-) Ist nicht mal viel, grade mal 1600 Bytes.

von Oliver (Gast)


Lesenswert?

U.a. stehts so ähnlich in den Beispielcodes von TI:

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR |= 0x01;                            // P1.0 output
  CCTL0 = CCIE;                             // CCR0 interrupt enabled
  CCR0 = 32769;
  TACTL = TASSEL_1 + MC_2 + ID_0;           // ACLK, contmode,
Vorteiler 0

  _BIS_SR(LPM3_bits + GIE);                 // Enter LPM3 w/ interrupt
}

// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  P1OUT ^= 0x01;                            // Toggle P1.0
  CCR0 += 32769;                            // Add Offset to CCR0
}

von Lucas (Gast)


Lesenswert?

Hallo! Ich arbeite zum ersten mal mit dem MSP430!
Es ist auch das erste mal das ich Mikrocontroller programmiere!
Würde gerne wissen wie ich den Controller vom sleep in den wake up und 
wieder zurück, versetzen kann! So das es sich z. B. alle paar Sekunden 
oder Minuten!
Schmal ein danke schön für jede Hilfe...!
LG Lucas

von Christian R. (supachris)


Lesenswert?

Wenn du die Beispiele die es auf der TI Homepage gibt, dir mal ansiehst, 
und verstehst, ist das kein Problem.

In den LPM3 beispielsweise schickt man den MSP430 mit

_BIS_SR(LPM3_bits + GIE);

Wird ein Interrupt ausgelöst, geht der MSP automatisch in den Active 
Mode.

Ist die Interrupt Service Routine zu Ende, wechselt der MSP erst mal 
wieder in den LPM, der vorher aktiviert war.

Will man den MSP nach Beenden der ISR wach halten muss man das 
gespeicherte Statusregister auf dem Stack verändern, z.B. so:

_BIC_SR_IRQ(LPM3_bits);

das lösche die LPM3-Bits auf dem Stack und nach dem RETI ist der MSP 
noch im Active Mode.

Schau dir insbesondere mal die Application Note SLAA264 an.

von nawhki (Gast)


Angehängte Dateien:

Lesenswert?

Bei mir haengt aber das Code nach dem LPM3 (beim Simulator und FET 
Debug). Ich verwende das MSP430F449 (Olimex MSP430F449STK2).Habe aber 
dieselbe Einstellungen.
Hab jemand eine Idee warum es so it ? Hab 2 Stunden den Fehler 
gesucht..aber leider keine gefunden..

mfg
nawhki

von Jörg S. (Gast)


Lesenswert?

Lös doch mal mit dem Debugger manuell ein Interrupt aus. Wird der dann 
bearbeitet?

von nawhki (Gast)


Lesenswert?

Nein, der wird nicht bearbeitet... Das Code haengt...

von nawhki (Gast)


Lesenswert?

Also. Hab das Problem geloest. Es liegt an das neue Kickstart 3.42A. Hab 
der V3.41A verwendet und das Code geht einwandfrei...

von Pie S. (pie_s)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen, ich experimentiere momentan mit dem MSP 430 (M430G2553).

Ich habe den Code von Oliver getestet und auf Timer A läuft das ganze 
einwandfrei. Ich möchte den Microcontroller alle 8 Sekunden aus dem 
Schlafmodus per Timer Interrupt wecken und wieder in den Schlafmodus 
versetzen. Das habe ich jetzt versucht auf Timer B zu transferieren und 
bis jetzt bin ich einwandfrei gescheitert.

Mein Programm sieht wie folgt aus:

#include <msp430g2553.h>

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR |= 0x01;                            // P1.0 output
  TA1CCTL2 = CCIE;                             // CCR0 interrupt enabled
  TA1CCR0 = 32769;
  TA1CTL = TASSEL_1 + ID_3 + MC_2 + ID_0;           // ACLK, divider 
(8s), contmode,


  _BIS_SR(LPM3_bits + GIE);                 // Enter LPM3 w/ interrupt
}

// Timer A0 interrupt service routine
#pragma vector= TIMER0_A1_VECTOR
__interrupt void Timer1_A3 (void)
{
  _BIC_SR_IRQ(LPM3_bits);               // Enter LPM0 w/ interrupt
  P1OUT ^= 0x01;                            // Toggle P1.0
  TA1CCR0 += 32769; // Add Offset to CCR0
}



Ich verstehe nicht, woher der Vektor und die Funktion _interrupt void 
Timer1_A3 kommt. Ich habe mich durch die Datenblätter geschlagen und bin 
zu dem Schluss gekommen, dass es so sein müsste aber wirklich ein 
Kochrezept habe ich nicht. Ich würde mich sehr freuen, wenn jemand die 
Muße hätte, einen Blick drüber zu werfen. Besten Dank!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Pie Sp schrieb:
> Ich verstehe nicht, woher der Vektor und die Funktion _interrupt void
> Timer1_A3 kommt.

Was meinst mit "woher"? Die Funktion ist ein Interrupthandler, d.h. 
sie wird unabhängig vom Rest des Programmes durch Hardware immer dann 
aufgerufen, wenn der Timer1_A3 seinen Interrupt auslöst.

Der Interruptvektor ist eine Erweiterung des C-Compilers, um solche 
Funktionen überhaupt umsetzen zu können (C selbst weiß nichts von 
Interrupts oder Nebenläufigkeit), und verknüpft die Interruptquelle mit 
der aufzurufenden Funktion -- der MSP430 kennt mehrere Interrupts, die 
alle mit eigenen Interrupthandlern benutzt werden können.

In Deiner main() initialisierst Du den Timer so, daß er unter bestimmten 
Umständen einen Interrupt auslöst. Welche das sind, steht nicht im 
Datenblatt, sondern im zu Deinem 'G2553 gehörenden "MSP430x2xx Family 
User's Guide" (www.ti.com/lit/ug/slau144j/slau144j.pdf). Dort wird jeder 
einzelne Peripheriebaustein ausführlich beschrieben.

von TimerA3 (Gast)


Lesenswert?

Pie Sp schrieb:
> versucht auf Timer B zu transferieren
Der G2553 hat keinen TimerB, er hat zwei TimerA3.
http://www.ti.com/general/docs/datasheetdiagram.tsp?genericPartNumber=MSP430G2553&diagramId=SLAS735J
Wirf einen Blick in das Headerfile deines Compiler. Dort findest du die 
Bezeichnungen für die beiden Timer.

Oliver schrieb:
> // Timer A0 interrupt service routine
> #pragma vector=TIMERA0_VECTOR
> __interrupt void Timer_A (void)
und
Pie Sp schrieb:
> // Timer A0 interrupt service routine
> #pragma vector= TIMER0_A1_VECTOR
> __interrupt void Timer1_A3 (void)
ist nicht richtig transformiert. Bei dir sollte es
#pragma vector= TIMER1_A0_VECTOR
lauten. Im FAmily User Guide unter Timer A findest du am Ende die 
Interruptvektoren.

Pie Sp schrieb:
> TA1CCTL2 = CCIE;                             // CCR0 interrupt enabled
Gibt den Interrupt für CCR2 frei. Für CCR0 ist das TA1CCTL0 zuständig.

Pie Sp schrieb:
> _BIC_SR_IRQ(LPM3_bits);               // Enter LPM0 w/ interrupt
Die Zeile in der ISR ist überflüssig.

Du solltest zuerst ohne LPM testen. Dafür wird eine while(1); in main 
benötigt.

von Pie S. (pie_s)


Lesenswert?

achso, das bedeutet, ich muss der Funktion nur den Namen des Bausteines 
geben und dann ist der Rest erledigt?

#pragma vector= TIMER0_A1_VECTOR
__interrupt void Timer_B (void)
{
  _BIC_SR_IRQ(LPM3_bits);               // Enter LPM0 w/ interrupt
  P1OUT ^= 0x01;                            // Toggle P1.0
  TA1CCR0 += 32769; // Add Offset to CCR0
}

Ich habe jetzt den Namen der Funktion auf "Timer_B" geändert, da der 
Timer laut Users Guide so heißt.

Ich habe auch den Vector gefunden, "Timer_B interrupt vector TBIV Read 
only 011Eh Reset with POR". Wie komme ich jedoch von der Codezeile 
"#pragma vector= TIMER0_A1_VECTOR" auf die richtige Bezeichnung. Ich 
denke "IMER0_A1_VECTOR" ist nicht korrekt. Mir fehlt das Veständnis 
dafür obwohl ich bereits im 6. Semester Elektrotechnik studiere, 
peinlich :-D

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Pie Sp schrieb:
> achso, das bedeutet, ich muss der Funktion nur den Namen des Bausteines
> geben und dann ist der Rest erledigt?

Nein, Du musst auch den passenden Vektor verwenden, sowie die 
Registerzugriffe anpassen.

Sieh in den von mir verlinkten "Family User's Guide", und sieh Dir die 
von TI veröffentlichten Codebeispiele (www.ti.com/lit/zip/slac463) an, 
die zeigen für jeden Peripheriebaustein, wie er zu verwenden ist, und 
wie die jeweils dazu passenden Interruptvektoren aussehen sollen.

Ein Zusammenklicktool für Peripheriinitialisierungen ist TIs "Grace":
http://www.ti.com/tool/Grace#descriptionArea

das kannst Du Dir auch ansehen.

von TimerA3 (Gast)


Lesenswert?

Pie Sp schrieb:
> Ich habe jetzt den Namen der Funktion auf "Timer_B" geändert, da der
> Timer laut Users Guide so heißt.
Guten Morgen, bitte aufwachen: Der G2553 hat keinen Timer B.

Und es gibt
TIMER0_A0
TIMER0_A1
TIMER1_A0
TIMER1_A1
was vier unterschiedliche Interruptvektoren sind.

Lies meinen Beitrag oben.

von Thomas S. (doschi_)


Lesenswert?

Zum M430G2553  findest Du die notwendige Literatur hier:

http://www.ti.com/product/MSP430G2553?keyMatch=G2553&tisearch=Search-EN&keyMatch=G2553&tisearch=Search-EN-Everything
--> http://www.ti.com/product/MSP430G2553/technicaldocuments

1) MSP430G2x53, MSP430G2x13 Mixed Signal Microcontroller (Rev. J)
   http://www.ti.com/lit/gpn/msp430g2553
2) MSP430x2xx Family User's Guide (Rev. J)
   http://www.ti.com/lit/pdf/slau144
3) MSP430G2553 Device Erratasheet (Rev. G)
   http://www.ti.com/lit/pdf/slaz440
Bitte lesen!

Die "code examples" für den G2553 kannst Du unter 
http://www.ti.com/lit/sw/slac485e/slac485e.zip  laden (/slac463  ist für 
die Gxx1-Reihe).

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Thomas Sch. schrieb:
> (/slac463  ist für die Gxx1-Reihe).

Danke für die Korrektur, ist mir offensichtlich durch die Lappen 
gerutscht.

von Pie S. (pie_s)


Lesenswert?

Vielen Dank für die Informationen. Ich habe mit Grace gearbeitet und bin 
ziemlich schnell auf die gewünschte Funktion gekommen.

Dieses Plugin ist ja hervorragend.

Gruß

Philipp

@falls jemand Interesse an dem Quellcode hat, könnte ich Ihn hier auch 
noch veröffentlichen.

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.