Microcontrolador enviando basura a la frambuesa

4

Estoy intentando 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 makefile:

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 de 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 baja velocidad sin usarlo?

    
pregunta 0x29a

2 respuestas

10

Su problema es que está calculando el divisor de velocidad en baudios para el "modo de doble velocidad" pero está descuidando habilitar ese modo al configurar el bit 1 de UCRS0A, que de manera predeterminada es 0. Esto significa que el divisor incorrecto de UART está operando 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ía:

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

  • Divide entre 8 en el cálculo de tu divisor y establece explícitamente el bit 1 de UCRS0A.

respondido por el Chris Stratton
3

El cambio inesperado de la tasa de BAUD a 4800 en el terminal de Linux solucionó 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 4MHZ no a 8MHZ.

    
respondido por el 0x29a

Lea otras preguntas en las etiquetas