Hice esta solucion para el modelado de la sierra en C, queria verificar si hacer una maquina de estados con la logica distribuida podia dar algun problema, mas que nada cuando se disparan las interrupciones, es mi solucion correcta/aceptable?
//maquina dedicada
//STATUS byte que contiene en los bits menos significativos el estado de los botoner
//son apretados simultaneamente si no difieren en mas de 150ms
//en el bit menos signitificativo de CONTROL se enciende o apaga la sierra
//la distancia al material a cortar no vale mas de TOL_MM
//el sensor interrumpe al procesador con la rutina tope, la distancia puede consultarse en DISTANCE
//en caso que la distancia varie fuera de la seguridad, debe encenderse el freno y la luz que debe titilar
//el freno se controla con el bit 2 de CONTROL y la luz con el 4
//hay un reloj de 100hz
#define APAGADA 0
#define PRENDIDA 1
#define FRENOMECANICO 2
char estado;
char estaBoton0Apretado;
char estaBoton1Apretado;
short tiempoBoton0Apretado;
short tiempoBoton1Apretado;
char seHaHechoTope;
short distPrimerTope;
char fueraDeRangoDeSeguridad;
short aControl;
void main() {
//instalo interrupciones
estado = APAGADA;
OUT(CONTROL, 0);
estaBoton0Apretado = 0;
estaBoton1Apretado = 0;
tiempoBoton0Apretado = 0;
tiempoBoton1Apretado = 0;
seHaHechoTope = 0;
distPrimerTope = 0;
fueraDeRangoDeSeguridad = 0;
aControl = 0;
enable();
while(1) {
estaBoton0Apretado = (in(STATUS) & 0x1 == 1);
estaBoton1Apretado = (in(STATUS) & 0x2 == 2);
switch (estado){
case APAGADA:
if(estaBoton0Apretado && estaBoton1Apretado && abs(tiempoBoton0Apretado - tiempoBoton1Apretado)*10 <= 150){
estado = PRENDIDA;
aControl = aControl | 0x1; //prendo motor
seHaHechoTope = 0;
}
break;
case PRENDIDA:
if(fueraDeRangoDeSeguridad){
estado = FRENOMECANICO;
aControl = ((aControl | 0x4) | 0x10); //prendo la alarma y el freno mecanico
}else(!estaBoton0Apretado || !estaBoton1Apretado){
estado = APAGADA;
aControl = aControl & 0xFE; //apago motor
}
break;
case FRENOMECANICO:
if(!estaBoton0Apretado || !estaBoton1Apretado){
estado = APAGADA;
aControl = aControl & 0xFE; //apago motor
aControl = ((aControl & FB) & EF); //se apaga el bit de alarma y de freno mecanico
}
break;
}
OUT(CONTROL, aControl);
}
}
//100 veces por segundo, cada 10ms
void timer(){
if(estaBoton0Apretado)
tiempoBoton0Apretado++;
else
tiempoBoton0Apretado = 0;
if(estaBoton1Apretado)
tiempoBoton1Apretado++;
else
tiempoBoton1Apretado = 0;
}
//cuando el protector de la sierra toca el material a cortar
void tope() {
if(!seHaHechoTope) {
distPrimerTope = in(DISTANCE);
}else{
if(abs(distPrimerTope - in(DISTANCE)) > TOL_MM)
fueraDeRangoDeSeguridad = 1;
else
fueraDeRangoDeSeguridad = 0;
}
}