mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 F2013 Timer A and Hi/Lo Interrupt


Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab mich nun schon einige Zeit mit dem MSP430 F2013 rumgeärgert, 
aber jetzt bin ich an einem Punkt angelangt an dem ich einfach nicht 
verstehe, warum Timer und Flanken Erkennung nicht gleichzeitig benutzt 
können.

Der folgende code compiliert zwar ohne fehler, allerdings startet der 
Timer anscheinend nicht (LED blinkt zumindest nicht).

Bitte um Hilfe, ich bin echt ratlos.

Da es keine anständige Dokumentation gibt, und auch TI mich nur auf die 
Beispiele verwiesen hat, die aber nur einzelne features enthalten, und 
keine kombinationen, hab ich ehrlichgesagt mitlerweile keinen Plan mehr 
was ich tun soll.

#define PORT_LED 0x01
#define TIMER_LED 0x02
#define FREQU_INPUT 0x04
#define TIMER_CYCLE 5000

int main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;


  
  P1DIR |= PORT_LED | TIMER_LED;
  P1OUT = 0x00; //disable all at the begining
  
  //in pin LDR
//  P1REN |= FREQU_INPUT;
  P1IE |= FREQU_INPUT; //enable interrupt
  P1IES |= FREQU_INPUT; //Hi/Lo Edge
  P1IFG &= ~FREQU_INPUT; //clear

  
  // cycle timer
  CCTL0 = CCIE;  // CCR0 interrupt enabled
  CCR0 += TIMER_CYCLE; //start soon
  TACTL = TASSEL_2 + MC_2;  // SMCLK, contmode [?]
        
  _BIS_SR(GIE);
}


#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
    P1OUT ^= TIMER_LED;
}


#pragma vector=PORT1_VECTOR
__interrupt void Port1 (void)
{
    P1OUT ^= PORT_LED;
    P1IFG &= ~FREQU_INPUT;
// how can I change Hi/Lo to Lo/Hi Edge detect?
// P1IES ^= FREQU_INPUT; //does this work??
}

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du willst die LED also einfach irgendwie blinken lassen?

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Letztendlich nein, das sind nur Demo LEDs, im normalfall kommt da eine 
H-Brücke dran, das ist nur der Deom aufbau, isoliert um mein Problem.

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
*Demo Aufbau

Der Input ist ein selbstgebauter optischer drezahlsensor (in der Demo 
ein Schalter)

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist das der richtige Interrupt Vector? Da gab es doch zwei...

Wird der Interrupt NIEMALS aufgerufen, oder doch vielleicht 1-mal?

>_BIS_SR(GIE);
Setzt das auch den LPM, oder fehlt bei deinem Code irgendwie noch eine 
while(1) schleife?

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fehler in dem geposteten C code: statt _BIS_SR(GIE); bitte 
_BIS_SR(LPM0_bits + GIE); benutzen

Autor: love MSP430F2013 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Bernhard,

bitte einmal auf der MSP-Struktur basierende
Sollbeschreibung der Softwarefunktion.

Und JA, Du hast eine LED, die blinken soll.
Das sieht man im Quelltext.
Deine Zukunftsvisionen findet man nicht im Quelltext.

Dann kann P1SEL 0, oder 1 sein. Damit ist dann
die Flanke klar.

Die family-APPN kennst Du.
user groups abgeklappert?
TI-Forum bekannt ?

Gruss
Dietmar

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bitte einmal auf der MSP-Struktur basierende
Sollbeschreibung der Softwarefunktion.

Tut mir leid, bitte was?




Dann kann P1SEL 0, oder 1 sein. Damit ist dann
die Flanke klar.

Danke für diese Info.




Die family-APPN kennst Du.
user groups abgeklappert?
TI-Forum bekannt ?

Nein-Nein-Nein

bitte mehr Info

Autor: love MSP430F2013 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz einfach-
so in der Art:
Durch eine fallende Flanke am Eingang P1.X soll
der Timer TA gestartet werden und,...

Auf der Seite www.ti.com und Suchen nach
MSP430F2013 kommst Du auf die "Heimseite"
dieses Derivates.
Da findest Du dann jede Menge PDFs zum Herunterladen.
Auch das family handbook der 2xx-Serie.

https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Aber nicht dünnhäutig sein. Einige beissen.
Die sind aber fit.
msp430@yahoogroups ist auch eine Quelle des Frohsinns.

Apropos mehr Info.
Schon einmal hier links oben in der Ecke geschaut ; ) ??

Hau 'rein !

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernhard S. schrieb:
> Dann kann P1SEL 0, oder 1 sein. Damit ist dann
> die Flanke klar.

P1SEL hat aber nichts mit der Flanke zu tun! Damit legst du fest, ob du 
ihn als GPIO oder als Special Function nutzen willst.

Generell ist es mit '0' belegt, also als GPIO - es schadet trotzdem 
nicht, dieses Register manuell zu setzen.

Bernhard S. schrieb:
> P1IE |= FREQU_INPUT; //enable interrupt
>   P1IES |= FREQU_INPUT; //Hi/Lo Edge
>   P1IFG &= ~FREQU_INPUT; //clear

Du solltest generell auch immer das Flag löschen, bevor du die 
Interrupts frei gibst. Ist aber nur generell, da GIE erst später gestzt 
wird.

So, wie deine main() momentan aussieht, kann es aber auch nicht 
funktionieren, da dein Programm sofort das Ende erreicht hat.

Bau mal eine
 while (1) {}
 mit ein. In den Schalfmodus kannst du ihn noch später versetzen.

Bernhard S. schrieb:
> CCR0 += TIMER_CYCLE; //start soon

Kannst du machen, aber initialisieren solltest du ihn mit "=", falls 
schon irgendein Scheiss im Register steht. Es sollte aber nach dem 
initialisieren '0' sein.

Bernhard S. schrieb:
> //in pin LDR
> //  P1REN |= FREQU_INPUT;

Wie ist denn die Schaltung aufgebaut? Was kommt am Port-Pin des uCs an? 
Wenn er auf low gezogen wird, dann brauchst du natürlich einen Pull-Up.

Bernhard S. schrieb:
> // how can I change Hi/Lo to Lo/Hi Edge detect?
> // P1IES ^= FREQU_INPUT; //does this work??

Yes, this works!

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
love MSP430F2013 schrieb im Beitrag #1732644:
> Durch eine fallende Flanke am Eingang P1.X soll
> der Timer TA gestartet werden und,...

Also das ist im Quelltext aber nicht drin!

[c]
#pragma vector=PORT1_VECTOR
__interrupt void Port1 (void)
{
   P1OUT ^= PORT_LED;
   P1IFG &= ~FREQU_INPUT;
   TAR = 0;
   CCTLO |= CCIE;
}

#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
   P1OUT ^= TIMER_LED;
   Timer stoppen, bzw. Interrupt disablen, weiß ja nicht, was hier 
insgesamt
   passieren soll
}

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry...[/c] :)

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernhard S. schrieb:
> P1DIR |= PORT_LED | TIMER_LED;
>   P1OUT = 0x00; //disable all at the begining

Ach noch was: Erst an den Port schreiben, dann seine Richtung festlegen! 
Gerade bei der geplanten H-Brücke SEHR WICHTIG!

Autor: love MSP430F2013 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

zu:
> P1SEL hat aber nichts mit der Flanke zu tun! Damit legst du fest, ob du
> ihn als GPIO oder als Special Function nutzen willst.
 Schon klar- auch Kopieren will gelernt sein.
Ich meinte natürlich P1IES (interrupt edge select).

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dumme Frage, macht es irgendeinen unterschied in welchem mode der 
interrupt "läuft"?

Danke für die Infos, ich werd' mich heute Nachmittag/Abend mal hinsetzen 
und das ganze mal anpassen.

Vielen Dank an alle schon mal

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die main endet nicht, das macht die IAR IDE automatisch, außerdem würde 
ich sonst im Debug Mode den Fehler bekommen, "main exited"

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich arbeite auch mit IAR und MSPs und wenn ich es so stehen habe 
wie du, ohne den Controller in den Schlafmodus zu schicken, dann läuft 
er ins Ende.

Aber das teilt er dir natürlich mit, klar.

Die Modes sind unterschiedlich, ja. Ich verwende meistens eher den 
Continous Mode.

Es ist manchmal ein wenig verwirrend mit den verschiedenen Timern, da 
CCR0 halt immernoch ne Sonderstellung hat - der legt ja in der Regel bei 
PWM-Applikationen die Periodendauer fest, die CCR1...X dann die 
Pulsweite.

Da hab ich auch schon oft Probleme mit gehabt, wenn ich CCR0 als ganz 
normalen Zähler haben wollte und zusätzlich CCR1 als weiteren Zähler. 
Aber es geht, klar.

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also nochmals viele Dank an alle.


Das ist jetzt der code, nicht erschrecken, ich hab noch einen weiteren 
Port benutzt um den code bezügl Flankenerkennung zu testen.

Ich bin offen für Verbesserungsvorschläge

#include <msp430x20x3.h>

#define TIMER_LED 0x01
#define PORT_LED_LOHI 0x02
#define PORT_LED_HILO 0x04
#define FREQU_INPUT 0x10
#define TIMER_CYCLE 50000

int main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;


  P1OUT = 0x00; //disable all at the begining  
  P1DIR |= PORT_LED_HILO | PORT_LED_LOHI | TIMER_LED;

  
  P1IE |= FREQU_INPUT; //enable interrupt
  P1IES |= FREQU_INPUT; //Hi/Lo Edge
  P1IFG &= ~FREQU_INPUT; //clear

  
  // cycle timer
  CCTL0 = CCIE;  // CCR0 interrupt enabled
  CCR0 = TIMER_CYCLE; //start soon
  TACTL = TASSEL_2 + MC_2;  // SMCLK, contmode [?]
        
  _BIS_SR(LPM0_bits + GIE);
}


#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
    P1OUT ^= TIMER_LED;
}


#pragma vector=PORT1_VECTOR
__interrupt void Port1 (void)
{
  if (P1IES & FREQU_INPUT)
    P1OUT ^= PORT_LED_HILO;
  else
    P1OUT ^= PORT_LED_LOHI;
  P1IFG &= ~FREQU_INPUT;
  P1IES ^= FREQU_INPUT; //change edge detect
}


Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und der code im letzten Post tut auch das was er soll, hat ich glatt 
vergessen :P

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Denis: Bei meiner H-Brücke ist das nicht wichtig, das haben wir via 
Hardware abgesichert dass es keinen kurzen gibt ;)

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernhard S. schrieb:
> @Denis: Bei meiner H-Brücke ist das nicht wichtig, das haben wir via
> Hardware abgesichert dass es keinen kurzen gibt ;)

Ja, das ist auch gut so, jedoch ist es nicht nur wegen dem Kurzen, 
sondern kann die H-Brücke dann kurz ungewollt "zucken".

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur mal aus Interesse, wie habt ihr das in Hardware gelöst?

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jeweils diagonal einen P und einen N Mos transistor "zusammengehängt". 
Ich kann morgen nochmal nachschauen, hab das nicht mehr so direkt im 
Kopf und die Schaltung liegt bei einem Komillitonen (der die 
letztendlich auch entworfen hat).

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

nachdem ich den Code in der Anwendung getestet habe, hat sich die 
Notwendigkeit von PWM bemerkbar gemacht, um ein "rundes" Verhalten des 
E-Motors zu bekommen (v.a. bei sehr niedrigen Geschwindigkeiten).

Dazu noch edwas sourcecode, bitte kommentare (wurde in dieser Form noch 
nicht getestet)

Ich bin für jede Art von Tips und Anmerkungen dankbar
#include <msp430x20x3.h>

#define TIMER_LED 0x01
#define PORT_LED_LOHI 0x02
#define PORT_LED_HILO 0x04
#define FREQU_INPUT 0x10
#define OUT_CTRL 0x40
#define TIMER_CYCLE 50000

static int x = 0;
int main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;


  P1OUT = 0x00; //disable all at the begining  
  P1DIR |= PORT_LED_HILO | PORT_LED_LOHI | TIMER_LED | OUT_CTRL;
  P1SEL |= OUT_CTRL;

  
  P1IE |= FREQU_INPUT; //enable interrupt
  P1IES |= FREQU_INPUT; //Hi/Lo Edge
  P1IFG &= ~FREQU_INPUT; //clear

  
  // cycle timer
  CCTL0 = CCIE;  // CCR0 interrupt enabled
  CCR0 = TIMER_CYCLE; //start soon
  CCTL1 = OUTMOD_6;
  CCR1 = 0;
  TACTL = TASSEL_2 + MC_3;
        
  _BIS_SR(LPM0_bits + GIE);
}



//ist es möglich PWM und timerinterrupts gleichzeitig zu benutzen???
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
// f(x) eine Formel die Tastverhältnis*TIMER_CYCLE zurückgibt
    CCR1 += f(x); // += oder = ???
    x=0;

    P1OUT ^= TIMER_LED;
}


#pragma vector=PORT1_VECTOR
__interrupt void Port1 (void)
{
  ++x;
  if (P1IES & FREQU_INPUT)
    P1OUT ^= PORT_LED_HILO;
  else
    P1OUT ^= PORT_LED_LOHI;
  P1IFG &= ~FREQU_INPUT;
  P1IES ^= FREQU_INPUT; //change edge detect
}

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der code vom letzten Post funktioniert NICHT

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernhard S. schrieb:
> Jeweils diagonal einen P und einen N Mos transistor "zusammengehängt".

Genau das ist ja die Konstellation, die nicht sicher ist, weil der 
n-Kanäler schneller ist, als der p-Kanäler. Das ist die einfachste 
Möglichkeit, aber keine sichere.

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis schrieb:
> Genau das ist ja die Konstellation, die nicht sicher ist, weil der
> n-Kanäler schneller ist, als der p-Kanäler. Das ist die einfachste
> Möglichkeit, aber keine sichere.

Es gibt P-N Leistungstransistoren Paare die extra für H-Brücken gebaut 
werden, bei denen dei Schaltzeitn nur minimal voneinander abweichen.

In unserem Fall reicht diese Sicherheit aus. Hätte das nicht gereicht, 
dann wär ein "enable" C-MOS schalter vor Vcc zum einsatz gekommen, der 
mit XOR mit den beiden Steuereingängen der H-Brücke gekoppelt ist (und 
falls notwendig Verzögerungsglieder).

Gibt es unter Umständen noch tipps zum Code oder wie man das geschickt 
lösen kann?

Autor: Bernhard S. (bernhard_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber du hast recht, das schließt weiterhin, im Falle von N und P mit 
stark verschiedenen Schaltzeiten einen kurzen nicht aus.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.