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(); } }
> 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.
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
>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
@Stefan: Vielen Dank. Das mit dem TAIF Flag habe ich glatt überlesen. Aber mit dieser Änderung funktionert es jetzt.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.