Hallo Robert,
ich habe es zwar etwas anders angestellt als du, aber ich bin mir mittlerweile definitiv sicher, dass ein 2. Interrupt ausgelöst wird, wenn ich die 'falschen' Werte übergebe.
Ich habe das ganze herausgefunden, indem ich in der ISR nacheinander in jeden case ein EA = 0 (verbietet global ALLE Interrupts) eingefügt habe. Wenn ich den in case 1 reinschreibe und Werte übergebe geht zunächst die erste LED an (für case 0), dann die 2. und dann is Ruhe. Wenn ich die Zeile in case 2 reinschreibe 'verzählt' er sich wieder. Das heißt doch, dass definitiv ein zweiter Interrupt ausgelöst wird, oder?
Dann ist nur noch die Frage woher...
Ich würde dir ja gerne ein Bild von meinem Oszilloskop schicken, aber leider kann man hier ja keine Anhänge an den Thread hängen und auf ftp-Server darf ich von hier scheinbar nicht. Also muss ich dir halt so versichern, dass es nur insgesamt 5 steigende Flanken am Eingang des Controllers gibt. Und die 3. kommt ganz sicher erst nachdem er bereits den counter auf 3 erhöht hat.
Das mit dem Disassembly wird vermutlich relativ schwierig, weil das wieder nur über Screenshot gehen wird, befürchte ich. Da hab ich aber auch schonmal reingeschaut und finde da ehrlich gesagt keinen Fehler. In einer Simulation (ohne Hardware) funktioniert das Programm auch einwandfrei.
Im Anschluß nochmal ein Originallisting meines aktuellen Programms:
Datei main.c:
Datei ports.c:Code://declaration of functions extern void PortInit(void); //declared in ports.c extern void InterruptInit(void); //declared in int.c //declaration of variables volatile unsigned char counter; //counter variable for number of trigger events volatile unsigned char time1, time2, time3; //time in ms (LSB to MSB) volatile unsigned char phase; //phase information volatile bit usePhase; //0 if phase is not used, 1 if phase is used volatile bit mainc; //1 if main contactor is used, else 0 void main (void) { PortInit(); //initialize the ports InterruptInit(); //initialize the trigger-interrupts counter = 0; //set starting value for counter EA = 1; //enable all interrupts globaly while(counter < 5); //wait for 5 transmissions from the computer /*if (mainc == 1) { P0_DATA &= 0xf8; //close the serial contactors (shoot is performed with main contactor) }*/ while(1); }
Datei int.c:Code:void PortInit(void) { P0_DIR = 0xb; //P0.0, P0.1 and P0.3 are outputs P1_DIR = 0x0; //P1.1 is an input P3_DIR = 0x0; //P3.0 to P3.7 are inputs //for testing: P1_DIR |= 0xc0; //P1.6 and P1.7 are outputs P0_DIR |= 0x4; //P0.2 is an output }
Wie gesagt, das EA=0 in int.c deaktiviert nur alle Interrupts (war zum Testen).Code:extern volatile unsigned char counter; //declared in main.c extern volatile unsigned char time1, time2, time3, phase; //declared in main.c extern volatile bit usePhase; //declared in main.c extern volatile bit mainc; //declared in main.c void InterruptInit(void) { //set priorities of interrupts (shoot = 2, trigger and phase = 1) IP1 = 0x8; //reset bit for shoot, set bit for trigger IPH1 = 0x4; //set bit for shoot, reset bit for trigger IP |= 0x4; //set bit for phase IPH = 0x3b; //reset bit for phase EXICON0 = 0x14; //edge selection for the three signals IEN0 &= 0xfb; //disable interrupt for phase (individually) IEN1 |= 0x4; //enable interrupt for the shoot(individually) IEN1 |= 0x8; //enable interrupt for trigger (individually) } void TriggerISR() interrupt 8 { P0_DATA &= 0xf8; switch (counter) { case 0: time1 = P3_DATA; //get LSB of time /*if (time1 == 0) { P0_DATA |= 1; } else { if (time1 == 2) { P0_DATA |= 2; } }*/ break; case 1: time2 = P3_DATA; //get 2nd byte of time /*if (time2 == 0) { P0_DATA |= 0x3; } else { if (time2 == 1) { P0_DATA |= 0x4; } }*/ break; case 2: time3 = P3_DATA; //get MSB of time EA = 0; //disable all interrupts /*if (time3 == 0) { P0_DATA |= 0x1; } else { if (time3 == 13) { P0_DATA |= 0x7; } }*/ break; case 3: phase = P3_DATA; //get phase information /*if (phase == 0) { P0_DATA |= 0x6; } else { if (phase == 128) { P0_DATA |= 0x1; } }*/ break; case 4: switch (P3_DATA) { case 0: usePhase = 0; //-> phase ignored mainc = 0; //use serial contactors break; case 1: usePhase = 1; //-> phase important mainc = 0; //use serial contactors break; case 2: usePhase = 0; //-> phase ignored mainc = 1; //use main contactor break; case 3: usePhase = 1; //-> phase important mainc = 1; //use main contactor break; default: break; } break; default: break; } counter++; P0_DATA = counter; IRCON0 &= 0xfb; //reset IR-Bit of trigger }
Vielen Dank für deine Bemühung!!! und viele Grüße







Zitieren

Lesezeichen