hi, an meinem msp430x149 sind unter anderem 4 taster, von denen ich einen verwenden möchte, um mittels interrupt in ein menüsystem zu kommen. die taster befinden sich an port1 und werden low-aktiv eingesetzt, indem sie die pins p1.4-p1.7, die über einen 4.7k widerstand an vcc hängen, auf gnd ziehen...das funktioniert soweit auch alles einwandfrei und ist schon eine weile im einsatz. jetzt habe ich folgendes problem: sobald beim initialisieren nach dem setzen des GIE bits auch das dem menü-taster entsprechende bit bei P1IE gesetzt ist, verabschiedet sich der controller sofort sang- und klanglos, wenn die schalter angeschlossen sind, der wert von P1IES spielt dabei keine rolle. die irq service routine wird auch nicht aufgerufen (soll sie ja zu dem zeitpunkt auch noch nicht werden, es wurde ja noch kein taster gedrückt). ich bin langsam echt ratlos. selbst 6 zeilen code bringen so das teil zum abschmieren. habe ich was vergessen? soweit ich weiss müsste das was ich getan habe reichen, und die schalter funktionieren im "normalen leben" ja auch und werden mit der gleichen spannung wie der µc betrieben...bei einem zweiten msp tritt das gleiche problem auf... in grösser verzweiflung michael
Hänge mal zumindest einen Teil Sourcecode an. Dann wird Dir bestimmt jemand helfen können...sonst ists halt nur raterei...
ich habe im folgenden mal die wesentlichen teile angehängt, die zum abstürzen lassen vollkommen ausreichen...nicht aufgelistet ist die routine zur initialisierung des lcds und die variablendeklaration, aber die spielen eigentlich keine rolle... das 4x20er lcd fährt mit 2 schwarzen zeilen hoch, nach der initialisierung ist es klar... das passiert aber nicht, da er eben vorher stoppt... debuggen zeigt, dass er nach P1IE setzen hängt - ohne GIE oder P1IE läuft das programm einwandfrei, die isr sollte ja eigentlich auch nicht besucht werden, da noch kein interrupt auftritt bei der initialisierung. // interrupt service routines #pragma interrupt_handler port1_isr:PORT1_VECTOR void port1_isr(void){ if (P1IFG&0x20){ // check if flag set (p1.5) menu=1; P1IE&=~0x20; // disable irqs (p1.5) P1IFG&=~0x20; // reset flag (p1.5) } } // main program int main(void){ WDTCTL = WDTPW + WDTHOLD; // watchdog off _BIS_SR(GIE); // general interrupt enable P1DIR=0x02; // srf04 echo pulse (p1.0, in), trigger pulse (p1.1, out); 4 switches (p1.4-p1.7, in) P1SEL=0x00; // gpio P1IE=0x20; // enable irqs (p1.5) P1IES=0x20; // irq on falling edge (p1.5) init_lcd(); [...]
Du resettest INNERHALB der ISR das PIE-Bit. Das ist IMHO falsch. Welchen Sinn soll das denn auch haben?
Ohje, noch ne Variante: >#pragma interrupt_handler port1_isr:PORT1_VECTOR >void port1_isr(void){ Leider weis ich nicht, wie man diese #pragma-Zeile richtig aufbaut, aber könnte es sein, daß Du Vektor und zugehörige Funktion vertauschst? Ich verweise immer auf die Makros aus der signal.h: #include <signal.h> interrupt[PORT1_VECTOR] void Port1_Interrupt (void) { /* something */ } für IAR, oder für gcc: #include <signal.h> interrupt(PORT1_VECTOR) void Port1_Interrupt (void) { /* something */ }
Stimmt, die Notation ist mir auch neu. @michael: Welchen Compiler benutzt du? Und welche IDE?
> Du resettest INNERHALB der ISR das PIE-Bit. Das ist IMHO falsch. > Welchen Sinn soll das denn auch haben? der geht danach ins menü und soll keine weitern irqs auslösen. ich gebs ja zu, das könnte man auch an den anfang des menü codes hängen. die einzelnen unterroutinen loopen alle mit while(!menu). ich werde das noch ändern. bei fast leerer isr ist das problem aber nach wie vor das gleiche. > Leider weis ich nicht, wie man diese #pragma-Zeile richtig aufbaut, > aber könnte es sein, daß Du Vektor und zugehörige Funktion > vertauschst? also die notation ist die gleiche wie in der c't, die mich (wie wohl manchen auch) zum msp430 geführt hat, und ich hatte bei timer- oder sonstigen isr's auch nie probleme sondern habe mich eben an diese schreibweise gewöhnt - den compiler scheint es auch nicht weiter zu stören. es handelt sich übrigens um den mspgcc, deshalb glaube ich nicht, dass es ein compilerfehler ist...(semi-)grafische umgebungen nutze ich keine...ich kann aber gerne mal eine andere routinen notation verwenden. was mich wirklich stutzig macht ist eben die tatsache, dass mit abgezogenen tastern keinerlei probleme auftreten... danke euch schonmal für die antworten bisher :)
Aha... Das hätte ich jetzt nicht erwartet... :) Hast Du mal die von mir vorgeschlagene Notation probiert? So stehts jedenfalls im Manual...
_BIS_SR(GIE) ist auch nicht gerade schön, eint(); und dint(); sehen doch
viel netter aus, dann noch sachen wie:
>P1IE=0x20; // enable irqs (p1.5)
in
P1IE = (1 << BIT5); // enable irqs (p1.5)
ändern und schon kann man das auch lesen :-)
Jetzt werf ich das auch noch durcheinander! P1IE = BIT5; Muss das heissen! Wenn Du noch andere Pinne dazu nehmen möchtest: P1IE = BIT0 | BIT2 | BIT5; Aktiviert die Interrupts für P1.0, P1.3 und P1.5...
Najaaa, man muss es ja nicht übertreiben. Diese Notation P1IE=0x20; finde ich völlig ok (und benutze sie auch selber), denn so schwer ist das hexadezimale System nun auch wieder nicht. ;-) @michael: Welche Hardware hast du denn? Olimex? Ein Hardware-Defekt ist ja auch immer mal denkbar ...
Ich wollte ja nur den Hinweis geben, daß man das so besser lesen kann ;) Es geht natürlich noch lesbarer, und es gibt auch immer jemand, ders noch besser kann. DIese "magic numbers" sind aber schon sehr "verpöhnt"... :-)
also ich weiss ja nicht was manche gegen hexadezimale schreibweise haben, schliesslich adressiert man ja immer 8bit, da ist das doch naheliegender :) und den gigantischen zahlenraum von 4 bit pro stelle kann man glaub ich noch überblicken, ich bin da ganz sebastians meinung :) bei den ports kann man das wohl auch bringen, für normale flags nehme ich aber auf jeden fall die defines... > @michael: Welche Hardware hast du denn? Olimex? Ein Hardware-Defekt > ist ja auch immer mal denkbar ... ja, ein olimex. ich habe aber (siehe allererstes posting) schon einen anderen getestet, wäre froh wenns nur das wäre :/ ich probier morgen nochmal rum, der ganze kram steht im moment an der uni :)
ich kam jetzt endlich mal zum testen...die variante mit signal.h hat funktioniert, auch wenn bei > interrupt(PORT1_VECTOR) void Port1_Interrupt (void) > { > /* something */ > } das eine void zuviel war :) danke an alle die sich die mühe gemacht hatten. aus irgend welchen gründen hatte der wohl die irq-routine nicht richtig erstellt. ebenso unklar ist, warum er nach aktivieren der irqs sofort die routine aufrufen will (das macht er jetzt immer noch, deshalb ist damals auch alles abgeschmiert), ich denke das ist architekturbedingt :/ egal. es läuft :)
Ahja, jetzt hab ichs auch gerochen ;-) Das erste "void" ist zu viel, kommt wohl vom C&P...
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.