Autor Tema: Problema en Interrupcion Externa ATmega128A  (Leído 4855 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado thegame

  • PIC18
  • ****
  • Mensajes: 441
    • Mcu Tronics
Problema en Interrupcion Externa ATmega128A
« en: 03 de Enero de 2022, 17:26:59 »
Que hay compañeros, Feliz Año, empezamos con problemas jajaja  :D  :D  :D

Les platico que, me he armado de valor, y he borrado todo vestigio de CCS Compiler para por fin migrar mis proyectos a Atmel........bueno no he borrado nada aun, pero si quiero pasarme ya a estos micros jajaja

He comenzado a migrar uno de mis proyectos, que mas me interesa, y una parte esencial es la interrupcion externa, he logrado hacerla funcionar en parte, digo en parte porque me ocurre un problema que seguramente debe ser algo mal echo de mi parte, aunque sospecho del compilador o del IDE (AVRgcc y Microchip Studio)

La interrupcion entra y se ejecuta, pero, en ella, coloco una bandera, algo asi.....

Código: [Seleccionar]
interrupcion (vect_int....)
{
      flag=1;
}

la cosa no es de sintaxis, por si ya me van a regañar que algo no esta bien escrito, es solo para ilustrar y es que el problema no esta en la declaracion de la rutina de interrupcion ni en si entra o no, de que entra, entra, probado, lo que no hace es ponerme la variable flag en 1

en el main( ), especificamente en el ciclo while, infinito, reviso esa bandera, y nunca se cumple el condicional IF que revisa a flag, esto se observa porque nunca enciende el led que le he mandado encender cuando flag sea 1.

algo asi....

Código: [Seleccionar]
void main(void)
{
    while(true)
   {
         if(flag==1)
         {
               flag=0;
               PORTE &= ~(1<<PIN_E4); //(logica negativa)
         }
   }
}

Bueno pues si coloco, directamente la instruccion de encendido, en la rutina de interrupcion todo va de maravilla, enciende apenas se genera la interrupcion externa en el pin correspondiente

Pero si se me ocurre hacerlo, atraves de la variable flag, no funciona

No se si es un tema de tipos de variables, uso una tipo uint_8, he probado cambiandola a int, y char, pero eso no hace ningun cambio, sigue igual.

Que sera que cuando uso flag, no funciona

Que hace falta?

En CCS jamas tuve un problema similar, que no me colocara una bandera a 1 ó 0, segun el caso, y es que estoy mas que seguro que si funciona la interrupcion.

De antemano muchas gracias por su ayuda y comentarios

Saludos
Nunca se deja de aprender

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema en Interrupcion Externa ATmega128A
« Respuesta #1 en: 03 de Enero de 2022, 17:43:45 »
Que hace falta?

Código: C
  1. volatile uint_8 flag;

Por lo que comentas tal vez sea el optimizador quitando esa parte del código. Ya que "no se usaria".

Desconectado thegame

  • PIC18
  • ****
  • Mensajes: 441
    • Mcu Tronics
Re:Problema en Interrupcion Externa ATmega128A
« Respuesta #2 en: 03 de Enero de 2022, 18:02:16 »
Que tal Killer

déjame pruebo.....y te comento

gracias
Nunca se deja de aprender

Desconectado thegame

  • PIC18
  • ****
  • Mensajes: 441
    • Mcu Tronics
Re:Problema en Interrupcion Externa ATmega128A
« Respuesta #3 en: 03 de Enero de 2022, 21:54:20 »
no cabe duda, aun me queda mucho por aprender, amigo Killer, tenias razon, funciona a la perfección y como me dio curiosidad, investigue un poco del porque, les dejo un enlace que explica aun mas porque deben declararse de ese modo este tipo de variables.

Muchas Gracias Killer y compañia

https://www.avrfreaks.net/forum/whats-volatile-variable
Nunca se deja de aprender

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema en Interrupcion Externa ATmega128A
« Respuesta #4 en: 04 de Enero de 2022, 07:20:18 »
Es un poco claro el porque se debe definir como volatile en ese thread.. Voy a resumirlo, existen 2 casos principales donde lo declaras volatile a una variable

Te lo explico mejor... En tu código vos tenes una funcion main que siempre se llama y una funcion interrupcion que se llama por hardware (por lo tanto el compilador no sabe que se llama a esa funcion)

Código: C
  1. void interrupcion()
  2. {
  3.       flag=1;
  4. }
  5.  
  6.  
  7. void main(void)
  8. {
  9.     while(true)
  10.    {
  11.          if(flag==1)
  12.          {
  13.                flag=0;
  14.          }
  15.    }
  16. }

Segun para el compilador esa funcion de interrupcion NUNCA se llama , ya que no haces dentro del main: interrupcion();
Por lo tanto para el compilador, vos nunca llamas a la interrupcion seteando la variable flag, y por lo tanto si solo pienso en lo que se ejecuta, segun tu main, jamas cambia flag a otro valor, por lo tanto al if jamas va a entrar, flag va a ser siempre 0 por ejemplo, entonces que mejor que quitar esa parte del código que nunca se va a ejecutar y esta ocupando espacio sin sentido.... Por eso te comentaba que era un tema del optimizador. Es mas, si tenes una opcion para quitar el optimizador, podes probar el codigo sin el volatile y te va a funcionar, pero obviamente uno quiere un codigo compacto o rapido, por lo tanto mejor el optimizador activado.

Por otra parte... Lo mismo ocurre si yo llamo a una variable 2 o 3 veces. Y esta variable se esta cambiando en otro lado (hardware), donde no hay una unión con llamadas entre funciones, el caso mas normal es el puerto de un microcontrolador... Supongamos el PORTE.

Código: C
  1. var = PORTE;             ;Suponete que aca PORTE valia 10
  2. ...
  3. var1 = PORTE + 1;       ; Paso el tiempo y cambio la entrada y ahora PORTE vale 30
  4. ...
  5. var2 = PORTE + 2;

Si no fuera porque PORTE esta declarado como volatile, el optimizador tomaria el primer valor "10" y lo usaria para var1 y var2 tambien... es decir tendrias los resultados 10,11  y 12 respectivamente. Leeria una sola vez para optimizar el codigo y hacerlo mas rapido ya que nada lo cambio entre medio.
Con el volatile estamos tambien avisandole al compilador que esa variable puede cambiar sin que sea el codigo quien lo cambie. Como es el caso de las entradas de un microcontrolador.
Entonces se omite el paso de optimizacion del codigo para esa variable y se busca el valor las 3 veces. quedando con los valores 10,31 y 32 respectivamente.

Espero que sea un poco mas claro.
« Última modificación: 04 de Enero de 2022, 07:28:16 por KILLERJC »

Desconectado thegame

  • PIC18
  • ****
  • Mensajes: 441
    • Mcu Tronics
Re:Problema en Interrupcion Externa ATmega128A
« Respuesta #5 en: 04 de Enero de 2022, 15:13:26 »
Clarisimo compañero Killer

Ojala sea de mucha utilidad a mas compañeros

muchas gracias como siempre

saludos
Nunca se deja de aprender