Microcontrolador enviando basura a Raspberry

Estoy tratando de enviar dos comandos a mi frambuesa en serie. Tengo el siguiente código:

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

#define F_CPU 8000000UL
#define BAUD  9600

int main( void ) 
{
    // BAUD RATE (bits per second)
    UBRR0 = ( ( F_CPU / 8 / BAUD ) - 1 ); // 01100111

    // CONFIGURATION REGISTERS
    UCSR0B = 0b00001000; // enable transmitter (TXEN0)
    UCSR0C = 0b00000110; // set 8-bit data frame size  

    char buf[2][222] = 
            {
                { "AT" },
                { "AT+CWSAP=\"AVRAP\",\"abcd\",11,0" }
            };

    int i = 0;
    int x = 0;

    while( 1 )
    {

        if( x == sizeof( buf ) )
        {
            break;
        }

        if( i<strlen( buf[ x ] ) )
        {
            UDR0 = buf[x][i];
            i++;
        }
        else
        {
            UDR0 = 13;
            UDR0 = 10;
            x++;
            i = 0;

            _delay_ms( 10000 );
        }


        _delay_ms( 50 );
    }

    return 0;
}

Y estoy usando el siguiente archivo MAKE:

CC=/usr/bin/avr-gcc
MEGA=328p
CFLAGS=-g -Os -Wall -mcall-prologues -mmcu=atmega$(MEGA)
OBJ2HEX=/usr/bin/avr-objcopy 
PROG=/usr/bin/avrdude
TARGET=serial

program : $(TARGET).hex
        $(PROG) -c avrispv2 -p m$(MEGA) -P /dev/ttyACM0 -e -U lfuse:w:0xe2:m -U hfuse:w:0xd9:m
        $(PROG) -c avrispv2 -p m$(MEGA) -P /dev/ttyACM0 -U flash:w:$(TARGET).hex

%.obj : %.o
        $(CC) $(CFLAGS) $< -o $@

%.hex : %.obj
        $(OBJ2HEX) -R .eeprom -O ihex $< $@

clean :
        rm -f *.hex *.obj *.o

Tenga en cuenta que estoy configurando los fusibles para usar el reloj interno, por lo que debería funcionar a 8Mhz:

-U lfuse:w:0x62:m

La velocidad de la CPU se define como 8Mhz, la tasa BAUD se establece en 9600, pero cuando ejecuto el siguiente comando en mi frambuesa, todo lo que veo es basura:

picocom /dev/ttyAMA0 -b 9600


picocom v1.7

port is        : /dev/ttyAMA0
flowcontrol    : none
baudrate is    : 9600
parity is      : none
databits are   : 8
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv
imap is        : 
omap is        : 
emap is        : crcrlf,delbs,

Terminal ready
�`�怘��`枆�~������▒�x�x�x�x�x�x�▒��▒�x�x�x�▒������怘�

No quiero ejecutar el microcontrolador con un oscilador externo, ¿puedo seguir usando la comunicación en serie a velocidades lentas sin usarla?

Bueno, ¿qué es la basura? Solo muestra una versión rota de UTF-8.
Así es exactamente como lo veo en la terminal. ¿Te refieres al volcado hexadecimal de la salida?
Sí, no puede depurar nada de esa salida. Si no tiene un osciloscopio, debe encontrar al menos alguna forma de identificar si se trata de un problema de velocidad de transmisión o no.
No se puede trabajar con el desarrollo de sistemas integrados sin un osciloscopio. Encontraría el problema en menos de un minuto si solo mide la velocidad en baudios.
@Lundin si agrego un osciloscopio, ¿cómo mediría la velocidad en baudios proveniente del microcontrolador? ¿Linux puede detectar eso?
Medirías la longitud del bit. 9600 bps = 9600 Hz lo que da una longitud de bit de 104us. Física y matemáticas de primaria. Aunque muchos osciloscopios pueden medir la frecuencia y generarla directamente en números simples.

Respuestas (2)

Su problema es que está calculando el divisor de velocidad en baudios para el "modo de doble velocidad", pero no habilitó ese modo configurando el bit 1 de UCRS0A, que por defecto es 0. Esto significa que el divisor UART defectuoso está funcionando en modo de velocidad única , para el cual el valor de su divisor es el doble de lo que debería ser. Por lo tanto, su puerto serie funciona a la mitad de la velocidad prevista.

Deberías:

  • Divida por 16 en el cálculo de su divisor y deje/establezca el bit 1 de UCRS0A en el reinicio predeterminado de borrado.

  • Divida por 8 en el cálculo de su divisor y establezca explícitamente el bit 1 de UCRS0A.

Extrañamente, cambiar la tasa de BAUD a 4800 en la terminal de Linux resolvió el problema:

picocom /dev/ttyAMA0 -b 4800
picocom v1.7

port is        : /dev/ttyAMA0
flowcontrol    : none
baudrate is    : 4800
parity is      : none
databits are   : 8
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv
imap is        : 
omap is        : 
emap is        : crcrlf,delbs,

Terminal ready
AT
AT+CWSAP="AVRAP","abcd",11,0

Supongo que los fusibles están configurando el ATMEGA para que funcione a 4 MHz, no a 8 MHz.

El problema no es el reloj, sino la mala configuración de la UART.
¡Aunque probar las tasas de baudios con una potencia de dos fue realmente un gran instinto de depuración!