La comunicación en serie de Uart no responde a Atmega16a

Soy nuevo en el avr (8bit uc) y recientemente me encontré con un problema al usar la comunicación en serie (uart) con la PC. El microcontrolador no responde en la terminal Putty, donde debería hacer eco de todo lo que he enviado.


Gracias por su respuesta a todos.

Lo siento por el código corrupto. No tenía idea de lo que estaba haciendo ya que soy un novato en esta sangría de código en el intercambio de pila.


El nuevo código se adjunta a continuación, por favor sugiera amablemente

#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>

volatile char data;

void USARTInit(uint16_t ubrr_value) {
    UBRRL = ubrr_value;
    UBRRH = (ubrr_value >> 8);
    UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
    UCSRB = (1 << RXEN) | (1 << TXEN);
}

void USARTWriteChar(char data) {
    while (!(UCSRA & (1 << UDRE)))
        { }

    //Now write the data to USART buffer
    UDR = data;                                                               
}                                                                             

void main() {                                                                 
    sei();                                                                    
    UCSRB |= (1 << RXCIE);                                                    
    USARTInit(51);                                                            

    while (1) {                                                               
        if (data == 'a') {                                                    
            USARTWriteChar(data);
        }
    }
}

ISR(USARTRXC_vect) {
    data = UDR;
}

así que aquí foo solo representa mis datos = 'a', desafortunadamente avr no responde a mis entradas. cuando escribo "a".

Bueno, ha comentado la línea que habría buscado datos de su UART, con la esperanza de que su interrupción funcione. Si utiliza el enfoque de sondeo en lugar de interrupciones, ¿tiene algún éxito?
@brhans Parece que está tratando de usar una interrupción para ello, pero es difícil saberlo con ese código mal formateado, y también parece truncado con eso if(data==1) }al final...
@Majenko Sí: el formato del código me engañó al principio y ese bit al final tampoco tiene ningún sentido.
@brhans lo he pasado por un estilo para limpiarlo un poco. Realmente destaca la parte del código roto...

Respuestas (1)

En primer lugar, ese código no se compilará. La última parte (el ISR) parece corrupta; es posible que desee volver a publicar esa parte.

En segundo lugar, no es de extrañar que si escribes "FOO" no responda, ya que el código está esperando a que presiones "a", momento en el que respondería con "[a][a][a][a] [a][a]..." hasta que presione algo más.

En tercer lugar, debe aprender a formatear su código correctamente, o al menos usar uno de los buenos formateadores automáticos, como Artistic Style.

Desafortunadamente, no tengo un ATMega16A aquí para probar su código, y no estoy al tanto de las interrupciones de Atmel, por lo que todo lo que puedo hacer es sugerir algunas cosas para probar:

  1. Asegúrese de que su código se esté ejecutando realmente y que la serie en sí esté funcionando: haga que imprima un mensaje de "Hola" al comienzo de su main()después de configurar el UART.
  2. Asegúrese de que la interrupción realmente se esté disparando; haga que se encienda un LED cuando se dispare la interrupción.
  3. Haz que parpadee otro LED como un "latido" en tu while(1)bucle principal para asegurarte de que no se atasque.

Editar: después de investigar y leer un poco (descubrí que las hojas de datos de Atmel están terriblemente mal escritas), descubrí que su vector de interrupción tiene un nombre incorrecto.

Esta página los enumera todos: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

Allí, después de un poco de exploración, puede encontrar que para el ATMega16, el vector RX debe nombrarse:

    USART_RXC_vect 

Después de cambiar el nombre, puedo ver en una descompilación que el ISR se instala correctamente en la tabla de vectores:

00000000 <__vectors>:
   0:   0c 94 2a 00     jmp 0x54    ; 0x54 <__ctors_end>
   4:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
   8:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
   c:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  10:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  14:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  18:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  1c:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  20:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  24:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  28:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  2c:   0c 94 5c 00     jmp 0xb8    ; 0xb8 <__vector_11>   // <-- ISR
  30:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  34:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  38:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  3c:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  40:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  44:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  48:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  4c:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  50:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>

... que no lo hizo antes.

También soy nuevo en los formatos de codificación, como sugirió sobre el estilo artístico, lo instalé en atmel studio 5.2 pero parece que no hay ninguna diferencia en el formato.
Nunca he usado Estilo Artístico de Atmel Studio. No sé si es compatible en absoluto en él. Solo lo uso como herramienta de línea de comandos, o desde mi propio IDE (UECIDE, que configuré especialmente para probar tu código).
La interrupción de uart que mencioné está funcionando en atmel studio 5.2 por alguna razón desconocida. Si doy la interrupción como usted mencionó, parece que me da un error como "MANEJADOR MISSTYPED"... y puedo recibir ambos TX/ RX, lo probé usando int en lugar de char... parece que tengo que usar (strcmp(x,y)==0)... gracias por tu problema amigo...