Cómo puedo solucionar este código para permitir que mi AVR para hablar sobre el puerto serie?

StackOverflow https://stackoverflow.com/questions/846206

  •  21-08-2019
  •  | 
  •  

Pregunta

He estado tirando de mi pelo últimamente tratando de conseguir un ATmega162 en mi STK200 a hablar con mi equipo a través de RS232.He comprobado y asegúrese de que el STK200 contiene un MAX202CPE chip.

He configurado el chip para utilizar su sistema interno de 8MHz reloj y se divide por 8.

He intentado copiar el código de la hoja de datos (y de hecho de los cambios que el compilador se quejó), pero fue en vano.

Mi código es el siguiente, podría por favor alguien me ayude a solucionar los problemas que estoy teniendo?

He confirmado que mi puerto serie funciona en otros dispositivos y no es defectuoso.

Gracias!

#include <avr/io.h>
#include <avr/iom162.h>

#define BAUDRATE 4800

void USART_Init(unsigned int baud)
{
    UBRR0H = (unsigned char)(baud >> 8);
    UBRR0L = (unsigned char)baud;

    UCSR0B = (1 << RXEN0) | (1 << TXEN0);

    UCSR0C = (1 << URSEL0) | (1 << USBS0) | (3 << UCSZ00);
}

void USART_Transmit(unsigned char data)
{
    while(!(UCSR0A & (1 << UDRE0)));

    UDR0 = data;
}

unsigned char USART_Receive()
{
    while(!(UCSR0A & (1 << RXC0)));

    return UDR0;
}

int main()
{

    USART_Init(BAUDRATE);

    unsigned char data;

    // all are 1, all as output
    DDRB = 0xFF;

    while(1)
    {
        data = USART_Receive();

        PORTB = data;

        USART_Transmit(data);


    }
}
¿Fue útil?

Solución 4

Después de leer la hoja de datos un poco más a fondo, yo estaba sentado de forma incorrecta la velocidad de transmisión. La hoja de datos ATmega162 tenía un gráfico de frecuencias de reloj representa frente a velocidades de transmisión y el error correspondiente.

Para una velocidad de transmisión 4800 y una frecuencia de reloj de 1 MHz, el error fue del 0,2%, que era aceptable para mí. El truco pasaba 12 a la función USART_Init (), en lugar de 4800.

Espero que esto ayude a alguien más fuera!

Otros consejos

He comentado en la respuesta de Greg, pero me gustaría añadir una cosa más. Para este tipo de problema el método estándar de oro de la depuración es a primera entienden asíncronos las comunicaciones serie, para obtener un osciloscopio y ver lo que está sucediendo en la línea. Si los caracteres se intercambian y es sólo un problema de velocidad de transmisión que será particularmente útil como se puede calcular la velocidad de transmisión que están viendo y luego ajustar el divisor en consecuencia.

He aquí un resumen muy rápido, sin duda, se puede encontrar algo mucho más amplio en la Wikipedia o en otro lugar.

Vamos a suponer 8 bits, sin paridad, 1 bit de parada (la configuración más común). ( '?' = Ascii) Entonces, si el carácter que se transmite es decir 0x3f, entonces la línea se parece a esto;

...--+   +---+---+---+---+---+---+       +---+--...
     | S | 1   1   1   1   1   1 | 0   0 | E
     +---+                       +---+---+

La alta (1) nivel es + 5V en el chip y -12V después de la conversión a niveles RS232.

El (0) bajo nivel es 0V en el chip y + 12V después de la conversión a niveles RS232.

S es el bit de inicio.

A continuación, tenemos 8 bits de datos, menos significativo en primer lugar, por lo que aquí 00.111.111 = 0x3f = '?'.

E es el tope (E final) bits.

Tiempo está avanzando de izquierda a derecha, como una pantalla de osciloscopio, Si la velocidad de transmisión es 4800, entonces cada bit vanos (1/4800) segundos = 0,21 milisegundos (aproximadamente).

Las obras receptor mediante el muestreo de la línea y en busca de un flanco de bajada (una línea de reposo es simplemente lógico '1' todo el tiempo). El receptor conoce la velocidad de transmisión, y el número de bits de arranque (1), por lo que mide un tiempo medio bit desde el flanco de bajada de encontrar el medio del bit de inicio, a continuación, las muestras de los tiempos de bit línea 8 en la sucesión después de eso para recoger el bits de datos. Después, el receptor espera un poco más de tiempo (hasta medio camino a través del bit de parada) y empieza a buscar otro bit de inicio (es decir, el flanco descendente). Mientras tanto, el carácter leído se pone a disposición del resto del sistema. El transmisor garantiza que el próximo flanco de bajada no comenzará hasta que el bit de parada es completa. El transmisor puede ser programado para esperar siempre más larga (con bits de parada adicionales), sino que es un problema heredado, bits de parada adicionales solamente se requiere con hardware muy lento y / o configuraciones de software.

no tengo material de referencia útil, pero el registro UBRR velocidad de transmisión por lo general contiene un valor divisor, en lugar de la propia velocidad de transmisión deseada. Un rápida búsqueda en Google indica que el valor correcto para el divisor 4800 baudios puede ser 239. Por lo tanto Proveedores:

divisor = 239;
UBRR0H = (unsigned char)(divisor >> 8);
UBRR0L = (unsigned char)divisor;

Si esto no funciona, comprobar con los documentos de referencia para su chip en particular para la fórmula de cálculo divisor correcta.

Para la depuración de la UART de comunicación, hay dos cosas que hacer:

1) Hacer un bucle en el conector y asegúrese de que puede leer lo que usted escribe.Si usted envía un personaje y volver exactamente, usted sabe que el hardware está conectado correctamente, y que, al menos, el conjunto básico de UART registro de configuración es correcta.

2) las veces que enviar el carácter 0x55 ("U") - el binario patrón de bits 01010101 le permitirá ver rápidamente el ancho de bits en el osciloscopio, el cual permitirá verificar que la velocidad de ajuste es correcto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top