This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Interrupt related crashes.

Dear all,

We are programming a 8051 core in C and we are experiencing crashes which are related to interrupts.

The machine in question uses 2 DACs to control servo motors. These motors rotate 2 C-shaped hands which needs to be homed. This homing (moving to default position) is done by 4 interrupts, 2 for each hand. Each hand has a sensor to detect the opening.

First we let the hands turn and we use a software counter to let them speed up, once at speed I enable 2 external interrupts which are triggered on the opening sensors.

The external interrupts make sure that the hands are steered in the opposite direction at full force to let them stop quicker.

Both external interrupts also start 2 hardware timers at a 1ms interval. These timer interrupts are used to track the time of the counter pulse and to turn the motors off.

Occasionally this action results in complete system reboot. It can go well a 100 times or it may reset after the 5th homing action. The crashs always occurs after the homing, this is why we are convinced it must be related to the interrupts.

The code which starts the motors and enables the external interrupts:

case lowerNippleHands:          // lower nipple arms and store the spokes if mininum torque isn't reached
                        nippleKeysOnNipples=0;  // control a pneumatic cylinder
                        rimMotorEnabled = 0;    // controls a relais
                        leftServoSCREW = 0;     // these are the 4 dacs used to controll the servo motors
                        rightServoSCREW = 0;
                        leftServoUNSCREW=zeroLoadTorqueLeft+10;
                        rightServoUNSCREW=zeroLoadTorqueRight+10;  // start both motors in unscrew direction at low torque
                        gotoCase(lowerNippleHands+1,150);                                        // 300ms delay to the next case
                break;

                case lowerNippleHands+1:
                        updateTorque_bool = false;
                        leftServoUNSCREW=255;                                                                                   // turn the motors at full power
                        rightServoUNSCREW=255;
                        leftServoSCREW=0;
                        rightServoSCREW=0;
                        gotoCase(lowerNippleHands+2,100);                               // 200ms delay to next case
                break;

                case lowerNippleHands+2:
                        iex2=0; // ensures the ISR does not gets executed when ex2 is set,
                        iex3=0; //  " " same for #3
                        ex2=1;  // start listening to upgoing flank of nipple home sensor (enables the ISR)
                        ex3=1;  // these interrupts set two timer interrupts which give a pulse to stop the nipple keys.
                        if(menu == TESTMACHINESEQUENCE) updateTorque_bool = true;
                        readySignal = true;
                break;

The interrupt code is as follows:

void ISR_ex2(void) interrupt ex2_vector                                         // left nipple hand home sensor
{
        ex2=0;
        leftServoSCREW=255;                                                                                                                     // initialize counter pulse
        leftServoUNSCREW=0;

        counterL = 0;                                                                                                                                           // clear this counter
        TR1 = 0;                                         // start timer 1
        TH1 = ((-500 >> 8) & 0xff);
        TL1 = (-500 & 0xff);
        TR1 = 1;
        ET1 = 1;
}

void ISR_ex3(void) interrupt ex3_vector                                         // right nipple hand home sensor
{
        ex3=0;
        rightServoSCREW=255;                                                                                                            // initialize counter pulse
        rightServoUNSCREW=0;

        counterR = 0;                                                                                                                                           // clear this counter
        TR2 = 0;                                         // start timer 2
        TH2 = ((-100 >> 8) & 0xff);
        TL2 = (-100 & 0xff);
        TR2 = 1;
        ET2 = 1;
}

void ISR_timer1(void) interrupt timer1_vector // timer 1 to stop left nipple key 1 ms interval
{
        counterL++;
        if(counterL==counterPulseL) {
                ET1 = 0;
                TR1 = 0;
                leftServoSCREW=0;
                leftServoUNSCREW=0;}
        else {
                TR1 = 0;                                         // restart timer 1
                TH1 = ((-500 >> 8) & 0xff);
                TL1 = (-500 & 0xff);
                TR1 = 1;}
}

void ISR_timer2(void) interrupt timer2_vector                   // timer 2 to stop right nipple key 1 ms interval
{
        counterR++;
        if(counterR==counterPulseR) {
                ET2 = 0;
                TR2 = 0;
                rightServoSCREW=0;
                rightServoUNSCREW=0;}
        else {
                TR2 = 0;                                         // restart timer 2
                TH2 = ((-100 >> 8) & 0xff);
                TL2 = (-100 & 0xff);
                TR2 = 1; }
}

Our leading theory is the crash/system reboot is perhaps a memory overlap between an ISR call and a function call with arguements.

I was wondering if any of you could shed some light on this matter. Could the 'using' keyword resolve our issue? Than we would let the interrupts using an alternative register bank.

I am open for ideas and suggestions.

Bas