¿Recibiendo una cadena completa de USART en ATMEGA16?

0

Estoy intentando recibir una cadena desde USART pero no, quiero recibir char por char y almacenarlas en una matriz hasta que el usuario ingrese '\ n' y finalmente muestre la cadena en la pantalla LCD, aquí está mi código: / p>

char REC;
void USART_Init(unsigned int BAUD )
{                                                          
unsigned int ubrr;                                     
ubrr=F_CPU/16/BAUD-1;                                
/* Set baud rate */                                   
UBRRH = (unsigned char)(ubrr>>8);                   
UBRRL = (unsigned char)ubrr;                         
/* Enable receiver and transmitter */                 
UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXC);                 
/* Set frame format: 8data, 1stop bit */                 
UCSRC = (1<<URSEL)|(3<<UCSZ0);                         
sei();                                                 
}                                                          

ISR(USART_RXC_vect){
REC = UDR;
}

int main(void)
{ 
lcd_init(20);
USART_Init(9600);
char data[10];
while(1)
   {
    int i = 0;
    while (REC !='\n')
    {
        data[i++]=REC;
    }
    data[i]='
char REC;
void USART_Init(unsigned int BAUD )
{                                                          
unsigned int ubrr;                                     
ubrr=F_CPU/16/BAUD-1;                                
/* Set baud rate */                                   
UBRRH = (unsigned char)(ubrr>>8);                   
UBRRL = (unsigned char)ubrr;                         
/* Enable receiver and transmitter */                 
UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXC);                 
/* Set frame format: 8data, 1stop bit */                 
UCSRC = (1<<URSEL)|(3<<UCSZ0);                         
sei();                                                 
}                                                          

ISR(USART_RXC_vect){
REC = UDR;
}

int main(void)
{ 
lcd_init(20);
USART_Init(9600);
char data[10];
while(1)
   {
    int i = 0;
    while (REC !='\n')
    {
        data[i++]=REC;
    }
    data[i]='%pre%';

    lcd_puts(data);

   }
 }
'; lcd_puts(data); } }
    

1 respuesta

7

De inmediato veo dos problemas, uno de ellos, y otro que muestra un poco de falta de comprensión.

El astuto es esta línea:

char REC;

REC se utiliza dentro de su interrupción y también fuera de su interrupción. Como tal, tiene que estar marcado como volatile o el compilador está en riesgo de optimizarlo ya que no sabe que el ISR lo está modificando.

volatile char REC;

El segundo es cómo lidiar con lo que está en REC:

while (REC !='\n')
{
    data[i++]=REC;
}

Envío la letra "A" a través del USART. REC se establece en A. Luego, en el bucle principal va:

  • ¿Es REC diferente a "\ n"?
  • Sí, es A. Ok, lo agrego a los datos e incremento i (i == 1).
  • ¿Es REC diferente a "\ n"?
  • Sí, es A. Ok, lo agrego a los datos e incremento i (i == 2).
  • ¿Es REC diferente a "\ n"?
  • Sí, es A. Ok, lo agrego a los datos e incremento i (i == 3).
  • ¿Es REC diferente a "\ n"?
  • Sí, es A. Ok, lo agrego a los datos e incremento i (i == 4).

... etc ...

  • ¿Es REC diferente a "\ n"?
  • Sí, es A. Ok, lo agrego a los datos e incremento i (i == 32767).
  • ¿Es REC diferente a "\ n"?
  • Sí, es A. Ok, lo agrego a los datos e incremento i (i == -32768).
  • ¿Es REC diferente a "\ n"?
  • Sí, es A. Ok, lo agrego a los datos e incremento i (i == -32767).

... y así sucesivamente ...

No tienes nada que decir "He usado el personaje que está actualmente en REC".

Lo que deberías estar haciendo es borrar la grabación después de cada vez que consumas un carácter:

if (REC != 0) {
    if (REC == '\n') {
        // do whatever you want with the array contents
        i =0;
        data[0] = 0;
    } else {
        data[i++] = REC;
    }
    REC = 0;
} 

También deberías comprobar que i nunca se hace demasiado grande y desborda tu matriz.

Un sistema aún mejor sería agregar el carácter entrante directamente a la matriz de datos en la rutina de interrupción. Cuando recibe un \n , establece un indicador para indicar al ciclo principal que es libre de usar el contenido de la matriz (no olvide borrar ese indicador cuando haya usado el contenido).

    
respondido por el Majenko

Lea otras preguntas en las etiquetas