Comunicación serial en Atmega128

0

Quiero enviar algunas cadenas a la PC a través del puerto serie. En cute com (software) se muestra la cadena pero faltan algunos caracteres. También algunos números hexadecimales se agregan al principio y al final de la cadena. ¿Cual podría ser el problema? ¿Alguien por favor puede ayudar a resolver este problema. Mi código está aquí.

#include <avr/io.h>  
#include <string.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
#include <util/delay.h>    
#define USART_BAUDRATE 9600    // Baud Rate value
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
void usart_init() {

//Enable communication in duplex mode
UCSR1A = (1 << U2X1);
UCSR1B |= (1 << RXEN1) | (1 << TXEN1);// Turn on the transmission and   reception circuitry
UCSR1C &= ~(1 << UMSEL1);
UCSR1C |= (1<<USBS1) | (1 << UCSZ10) | (1 << UCSZ11);

 UBRR1L = BAUD_PRESCALE;// Load lower 8-bits of the baud rate value into the low byte of the UBRR register
 UBRR1H = (BAUD_PRESCALE >> 8);          // Load upper 8-bits of the baud rate value.. 
 }

 void serial_write(unsigned char data) {

  while(!(UCSR1A & (1<<UDRE1)))
  ;
  UDR1 = data;
  _delay_ms(10);
 }

 void transmitString(unsigned char *str) {

 int i;
 for(i=0;i<strlen(str);i++) {
  serial_write(str[i]);
  _delay_ms(1);
 }
 }

 int main() {
    cli();
    usart_init();
    unsigned char buffer[20];
    strcpy(buffer, "Walk Alone");
    while(1) {  
    transmitString(buffer);
    //_delay_ms(250);
  }
   return 0;
  }
    
pregunta Sanju

3 respuestas

1

Según mi lectura de su código y la hoja de datos, hay dos problemas:

Dos bits de parada

El código aquí probablemente no es lo que quieres:

UCSR1C |= (1<<USBS1) | (1 << UCSZ10) | (1 << UCSZ11);

Esto establece 2 bits de parada (valor de USBS1 == 1). Probablemente quieras una parada. Yo usaría una construcción como esta:

UCSR1C = (0<<USBS1) | (0 << UCSZ12) | (1 << UCSZ11) | (1 << UCSZ10);

solo para dejar muy claro lo que estás haciendo.

Velocidad de transmisión

Según mis cálculos, su BAUD_PRESCALE es 16000000/9600 * 16-1 = 26666 . De acuerdo con la hoja de datos, para 9600 con U2X1 establecido, los registros UBRR ( L y H ) deben configurarse en 207 . En mi opinión, no está configurando la velocidad de transmisión correctamente.

Una nota sobre interrupciones

En respuesta a las David Norman 's comment acerca de las interrupciones (creo que lo que significa que hay interrupciones sería más fácil), me permito disentir.

  • De todos modos, para mí, el sondeo es más fácil de implementar
  • Para muchas tareas AVR, (como los envíos SPI), se ha encontrado que el sondeo es más rápido que las comunicaciones controladas por interrupciones: probablemente debido a la alta sobrecarga relativa de los saltos (tener que tocar la pila), habilitando / deshabilitando los bits de interrupción, etc.

Como David Norman señala, si la duración de la batería es una preocupación, entonces las comunicaciones controladas por interrupciones pueden Ser una mejor solución.

    
respondido por el angelatlarge
0

Soltaría Cute Com de inmediato y cambiaría a algo como Termite . Por lo general, cuando se eliminan caracteres (me ha pasado muchas veces) es porque el programa de terminal usa la clase .NET SerialPort que convierte los datos recibidos a ASCII y luego los traduce a lo que el usuario desee. En su lugar, debe utilizar un programa que use Win32API directamente (es decir, Termite). Puede elegir mostrar en binario, ASCII o hexadecimal sin preocuparse en absoluto. Cambié el año pasado y nunca volvería (después de pasar 2 semanas depurando algo que no estaba roto).

    
respondido por el tmwoods
-1

Estaba enfrentando el mismo problema cuando intentaba enviar una cadena a mi pantalla LCD en serie usando mega128. El problema era que el reloj del sistema era demasiado rápido en comparación con la velocidad a la que se transfieren los bytes.

Primero comente su velocidad en baudios en el código de su programa.

En segundo lugar, no utilice retrasos en su función en lo que respecta a la comunicación en serie.

En tercer lugar, para solucionar problemas de uso de puntos de interrupción donde su código envía datos que serían UDR1 = data; . Observe en el otro lado si está recibiendo cada personaje. Esto es para garantizar que su controlador serial esté funcionando correctamente.

Cuarto, ya que no está utilizando interrupciones (lo cual será mucho más fácil de manejar), verifique cuando el búfer esté vacío para un nuevo byte, así como también verifique si el indicador está borrado (creo que ya lo hizo, No estoy revisando la hoja de datos).

    
respondido por el David Norman

Lea otras preguntas en las etiquetas