Guten Morgen,

im Anschluss also das momentan aktuelle Programm. Ich kann dir aber noch nicht versprechen, dass es 100%ig gleich bleiben wird, aber viel wird sich auf jeden Fall nicht mehr ändern.
Wenn dich 'nur' der problematische Programmteil interessiert schau einfach nur in die Datei int.c (und da in die Funktion TriggerISR), ich poste hier mal mein komplettes Programm (+ Disassembly).
Viele Grüße nach Wien
Michael

Datei main.c:
Code:
#include "main.h"
#include "io.h"

//declaration of functions
extern void PortInit(void);				//declared in ports.c
extern void TimerInit(void);			//declared in timer.c
extern void InterruptInit(void);		//declared in int.c
extern void Shoot (void);				//declared in int.c
extern void CorrectTimes(void);			//declared in timer.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 ready;								//0 if shoot paused, 1 if shoot is performed
volatile bit mainc;								//1 if main contactor is used, else 0
volatile bit europe;							//1 if f=50Hz (European), 0 if f=60Hz (American)

extern volatile bit error;						//declared in int.c

/*--------------------------------------------------------------*/
/*	function main												*/
/*	initalizes the controller, executes the program				*/
/*	no input, no return value									*/

void main (void)
{
	PortInit();						//initialize the ports
	TimerInit();					//initialize the timers
	InterruptInit();				//initialize the trigger-interrupts
	counter = 0;					//set starting value for counter
	ready = 0;						//shoot must not be performed yet
	EA = 1;							//enable all interrupts globaly

	while(counter < 5);			//wait for 5 transmissions from the computer
	finished = 0;				//reset finished bit
	if ((phase & 0x80) == 0)
	{
		europe = 0;
	}
	else
	{
		europe = 1;
	}
	if (mainc == 1)
	{
		P0_DATA |= 0x2;			//close the serial contactors (shoot is performed with main contactor)
	}
	else
	{
		P0_DATA |= 0x1;			//close the main contactor (shoot is performed with serial contactors)
	}
	CorrectTimes();				//corrects time1 to time3

	while(ready == 0);			//wait for shoot-signal from computer
	if (usePhase == 1)
	{
		IRCON0 &= 0xfd;			//reset IR-Bit of null-phase
		while ((IRCON0 & 0xfd) == 0);	//wait for IR-Bit of null-phase
		if (europe == 1)
		{
			TR0 = 1;			//start T0 (for 50Hz)
			while (phase > 0);	//wait until signal has desired phase
			TR0 = 0;			//stop T0
		}
		else
		{
			TR1 = 1;			//start T1 (for 60Hz)
			while (phase > 0);	//wait until signal has desired phase
			TR1 = 0;			//stop TR1
		}
	}
	Shoot();					//perform the shoot
	while(1);
}
//end of function main()
Datei int.c:
Code:
#include "main.h"

//declaration of functions
void ResetShoot(void);
void Shoot(void);

//declaration of variables
volatile bit error;											//to correct counter if necessary
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, ready;							//declared in main.c

/*------------------------------------------------------*/
/*	function InterruptInit								*/
/*	initializes the trigger-interrupts					*/
/*	no input, no return value							*/
/*	shoot -> EXINT2	(both edges)									
	trigger -> EXINT3 (rising edge)
	phase -> EXINT1 (rising edge) NOT ACTIVATED!!!		*/

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 = 0x64;						//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)
	error = 1;
}
//end of function InterruptInit()

/*------------------------------------------------------*/
/*	function TriggerISR									*/
/*	ISR for trigger signal to latch time and phase		*/
/*	no input, no return value							*/

void TriggerISR() interrupt 9
{
	switch (counter)
	{
		case 0:
			time1 = P3_DATA; 		//get LSB of time
			break;

		case 1:
			time2 = P3_DATA;		//get 2nd byte of time
			if (time1 > 127 && error == 1)
			{
				error = 0;
				counter--;
			}
			break;

		case 2:
			time3 = P3_DATA;	  	//get MSB of time
			break;

		case 3:
			phase = P3_DATA;		//get phase information
			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++;								//increase counter value by 1
	IRCON0 &= 0xf7;							//reset IR-Bit of trigger
}
//end of function TriggerISR()

/*------------------------------------------------------*/
/*	function ShootISR									*/
/*	ISR for pin shoot -> start or pause shoot			*/
/*	no input, no return value							*/

void ShootISR () interrupt 8
{
	if ((P2_DATA & 0x2) == 0)		//-> Interrupt on falling edge
	{
		ResetShoot();				//open the contactor
		ready = 0;					//reset ready-bit
	}
	else
	{
		if (counter > 0) 			//if first IR on rising edge->maybe use phase information
		{
			ready = 1;				//just set the ready bit (shoot performed by main())
		}
		else
		{		
			Shoot();				//close the contactors
			ready = 1;				//set the ready-bit
		}
	}
	IRCON0 &= 0xfb;					//reset IR-Bit of shoot
}
//end of function ShootISR()

/*------------------------------------------------------*/
/*	function ResetShoot									*/
/*	stops the shoot										*/
/*	no input, no return value							*/

void ResetShoot()
{
	TR2 = 0;						//stop T2
	if (mainc == 1)
	{
		P0_DATA &= 0xfe;			//open the main contactor
	}
	else
	{
		P0_DATA &= 0xfd;			//open the serial contactors
	}
}
//end of function ResetShoot()

/*------------------------------------------------------*/
/*	function Shoot										*/
/*	closes the relais for the shoot and starts T2		*/
/*	no input, no return value							*/

void Shoot()
{
	if (mainc == 1)
	{
		P0_DATA |= 0x1;				//close the main contactor
	}
	else
	{
		P0_DATA |= 0x2;				//close the serial contactors
	}
	TR2 = 1;						//start T2
}
//end of function Shoot()