Hola a todos,
Estoy desarrollando una aplicación que comunica vía MODBUS con un dispositivo. Quiero detectar si hay una pérdida de comunicación entre ellos para que active una alarma. He implementado un timer con el TMR2 para que active la alarma si transcurren mas de 20 segundos aproximadamente sin comunicación. Funciona correctamente, la alarma se activa a los 20 segundos sin comunicación pero después de un rato el contador se resetea solo y desactiva la alarma hasta que vuelven a transcurrir otros 20 segundos sin comunicación.
Os adjunto el fragmento de código donde está implementado esto a ver si alguien tiene alguna idea de qué puede estar pasando porque no le encuentro ningún sentido....
TMR2_Interrupt
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+INTERRUPT SERVICE ROUTINE
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//-----------------------------------------------------------------------------
//- HIGH INTERRUPT Addressing -
//-----------------------------------------------------------------------------
#pragma code HighInterruptVector = 0x0008
void HighInterruptVector (void)
{
_asm
goto HighInterruptRoutine
_endasm
}
//-----------------------------------------------------------------------------
//- HIGH INTERRUPT Function -
//-----------------------------------------------------------------------------
#pragma interrupt HighInterruptRoutine
void HighInterruptRoutine (void)
{
if (PIR1bits.TMR2IF)
{
if (TMR2_Counter <= 1250) //20 seconds
{
TMR2_Counter ++;
}
PIR1bits.TMR2IF = 0; //CLEAR TMR2 flag
}
}
Yo reseteo manualmente el TMR2_Counter a 0 únicamente al recivir algún dato por la interrupción serie. He comprobado y ésta no se activa en ningún momento, por lo que el reseteo del contador no viene dado por esto.
Alarm managing
if(Alarm1 != 0 | Alarm2 !=0)
{
if (Alarm1 == 0x0003 & Alarm2 == 0x0000) //Loss of synchronism with the motor Alarm
{
alarmCounter = 0; //Reset Alarm counter
syncAlarmCounter_Aux ++;
if (syncAlarmCounter_Aux > 32000) //1 second
{
syncAlarmCounter_Aux = 0;
syncAlarmCounter ++;
if (syncAlarmCounter > 15) //Seconds of Time Out for loss of synchronism alarm
{
PORTCbits.RC0 = 0; //Activate Relay if loss of synchronism alarm detected while x period of time (Negative Logic)
PORTCbits.RC1 = 0;
}
}
}
else //For any other alarm activate Relay
{
alarmCounter_Aux ++;
syncAlarmCounter = 0; //Reset the loss of synchronism Alarm counter
if (alarmCounter_Aux > alarmTimeOut_Aux)
{
alarmCounter_Aux = 0;
alarmCounter ++;
if (alarmCounter > alarmTimeOut)
{
PORTCbits.RC0 = 0; //Activate Relay if alarm detected (Negative Logic)
PORTCbits.RC1 = 0;
}
}
}
if (TMR2_Counter > 1250) //20s without RS485 communication
{
PORTCbits.RC0 = 0; //Activate Relay if alarm detected (Negative Logic)
PORTCbits.RC1 = 0;
}
}
else
{
alarmCounter = 0;
syncAlarmCounter = 0; //Reset the loss of synchronism Alarm counter
if (TMR2_Counter > 1250 ) //20s without RS485 communication
{
PORTCbits.RC0 = 0; //Activate Relay if alarm detected (Negative Logic)
PORTCbits.RC1 = 0;
}
else
{
PORTCbits.RC0 = 1; //Desactivate Relay if no alarm detected
PORTCbits.RC1 = 1;
}
}
Si necesitáis mas info preguntadme sin miedo. Espero que alguien pueda darle luz a este asunto porque me está volviendo loco... Gracias!!!
EDITO:
Ya está solucionado, el problema era el WathcDog que llegaba al overflow y reseteaba el micro completo, me habia olvidado completamente del chucho guardian

, ahor aya funciona todo perfectamente, gracias!!