Mikrocontroller sendet Datenmüll an Raspberry

Ich versuche, zwei Befehle seriell an meine Himbeere zu senden. Ich habe folgenden Code:

#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;
}

Und ich verwende das folgende 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

Beachten Sie, dass ich die Sicherungen so einstelle, dass sie die interne Uhr verwenden, also sollte sie mit 8 MHz laufen:

-U lfuse:w:0x62:m

Die CPU-Geschwindigkeit ist als 8 MHz definiert, die BAUD-Rate ist auf 9600 eingestellt, aber wenn ich den folgenden Befehl auf meiner Himbeere ausführe, sehe ich nur Müll:

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�▒������怘�

Ich möchte den Mikrocontroller nicht mit einem externen Oszillator betreiben. Kann ich die serielle Kommunikation trotzdem mit langsamen Raten verwenden, ohne sie zu verwenden?

Nun, was ist der Müll? Sie zeigen nur eine defekte UTF-8-Version.
Genau so sehe ich es im Terminal. Beziehen Sie sich auf den Hex-Dump der Ausgabe?
Ja, Sie können nichts von dieser Ausgabe debuggen. Wenn Sie kein Oszilloskop haben, müssen Sie zumindest einen Weg finden, um festzustellen, ob es sich um ein Baudratenproblem handelt oder nicht.
Ohne ein Oszilloskop ist die Entwicklung eingebetteter Systeme nicht möglich. Sie würden das Problem in weniger als einer Minute finden, wenn Sie nur die Baudrate messen.
@Lundin Wenn ich ein Oszilloskop hinzugefügt hätte, wie würde ich die Baudrate messen, die vom Mikrocontroller kommt? Kann Linux das erkennen?
Sie würden die Bitlänge messen. 9600 bps = 9600 Hz, was eine Bitlänge von 104 us ergibt. Grundschule Physik & Mathe. Viele Oszilloskope können jedoch die Frequenz messen und direkt in einfachen Zahlen ausgeben.

Antworten (2)

Ihr Problem besteht darin, dass Sie den Baudratendivisor für den "Doppelgeschwindigkeitsmodus" berechnen, diesen Modus jedoch nicht aktivieren, indem Sie Bit 1 von UCRS0A setzen, das standardmäßig auf 0 eingestellt ist. Dies bedeutet, dass der schlechte UART-Teiler im Einzelgeschwindigkeitsmodus arbeitet , für die Ihr Divisorwert doppelt so hoch ist wie er sein sollte. Somit arbeitet Ihre serielle Schnittstelle mit der halben beabsichtigten Geschwindigkeit.

Sie sollten entweder:

  • Dividieren Sie in Ihrer Divisorberechnung durch 16 und belassen/setzen Sie UCRS0A-Bit 1 auf dem Reset-Standard von gelöscht.

  • Teilen Sie in Ihrer Divisorberechnung durch 8 und setzen Sie explizit Bit 1 von UCRS0A.

Das seltsame Ändern der BAUD-Rate auf 4800 im Linux-Terminal löste das Problem:

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

Ich denke, die Sicherungen stellen den ATMEGA so ein, dass er mit 4 MHz und nicht mit 8 MHz läuft.

Das Problem ist nicht die Uhr, sondern eine Fehlkonfiguration des UART.
Obwohl das Testen der Baudraten um eine Zweierpotenz in der Tat ein großartiger Debugging-Instinkt war!