4 votos

Xbee no respuesta oportuna. Gran retardo entre cada transmisión

He preparado un programa de instalación para 2 Xbees uno conectado a la PC a través de XCTU y el otro interconectado con el Atmega 168. El software del terminal pondrá a " 1 " y el xbee con Atmega 168 devolverá 1.

El código es como sigue.

#include<avr/io.h>
#include<avr/interrupt.h>
#include<util/delay.h>

    unsigned char data; //to store received data from UDR1



//Function To Initialize UART0
// desired baud rate:9600
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
 UCSR0B = 0x00; //disable while setting baud rate
 UCSR0A = 0x00;
 UCSR0C = 0x06;
 UBRR0L = 0x06; //set baud rate lo
 UBRR0H = 0x00; //set baud rate hi
 UCSR0B = 0x98;
}


ISR(USART_RX_vect)      // ISR for receive complete interrupt
{
    data = UDR0;  //making copy of data from UDR0 in 'data' variable 
    if(data == 0x31)
    UDR0 = data;                //echo data back to PC

}

//Function To Initialize all The Devices
void init_devices()
{
 cli(); //Clears the global interrupts
 uart0_init(); //Initailize UART0 for serial communiaction
 sei();   //Enables the global interrupts
}

//Main Function
int main(void)
{
    init_devices();
    while(1);
}

Este código funciona bien, y la siguiente es la deseada y la obtenida a la salida...

enter image description here

Ahora, el problema es cuando quiero obtener respuesta 3 para una transmisión de 3 desde la PC. Yo estoy usando el avr studio 4 (sí, yo sé que yo estoy con efecto retroactivo) y Atmega 168PA-PU. La configuración para ambos casos es como se muestra en la imagen...

enter image description here

Así que he copiado el programa anterior totalmente y sólo cambió la línea de

ISR(USART_RX_vect)      // ISR for receive complete interrupt
{
    data = UDR0;  //making copy of data from UDR0 in 'data' variable 
    if(data == 0x31)
    UDR0 = data;                //echo data back to PC

}

para el siguiente

ISR(USART_RX_vect)      // ISR for receive complete interrupt
{
    data = UDR0;  //making copy of data from UDR0 in 'data' variable 
    if(data == 0x33)
    UDR0 = data;                //echo data back to PC

}

Pero el obtenido de salida está en ninguna parte cerca de lo que su supone que debe ser. En la siguiente imagen se debe aclarar.

enter image description here

PS: Hemos utilizado separado (Atmega 168-PU & Atmega 168PA-PU) para los dos programas. Puede ocurrir que hay una cierta discrepancia en el oscilador interno. En algún sitio he leído que puede ser un +/-10% de la imprecisión.

2voto

xilun Puntos 261

No estoy 100% seguro de que esto solucione tu problema, pero normalmente antes de enviar los datos que usted quiere comprobar que el transmisor de la celebración de registro está vacío antes de que el envío de un personaje. Usted podría intentar esto:

ISR(USART_RX_vect)      // ISR for receive complete interrupt
{
    data = UDR0;  //making copy of data from UDR0 in 'data' variable 
    if(data == 0x33)
    {
        while(!(UCSR0A & (1 << UDRE0))) // Wait for data register to be empty
            ;
        UDR0 = data;                //echo data back to PC
    }
}

Pero haciendo la espera en el interior de la interrupción puede causar que usted pierda caracteres recibidos. En su lugar me gustaría hacer normalmente algo más parecido a esto:

volatile unsigned char data, got_data;
unsigned char buffered_data;

ISR(USART_RX_vect)      // ISR for receive complete interrupt
{
    data = UDR0;  //making copy of data from UDR0 in 'data' variable 
    got_data = 1;
}

int main(void)
{
    init_devices();
    while (1)
    {
        if (got_data)
        {
            // Ideally you should disable interrupts here
            buffered_data = data;
            got_data = 0;
            // And re-enable interrupts here
            if (buffered_data == 0x33)
            {
                while(!(UCSR0A & (1 << UDRE0))) // Wait for data register to be empty
                    ;
                UDR0 = buffered_data;                //echo data back to PC
            }
       }
    }
}

También me di cuenta de que su adición sobre el reloj de tener un potencial innacuracy de +/- 10%, lo que es un poco grande para una comunicación fiable. Mientras que normalmente objetivo de 2% de precisión cuando se utiliza de serie de comunicaciones que usted debe apuntar para menos de un 5%, de lo contrario usted puede aproximadamente la mitad un poco por el final de 10 bits.

0voto

Tatu Lahtela Puntos 2876

Este problema no es con respecto a su software, porque corrió el mismo programa en los dos casos? Así que debe ser de hardware. La irregularidad en el 2º caso sugiere que hay algo de velocidad en baudios de desajuste. Por tanto, concluyo que el problema es, sin duda debido a la interna RC osciladores que no son exactos como usted menciona a sí mismo.

Trate de usar externa del oscilador de cuarzo. Conectar con XTAL1 Y XTAL2 con adecuado de los condensadores. Yo personalmente uso 12 mhz con tapas de 22pF. Cambiar el fusible de la configuración antes de grabar el programa. Intente buscar en Google avrdude fusible de la calculadora.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X