Wie kann ich diesen Code beheben, damit mein AVR über den seriellen Port sprechen kann?

StackOverflow https://stackoverflow.com/questions/846206

  •  21-08-2019
  •  | 
  •  

Frage

Ich habe in letzter Zeit versucht, mir die Haare herauszuziehen, um einen ATMEGA162 auf meinem STK200 zu bekommen, um mit meinem Computer über RS232 zu sprechen. Ich habe überprüft und sichergestellt, dass der STK200 einen max202CPE -Chip enthält.

Ich habe den Chip so konfiguriert, dass er seinen internen 8 -MHz -Takt verwendet und ihn bis 8 geteilt hat.

Ich habe versucht, den Code aus dem Datenblatt zu kopieren (und Änderungen vorgenommen, bei denen sich der Compiler beschwert hat), aber ohne Erfolg.

Mein Code ist unten, könnte mir jemand helfen, die Probleme zu beheben, die ich habe?

Ich habe bestätigt, dass mein serieller Port auf anderen Geräten funktioniert und nicht fehlerhaft ist.

Vielen Dank!

#include <avr/io.h>
#include <avr/iom162.h>

#define BAUDRATE 4800

void USART_Init(unsigned int baud)
{
    UBRR0H = (unsigned char)(baud >> 8);
    UBRR0L = (unsigned char)baud;

    UCSR0B = (1 << RXEN0) | (1 << TXEN0);

    UCSR0C = (1 << URSEL0) | (1 << USBS0) | (3 << UCSZ00);
}

void USART_Transmit(unsigned char data)
{
    while(!(UCSR0A & (1 << UDRE0)));

    UDR0 = data;
}

unsigned char USART_Receive()
{
    while(!(UCSR0A & (1 << RXC0)));

    return UDR0;
}

int main()
{

    USART_Init(BAUDRATE);

    unsigned char data;

    // all are 1, all as output
    DDRB = 0xFF;

    while(1)
    {
        data = USART_Receive();

        PORTB = data;

        USART_Transmit(data);


    }
}
War es hilfreich?

Lösung 4

Nachdem ich das Datenblatt ein wenig gründlicher gelesen hatte, habe ich den Baudrate fälschlicherweise festgelegt. Das ATMEGA162 -Datenblatt enthielt ein Diagramm mit Taktfrequenzen, die gegen Baud -Raten und den entsprechenden Fehler aufgetragen wurden.

Für eine 4800 Baudrate und eine 1 -MHz -Taktfrequenz betrug der Fehler 0,2%, was für mich akzeptabel war. Der Trick bestand an der Funktion usart_init () anstelle von 4800.

Hoffe das hilft jemand anderem aus!

Andere Tipps

Ich habe Gregs Antwort kommentiert, möchte aber noch etwas hinzufügen. Für diese Art von Problem ist die Goldstandardmethode des Debuggens zuerst zuerst verstehe Asynchrone serielle Kommunikation, dann ein Oszilloskop zu bekommen und zu sehen, was auf der Linie passiert. Wenn Charaktere ausgetauscht werden und es sich nur um ein Baudrate -Problem handelt, ist dies besonders hilfreich, da Sie den Baudrate, den Sie sehen, berechnen können, und dann den Divisor entsprechend anpassen.

Hier ist eine super schnelle Grundierung, ohne Zweifel können Sie etwas viel umfassenderes für Wikipedia oder anderswo finden.

Nehmen wir 8 Bit, keine Parität, 1 Stoppbit (das häufigste Setup) an. Wenn dann das übertragene Zeichen 0x3f (= ascii '?') Ist, sieht die Linie so aus;

...--+   +---+---+---+---+---+---+       +---+--...
     | S | 1   1   1   1   1   1 | 0   0 | E
     +---+                       +---+---+

Der hohe (1) -Pegel beträgt +5 V am Chip und -12 V nach der Umwandlung auf RS232 -Werte.

Der niedrige (0) -Pegel beträgt 0 V am Chip und +12 V nach der Umwandlung auf RS232 -Pegel.

S ist das Startbit.

Dann haben wir 8 Datenbits, am wenigsten signifikant, also hier 00111111 = 0x3f = '?'

E ist das Stop (e für das Ende).

Die Zeit verläuft wie ein Oszilloskop -Display von links nach rechts.

Der Empfänger arbeitet, indem er die Linie probiert und nach einer fallenden Kante sucht (eine ruhende Linie ist einfach logisch '1' ständig). Der Empfänger kennt den Baudrate und die Anzahl der Startbits (1), sodass er eine halbe Bitzeit vom fallenden Rand misst, um die Mitte des Startbits zu finden, und dann die Linie 8 -Bit -Male danach nacheinander, um das zu sammeln Daten Bits. Der Empfänger wartet dann noch einmal Zeit (bis zur Hälfte des Stopbits) und beginnt nach einem weiteren Startbit (dh Falling Edge). In der Zwischenzeit wird dem Rest des Systems der Charakter -Lesen zur Verfügung gestellt. Der Sender garantiert, dass die nächste fallende Kante erst beginnt, wenn das Stoppbit abgeschlossen ist. Der Sender kann so programmiert werden, dass es immer länger wartet (mit zusätzlichen Stoppbits), aber dies ist ein älteres Problem. Zusätzliche Stoppbits wurden nur mit sehr langsamen Hardware und/oder Software -Setups benötigt.

Ich habe kein Referenzmaterial praktisch, aber das Baudrate -Register UBRR enthält normalerweise einen Divisorwert und nicht die gewünschte Baudrate selbst. EIN Schnelle Google -Suche Zeigt an, dass der richtige Divisorwert für 4800 Baud 239 betragen kann. Versuchen Sie also:

divisor = 239;
UBRR0H = (unsigned char)(divisor >> 8);
UBRR0L = (unsigned char)divisor;

Wenn dies nicht funktioniert, wenden Sie sich an die Referenzdokumente für Ihren bestimmten Chip für die korrekte Formel zur Berechnung des Divisors.

Zum Debuggen von UART -Kommunikation gibt es zwei nützliche Dinge zu tun:

1) Führen Sie einen Loop-Back am Anschluss durch und stellen Sie sicher, dass Sie das, was Sie schreiben, zurücklesen. Wenn Sie ein Zeichen senden und genau zurückbekommen, wissen Sie, dass die Hardware korrekt verkabelt ist und dass zumindest der Grundsatz der UART -Registerkonfiguration korrekt ist.

2) Senden Sie wiederholt das Zeichen 0x55 ("U") - Das Binärbitmuster 01010101 ermöglicht es Ihnen, die Bitbreite am Oszilloskop schnell zu sehen, mit der Sie überprüfen können, ob die Geschwindigkeitseinstellung korrekt ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top