Recepción y decodificación del código X10 de Manchester

1

Resuelto: Después de mucha depuración, descubrí que era el UART que no funcionaba correctamente (no estoy seguro de por qué todavía) y que el puerto que solía encender los LED no funcionaba (PORTC). Así que nunca hubo ningún problema.

Pregunta original

Hola, estoy haciendo un proyecto en el que necesito enviar algunos datos a través de X10 desde un microcontrolador (específicamente un ATmega32) a otro microcontrolador (nuevamente un ATmega32). Ambos tienen una velocidad de reloj de 3.8646 MHz y se ejecutan en un STK500.

Parece que envío mis datos correctamente, pero mi decodificador parece tener problemas para decodificar los datos.

Primero, cuando recibo mis datos (1 byte) a través de X10, guardo todos los bits de Manchester en una matriz de caracteres sin signo (1/0 como startbit y el resto son datos). Luego guardo los datos en otra matriz char sin firmar (llamada búfer). Para propósitos de prueba, muestro esos datos en un terminal a través de UART. El código relevante se puede encontrar aquí.

unsigned char buffer[9];
index = 2;

for (int i = 0; i < BYTE; i++)
{
    // If bit 1 is received save that
    if (reciever[index] != 0 && reciever[index+1] == 0)
    {
        buffer[i] = 1;
        index += 2;
    }
    // If bit 0 is received save that
    else if (reciever[index] == 0 && reciever[index+1] != 0)
    {
        buffer[i] = 0;
        index += 2;
    }
    else
    break;
}

for (int i = 0; i < BYTE; i++)
{
    SendChar(buffer[i]);
}

mode = MODE_IDLE;

Esto parece funcionar, si, por ejemplo, el transmisor envía el decimal 150, el terminal muestra [120 0 0 120 0 120 120 0] (por alguna razón, '1' no se guardará como '1', pero '0 'se guardará como un' 0 '), lo que sugeriría que los datos se envían correctamente.

Sin embargo, si luego trato de decodificar el búfer a un único byte de caracteres, nunca obtendré lo que estaba destinado. En el siguiente código, guardo de nuevo los datos recibidos en un búfer y luego intento mostrarlos en un terminal y algunos LED en el STK500.

unsigned char buffer[9];
index = 2;

for (int i = 0; i < BYTE+1; i++)
{
    // If bit 1 is received save that
    if (reciever[index] != 0 && reciever[index+1] == 0)
    {
        buffer[i] = 1;
        index += 2;
    }
    // If bit 0 is received save that
    else if (reciever[index] == 0 && reciever[index+1] != 0)
    {
        buffer[i] = 0;
        index += 2;
    }
    else
    break;
}
unsigned char shifter = 0;
unsigned char byte = 0;
for (int i = 0; i < BYTE+1; i++)
{
    if (buffer[i] != 0)
    {
        shifter =  (1 << (BYTE - (i+1)));
        byte += shifter;

    }
    else if (buffer[i] = 0)
    {
        shifter = 0;
        byte += shifter;
    }
}
mode = MODE_IDLE;
SendChar(byte);
writeAllLEDs(byte);

En el terminal obtengo 128 y 120 y en el STK500 solo se encienden led7 y led1, lo que sugiere que mi descodificación está desactivada. Sin embargo, si intento depurar a través de Atmel Studio, la variable byte siempre sale con los valores correctos que he elegido.

Realmente podría usar algo de ayuda, porque no puedo entender qué está pasando.

writeAllLEDs ()

PORTC = ~pattern; 

SendChar ()

 // Wait for transmitter register empty (ready for new character)
  while ( (UCSRA & (1<<5)) == 0 )
  {}
  // Then send the character
  UDR = Tegn;

EDIT 1: No parece haber ningún problema al llenar el búfer.

Estoy llenando la matriz del receptor en ISR cuando Timer2 se desborda:

// Stop Timer2
    TCCR2 = 0;
    TCNT2 = 24;

    if (mode == MODE_IDLE)
    {
        if (PIND & (1 << PD6))
        {
            reciever[index++] = 1;
        }
        else if (PIND & ~(1 << PD6))
        {
            if (reciever[0] == 1)
            {
                reciever[index++] = 0;
                mode = MODE_RECEIVING;
            }
        }
    }
    else if (mode == MODE_RECEIVING)
    {
        if (PIND & (1 << PD6))
        {
            reciever[index++] = 1;

            if (index == 19) mode = MODE_RECEIVED;
        }
        else if (PIND & ~(1 << PD6))
        {
            reciever[index++] = 0;

            if (index == 19) mode = MODE_RECEIVED;
        }
    }

EDIT 2: se olvidó de agregar cómo se declaran los valores del receptor, índice. Ellos por supuesto globales:

volatile unsigned char mode = MODE_IDLE;
volatile unsigned int reciever[19] = {0};
volatile unsigned int index = 0;
    
pregunta Mikkel Poulsen

0 respuestas

Lea otras preguntas en las etiquetas