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


von Bernhard S. (bernhard_s)


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.
1
#define PORT_LED 0x01
2
#define TIMER_LED 0x02
3
#define FREQU_INPUT 0x04
4
#define TIMER_CYCLE 5000
5
6
int main( void )
7
{
8
  // Stop watchdog timer to prevent time out reset
9
  WDTCTL = WDTPW + WDTHOLD;
10
11
12
  
13
  P1DIR |= PORT_LED | TIMER_LED;
14
  P1OUT = 0x00; //disable all at the begining
15
  
16
  //in pin LDR
17
//  P1REN |= FREQU_INPUT;
18
  P1IE |= FREQU_INPUT; //enable interrupt
19
  P1IES |= FREQU_INPUT; //Hi/Lo Edge
20
  P1IFG &= ~FREQU_INPUT; //clear
21
22
  
23
  // cycle timer
24
  CCTL0 = CCIE;  // CCR0 interrupt enabled
25
  CCR0 += TIMER_CYCLE; //start soon
26
  TACTL = TASSEL_2 + MC_2;  // SMCLK, contmode [?]
27
        
28
  _BIS_SR(GIE);
29
}
30
31
32
#pragma vector=TIMERA0_VECTOR
33
__interrupt void Timer_A (void)
34
{
35
    P1OUT ^= TIMER_LED;
36
}
37
38
39
#pragma vector=PORT1_VECTOR
40
__interrupt void Port1 (void)
41
{
42
    P1OUT ^= PORT_LED;
43
    P1IFG &= ~FREQU_INPUT;
44
// how can I change Hi/Lo to Lo/Hi Edge detect?
45
// P1IES ^= FREQU_INPUT; //does this work??
46
}

von Jörg S. (joerg-s)


Lesenswert?

Du willst die LED also einfach irgendwie blinken lassen?

von Bernhard S. (bernhard_s)


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.

von Bernhard S. (bernhard_s)


Lesenswert?

*Demo Aufbau

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

von Jörg S. (joerg-s)


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?

von Bernhard S. (bernhard_s)


Lesenswert?

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

von love MSP430F2013 (Gast)


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

von Bernhard S. (bernhard_s)


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

von love MSP430F2013 (Gast)


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 !

von Dennis (Gast)


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
1
 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!

von Dennis (Gast)


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
}

von Dennis (Gast)


Lesenswert?

Sorry...[/c] :)

von Dennis (Gast)


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!

von love MSP430F2013 (Gast)


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).

von Bernhard S. (bernhard_s)


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

von Bernhard S. (bernhard_s)


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"

von Dennis (Gast)


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.

von Bernhard S. (bernhard_s)


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
1
#include <msp430x20x3.h>
2
3
#define TIMER_LED 0x01
4
#define PORT_LED_LOHI 0x02
5
#define PORT_LED_HILO 0x04
6
#define FREQU_INPUT 0x10
7
#define TIMER_CYCLE 50000
8
9
int main( void )
10
{
11
  // Stop watchdog timer to prevent time out reset
12
  WDTCTL = WDTPW + WDTHOLD;
13
14
15
  P1OUT = 0x00; //disable all at the begining  
16
  P1DIR |= PORT_LED_HILO | PORT_LED_LOHI | TIMER_LED;
17
18
  
19
  P1IE |= FREQU_INPUT; //enable interrupt
20
  P1IES |= FREQU_INPUT; //Hi/Lo Edge
21
  P1IFG &= ~FREQU_INPUT; //clear
22
23
  
24
  // cycle timer
25
  CCTL0 = CCIE;  // CCR0 interrupt enabled
26
  CCR0 = TIMER_CYCLE; //start soon
27
  TACTL = TASSEL_2 + MC_2;  // SMCLK, contmode [?]
28
        
29
  _BIS_SR(LPM0_bits + GIE);
30
}
31
32
33
#pragma vector=TIMERA0_VECTOR
34
__interrupt void Timer_A (void)
35
{
36
    P1OUT ^= TIMER_LED;
37
}
38
39
40
#pragma vector=PORT1_VECTOR
41
__interrupt void Port1 (void)
42
{
43
  if (P1IES & FREQU_INPUT)
44
    P1OUT ^= PORT_LED_HILO;
45
  else
46
    P1OUT ^= PORT_LED_LOHI;
47
  P1IFG &= ~FREQU_INPUT;
48
  P1IES ^= FREQU_INPUT; //change edge detect
49
}

von Bernhard S. (bernhard_s)


Lesenswert?

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

von Bernhard S. (bernhard_s)


Lesenswert?

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

von Dennis (Gast)


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".

von Dennis (Gast)


Lesenswert?

Nur mal aus Interesse, wie habt ihr das in Hardware gelöst?

von Bernhard S. (bernhard_s)


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).

von Bernhard S. (bernhard_s)


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
1
#include <msp430x20x3.h>
2
3
#define TIMER_LED 0x01
4
#define PORT_LED_LOHI 0x02
5
#define PORT_LED_HILO 0x04
6
#define FREQU_INPUT 0x10
7
#define OUT_CTRL 0x40
8
#define TIMER_CYCLE 50000
9
10
static int x = 0;
11
int main( void )
12
{
13
  // Stop watchdog timer to prevent time out reset
14
  WDTCTL = WDTPW + WDTHOLD;
15
16
17
  P1OUT = 0x00; //disable all at the begining  
18
  P1DIR |= PORT_LED_HILO | PORT_LED_LOHI | TIMER_LED | OUT_CTRL;
19
  P1SEL |= OUT_CTRL;
20
21
  
22
  P1IE |= FREQU_INPUT; //enable interrupt
23
  P1IES |= FREQU_INPUT; //Hi/Lo Edge
24
  P1IFG &= ~FREQU_INPUT; //clear
25
26
  
27
  // cycle timer
28
  CCTL0 = CCIE;  // CCR0 interrupt enabled
29
  CCR0 = TIMER_CYCLE; //start soon
30
  CCTL1 = OUTMOD_6;
31
  CCR1 = 0;
32
  TACTL = TASSEL_2 + MC_3;
33
        
34
  _BIS_SR(LPM0_bits + GIE);
35
}
36
37
38
39
//ist es möglich PWM und timerinterrupts gleichzeitig zu benutzen???
40
#pragma vector=TIMERA0_VECTOR
41
__interrupt void Timer_A (void)
42
{
43
// f(x) eine Formel die Tastverhältnis*TIMER_CYCLE zurückgibt
44
    CCR1 += f(x); // += oder = ???
45
    x=0;
46
47
    P1OUT ^= TIMER_LED;
48
}
49
50
51
#pragma vector=PORT1_VECTOR
52
__interrupt void Port1 (void)
53
{
54
  ++x;
55
  if (P1IES & FREQU_INPUT)
56
    P1OUT ^= PORT_LED_HILO;
57
  else
58
    P1OUT ^= PORT_LED_LOHI;
59
  P1IFG &= ~FREQU_INPUT;
60
  P1IES ^= FREQU_INPUT; //change edge detect
61
}

von Bernhard S. (bernhard_s)


Lesenswert?

Der code vom letzten Post funktioniert NICHT

von Dennis (Gast)


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.

von Bernhard S. (bernhard_s)


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?

von Bernhard S. (bernhard_s)


Lesenswert?

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

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.