www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430F149 Timer A Interrupt/ CrossWorks


Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich beginne gerade mit der Programmierung eine MSP430F149 
Mikrocontrollers von TI. Als Hardware habe ich hier ein Olimex Board und 
als IDE Rowley CrossWorks. Ich versuche gerade den TimerA in Kombination 
mit einem Overflow Interrupt auszuprobieren. Doch leider zeigt mir das 
Multimeter unmittelbar nach dem Power Up am Pin die Spannung von 1,62V 
an. Ich vermute, das er stehts und ständig in der Interrupt-Routine 
verbleibt und jeweils schnell den Port Ausgang von 0 auf 3,3V zieht und 
so eine Spannung von 1,62V am Multimeter zu sehen ist. Kann jemand mir 
den Fehler im Code erklären. Ich weiss, das der Code nicht gerade 
übersichtlich oder effektiv geschrieben ist. Es dienst ausschliesslich 
zum kennlernen des Controllers und der Programmiersprache C.

Danke


typedef struct
  {
  unsigned p1_dir_0:1;
  unsigned p1_dir_1:1;
  unsigned p1_dir_2:1;
  unsigned p1_dir_3:1;
  unsigned p1_dir_4:1;
  unsigned p1_dir_5:1;
  unsigned p1_dir_6:1;
  unsigned p1_dir_7:1;
  }datatype_p1_dir_bit;

typedef union
  {
  datatype_p1_dir_bit   p1_dir_bit;
  unsigned char         p1_dir_byte;
  }datatype_p1_dir_byte;

datatype_p1_out_byte  *ptr_p1_out=(unsigned char*)0x21;
datatype_p1_dir_byte  *ptr_p1_dir=(unsigned char*)0x22;
/*********************************************************************** 
*****************************************
                                Interrupt Routine:  Timer A Overflow
************************************************************************ 
****************************************/
void handle_timer_interrupt(void) __interrupt[TIMERA1_VECTOR]
{
(*ptr_p1_out).p1_out_bit.p1_out_0=!(*ptr_p1_out).p1_out_bit.p1_out_0;
}
/*********************************************************************** 
*****************************************
                                Source File:  Main
************************************************************************ 
****************************************/
void main(void)
{
(*ptr_p1_dir).p1_dir_bit.p1_dir_0=1;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
TACTL = TASSEL0 + TACLR + TAIE; // ACLK, clear TAR, interrupt enabled
TACTL |= MC1; // Start Timer_A in continuous mode
_EINT(); // Enable interrupts
for (;;)
{
_NOP();
}
}

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> datatype_p1_out_byte  *ptr_p1_out=(unsigned char*)0x21;
> datatype_p1_dir_byte  *ptr_p1_dir=(unsigned char*)0x22;

Es gibt eine Include-Datei namens msp430.h, in der Symbole wie P1DIR und 
P1OUT definiert sind. Die solltest Du auch verwenden.


> (*ptr_p1_dir).p1_dir_bit.p1_dir_0=1;

Geht das noch komplizierter?

> (*ptr_p1_out).p1_out_bit.p1_out_0=!(*ptr_p1_out).p1_out_bit.p1_out_0;

Oh ja, es geht noch komplizierter.

Anstelle solcher Konstrukte würde ich schreiben

  P1DIR = 1;

oder meinetwegen

  P1DIR |= 1;



und im Interrupthandler

  P1OUT ^= 1;

Das lässt andere Leute, die sich mit dem MSP430 beschäftigen, leichter 
erkennen, was Du da zu treiben versuchst.

Desweiteren verzichtest Du auf eine Initialisierung des "basic clock 
module". Damit wird ACLK aus LFXT1CLK erzeugt - was ist denn da 
angeschlossen?

Wenn da nichts ist, was schwingen kann, dann wird Deine Interruptroutine 
auch nicht aufgerufen.

Im übrigen ist ein Multimeter vielleicht auch nicht das geeignete 
Mittel, um ein Rechtecksignal mit mehr als 0.25 Hz Frequenz zu messen.

Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

an ACLK ist eine 32kHz Uhrenquarz angeschlossen, das habe ich vergessen 
zu erwähnen. Das Taktsignal habe ich, nachträglich nochmals durch 8 
geteilt, so dass ich gehofft habe, es auf dem Multimeter zu erkennen.

Mit freundlichen Grüßen

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Desweiteren verzichtest Du auf eine Initialisierung des "basic clock
>module". Damit wird ACLK aus LFXT1CLK erzeugt - was ist denn da
>angeschlossen?

Wenn ich die Olimex-Boards so überfliege, ist da meist ein Uhrenquarz 
dran, passt also!

>Im übrigen ist ein Multimeter vielleicht auch nicht das geeignete
>Mittel, um ein Rechtecksignal mit mehr als 0.25 Hz Frequenz zu messen.
 Wenn ich richtig gerechnet habe, sollte bei ACLK=32,768kHz und Timer_A 
im cont_mode die ISR alle 2s aufgerufen werden... passt auch!

Das einzige was nicht passt, ist dass in der ISR das TAIFG-Flag nicht 
zurückgesetzt wird. Das passiert bei diesem Interrupt nicht automatisch, 
weil dieser IRQ von drei verschiedenen Quellen genutzt wird.
Also entweder TAIFG händisch löschen oder besser das TAIV-Register lesen

Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stefan:  Vielen Dank. Das mit dem TAIF Flag habe ich glatt überlesen. 
Aber mit dieser Änderung funktionert es jetzt.

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.