No puedo salir de la comunicación serial impulsada por interrupciones

0
El programa

funciona correctamente pero después de recibir '#' tiene que salir del bucle while e imprimir "Salir" en lcd pero no lo hace. El programa aún está en el bucle while.

#define F_CPU 14745600
#include<avr/io.h>
#include<avr/interrupt.h>
#include<util/delay.h>
char data;
int ser=1;
void uart2_init(void)
{
   UCSR2B = 0x00; //disable while setting baud rate
   UCSR2A = 0x00;
   UCSR2C = 0x06;
   UBRR2L = 0x5F; //set baud rate lo
   UBRR2H = 0x00; //set baud rate hi
   UCSR2B = 0x98;
}

ISR(USART2_RX_vect)         // ISR for receive complete interrupt
{   
  data = UDR2;
  lcd_wr_char(data);    

  if(data=='#')
  { 
    ser=0;
  } 
}

void init_devices()
{
   cli(); //Clears the global interrupts

   lcd_port_config();
   uart2_init();

   sei();   //Enables the global interrupts
 }

//Main Function
int main(void)
{
  init_devices();
  lcd_set_4bit();
  lcd_init();
  while(ser);
  lcd_string("Exit");
}
    
pregunta Pravein

1 respuesta

3

Tienes ser no declarado como volátil. Lo que esto significa es que el compilador no sabe que se puede cambiar en un ISR.

Esencialmente, ser se inicializa a 1. En la función main() , el compilador examinará el código y verá que llega al bucle while(ser) . Ahora, por lo que puede ver, ser nunca se cambia desde el momento en que se inicializa hasta el momento en que se alcanza el bucle while() (porque puede ver que la función main() no llama a nada que cambie el valor ). También puede ver que ser no cambia dentro del bucle while() .

Lo que esto significa es lo que el compilador puede ver, el bucle while() siempre se ingresará porque ser es 1, pero nunca se cerró porque ser no cambia en ningún lugar que sabe que puede alcanzar la ejecución.

Luego dice, bueno, si el bucle while() nunca saldrá, entonces no tiene sentido comprobar el valor de ser , ni hay ningún punto que incluya el código después del bucle (ya que nunca será alcanzado). Todo el bucle se optimizará para simplemente:

rjmp .-2

Que representa un bucle infinito (saltará a sí mismo y se repetirá para siempre).

Pero espera te oigo llorar. ser puede ser cambiado. Se modifica en el ISR. Bueno, está bien, lo sabes, pero el compilador no. No es consciente de que el procesador puede saltar repentinamente a otro bit de código por su cuenta (bueno, cuando en realidad se activa una interrupción). Necesita decirle que esto puede suceder.

Al declarar algo como volátil, le indica al compilador que siempre cargue desde la memoria el valor de esa memoria cada vez que se use. Esto significa que el compilador no puede asumir que nunca cambiará, porque se le ha dicho que debe verificarlo específicamente. Ya no puede decir con certeza que el valor en la memoria es el valor que se pone al principio.

    
respondido por el Tom Carpenter

Lea otras preguntas en las etiquetas