Forum: Mikrocontroller und Digitale Elektronik MSP430 TIMER-A Problem mit Interrupt


von B. B. (bebu1)


Angehängte Dateien:

Lesenswert?

Hallo liebe Forums-Gemeinde!

Ich nutze diese Forum schon länger als Nachschlagwerk, aber das ist 
jetzt mein erstes Post, also habt Rücksicht wenn nicht alles passt ;)

Ich bin Einsteiger beim Programmieren von Mikrocontrollern und stecke 
seit längerem an einem Problem.

Als myC verwende ich einen MSP430F5310 und programmiere mit dem 
CodeComposer.

Ich muss für ein Projekt ein Display(DOGM162 mit ST7036-Controller) 
ansteuern. Ich habe schon sehr viele Code-Bsp im Internet gefunden und 
probiert zu verstehen und anzupassen aber leider blieb das LCD immer 
schwarz ;(.

Nun zu meiner eigentlichen Frage:
Für die Initialisierung des Displays brauche ich eine Zeitverzögerung. 
Da es ja beim MSP keine fertige Funktion gibt, möchte ich es über einen 
Timer mit Interrupt lösen.

Anbei der Code (ich hoffe man kann ich öffnen).
Ich habe probiert den Code Schritt für Schritt durchzugehen und im 
Register die Werte anzusehen. Soweit ich es erkennen konnte zählt er bis 
zum Grenzwert setzt auch das CCIF, geht aber dann nicht in die Routine 
und bleibt in der do-Schleife hängen.

Könnt ihr mit ev. weiterhelfen?

DANKE!

von HutHut (Gast)


Lesenswert?

CCS versteht __delay_cycles, damit sollte es dir möglich sein Anhand der 
der Frequenz ein ein Delay zu erzeugen.

von B. B. (bebu1)


Lesenswert?

Danke, das mit dem delay_cycles habe ich auch schon mal versucht. Weiß 
jetzt aber gar nicht warum ich davon abgekommen bin.
Wäre diese Lösung eine saubere Lösung?
Und weißt du welche Clock dafür verwendet wird?

LG

von Wunder gibt es immer wieder ... (Gast)


Lesenswert?

Du zeigst nur einen kleinen Ausschnitt, aus dem man nix erkennt.

Brauchst den WDT? Wenn nicht ist das eine günstige Zeitreferenz. Wie es 
geht? Steht 1:1 im Family User Guide.

Probiere es einfach aus. Wenn es nicht läuft, melde dich mit deinem Code 
wieder.

von Max G. (l0wside) Benutzerseite


Lesenswert?

In der Initialisierung ist ein delay_cycles() in Ordnung. In der main 
loop dagegen wäre es unfein.

Für die Interrupt-Lösung in deinem Code fehlt das globale 
Interrupt-Enable.
_BIS_SR(LPM0_bits + GIE); sollte dir helfen.

Max

: Bearbeitet durch User
von B. B. (bebu1)


Angehängte Dateien:

Lesenswert?

Ich wollte nicht den ganzen Code anhängen da ich mir dachte dass es zu 
unübersichtlich ist.

Ich arbeite noch am delay, also kann es sein dass noch nicht alles 
korrekt ist.

von B. B. (bebu1)


Lesenswert?

Danke Max!

Du hast mich in die richtige Richtung geführt. Mit dem LPM hat es nicht 
funktioniert aber auf den ersten Blick geht es mit __enable_interrupt();

Danke!

Jetzt muss ich noch schauen ob ich das LCD zum laufen bring ;)

von who (Gast)


Lesenswert?

Zur Anregung hier ein Beispiel mit dem WDT
1
#include "io430.h"
2
3
typedef unsigned char     uint8_t;
4
typedef unsigned int      uint16_t;
5
6
volatile uint16_t delaycount;
7
8
9
void delay (uint16_t time)
10
{
11
  delaycount = time / 8;
12
  while (delaycount > 0) ;
13
}
14
15
void main( void )
16
{
17
    // stop watchdog timer to prevent time out reset
18
  WDTCTL = WDTPW + WDTHOLD;
19
   // clock source DCO, set to 1MHz
20
  BCSCTL1 = CALBC1_1MHZ;
21
  DCOCTL = CALDCO_1MHZ;
22
   // init port
23
  P1DIR |= BIT0;                        // Set P1.0 to output direction
24
   // WDT Timer 8ms
25
  WDTCTL = WDT_MDLY_8;
26
   // enable interrupts
27
  IE1 |= WDTIE;
28
  __enable_interrupt();
29
  while(1)
30
  {
31
    P1OUT |= BIT0;
32
    delay (1000);
33
    P1OUT &= ~BIT0;
34
    delay (250);
35
  }
36
37
}
38
39
//Watchdog Timer interrupt service routine
40
#pragma vector=WDT_VECTOR
41
__interrupt void WDT_ISR (void)
42
{
43
  if(delaycount > 0)
44
    delaycount--;
45
}

Das geht natürlich besser. Solange das Delay läuft könnte man LPM 
aktivieren.

von B. B. (bebu1)


Lesenswert?

Danke für den Tip mit dem WDT, aber ich werde es jetzt mal mit dem Timer 
weiterverfolgen.

Gibt es eine einfache Möglichkeit, die Zeit meines Delays zu überprüfen?
Eine andere Frage habe ich auch noch zu meinem delay. Wenn ich das delay 
im main aufrufe scheint es zu funktionieren. Wenn ich es aber in einer 
ISR zum Entprellen eines Tasters verwenden möchte, gehts es nicht.
Darf ich so überhaupt vorgehen?

von nur mal so (Gast)


Lesenswert?

Bernhard B. schrieb:
> ich werde es jetzt mal mit dem Timer
> weiterverfolgen

Im Beispiel wird der WDT als Timer genutzt. Warum den kostbaren Timer A 
für so einfache Dinge verschwenden?

Bernhard B. schrieb:
> die Zeit meines Delays zu überprüfen

Port Pin toggeln und messen.

Bernhard B. schrieb:
> Wenn ich es aber in einer
> ISR zum Entprellen eines Tasters verwenden möchte, gehts es nicht.
> Darf ich so überhaupt vorgehen?

Du darfst auch durch Null teilen, aber du bekonmmst das nicht ans 
Laufen. ;->

Du erwartest in einer ISR einen anderen Interrupt. Geht das überhaupt? 
Wenn ja, wer darf wenn unterbrechen? Im Datenblatt gibt es eine Tabelle 
und im family user guide ein extra Kapitel.

Eine ISR sollte nicht unnötig aufgebläht werden. Ein delay gehört da 
nicht rein.

von B. B. (bebu1)


Lesenswert?

Der Hintergrund für mein delay mittels Timer war ursprünglich 
folgendlich:
 Ich brauche eine Verzögerung für
- das LCD
- zum Tastenentprellen
- ev. für noch andere Funktionen.

Darum dachte ich mir dass es praktisch ist wenn ich mir eine "gescheite" 
delay-Funktion bastel die ich für alles verwenden kann.

von nur mal so (Gast)


Lesenswert?

Guter Gedanke. Leider läßt sich so nicht das Interruptverhalten des µC 
verändern.

Aber ein delay in einer ISR ist nicht gut, nein, es ist sogar böse. :-D

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.