fbpx

Expresate

Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:

CCS ejecuta IF sin ...
 
Avisos
Vaciar todo

CCS ejecuta IF sin cumplir la condicion

9 Respuestas
6 Usuarios
0 Reactions
22.4 K Visitas
jcobreros
Respuestas: 11
Topic starter
(@jcobreros)
Active Member
Registrado: hace 17 años

Buenas tardes, hoy tengo el día raro.
Veamos, tengo una interrupcion que salta cuando entra algo por el puerto serie. Esta interrupcion escribe en la variable Keypress el valor ASCII recibido, y en el bucle principal hay una rutina que se ejecuta si Keypress es distinto de 0, y al final lo vuelve a poner a 0.
Esto funciona correctamente y nunca me ha dado problemas.
He añadido otro IF más adelante en el Main (encerrando una rutina que antes ya estaba y no daba problemas) y ahora se ejecuta la rutina del Keypress cuando Keypress vale 0 (no todas las veces, pero a intervalos regulares).
Pego código relevante:

int Keypress=0x00;
int ready=0;

#int_rda //interrupcion puerto serie
void rda_isr() {
Keypress=0x00;
if(kbhit()){
Keypress=getc();
}
}

#int_TIMER1
void TIMER(){
ready=1;
}

void main() {
setup_timer_1(T1_INTERNAL | T1_DIV_BY_2);
enable_interrupts(int_rda);
enable_interrupts(global);
enable_interrupts(INT_TIMER1);
set_TIMER1(0);
do {
// CONTROL DESDE LA RS-232
if(Keypress!=0) //ESTE ES EL BUCLE QUE HACE COSAS RARAS. ENTRA Y EL PRINTF IMPRIME QUE KEYPRESS=0
{
printf("%d",Keypress);
Keypress=0;
}

if (ready==1) //ESTE ES EL IF QUE FASTIDIA TODO. EL CODIGO QUE SE EJECUTA YA ESTABA, ES SOLO AL AÑADIR LA CONDICION
{

if (angl>6.28)
{
angl=0;
}
angl+=0.01;
tservo0=2000*sin(angl)+3800;
tservo1=2000*cos(angl)+3800;
ready=0;
}
}
while (TRUE);
}

Lo que pasa es que cuando meto la condicion de ready==1, entra en la rutina de Keypress!=0. Es curioso ver que justo despues de evaluar la condicion, escribe el valor de Keypress y es 0. Muy raro. He comprobado (poniendo printf por todas partes) que la interrupcion rda_isr se ejecuta solo cuando pulso una tecla. es el if(keypress!=0) el que la lía.
Esto es lo más contradictorio que me ha pasado... Si elimino el if(ready==1) el otro IF funciona bien. Si lo vuelvo a poner, el otro IF entra cuando le da la gana.

Alguna idea??

Responder
8 respuestas
safareig
Respuestas: 29
(@safareig)
Eminent Member
Registrado: hace 16 años

Hola jcobreros

Intenta hacer esto. Declara la variable "ready" como volatile. volatile int ready = 0;

De esta forma le dices al compilador que la variable puede tomar distinto valor a 0 en una interrupción o por causas externas al programa.

Un saludo...

Responder
jcobreros
Respuestas: 11
Topic starter
(@jcobreros)
Active Member
Registrado: hace 17 años

Safareig, he intendado lo que dices, tanto volatile int ready como volatiel int keypress, pero sigue exactamente igual.
He probado a crear otra variable como keypress (por darle redundancia al asunto), y cuando pongo "if (keypress!=0 && keypress2!=0)" todo funciona como tiene que funcionar.... pero me jode.
Voy a seguir mirando por ahi, a ver si hay suerte.
Muchas gracias!

Responder
cmelendo
Respuestas: 101
(@cmelendo)
Estimable Member
Registrado: hace 18 años

A veces los compiladores utilizan técnicas de optimizado de memoria o velocidad que pueden contradecir la lógica del programa. Por ejemplo el utilizar memoria Overlay para las variables locales de las funciones (ahorro de memoria al utilizar las mismas posiciones de memoria para distintas variables locales) puede provocar que una interrupción nos cambie el valor de una variable local de la función interrumpida.
Seguramente no sea este tu caso pero mira las opciones de compilación (si las hay, no conozco es CSS) por si las pudieras cambiar. Tambien ayuda mucho ver el código ensamblador que te genera para buscar errores fantasma de este tipo.

Suerte.

Responder
heli
Respuestas: 748
 Heli
(@heli)
Ardero
Registrado: hace 19 años

Puede que, al hacer operaciones trigonométricas en punto flotante, main() tarde tanto en ejecutarse que se produce overrun en la interrupción del puerto serie y getc() devuelve 0x00. Recuerda que, además, 0x00 es un caracter legal que puede ser enviado y recibido por el puerto serie.
Prueba a quitar de main los sin() y cos() y poner otras funciones menos pesadas...
Mira en el manual si esas funciones de librería deshabilitan las interrupciones.

Responder
Página 2 / 2
Compartir: