Hallo,
ich habe hier gerade einen Atmega32u2 vor mir liegen. Ich benötige sein
SPI-Protokoll über den USART, um eine SPI-Kette ansteuern zu können.
Ich arbeite dabei mit gcc avr und einer Makefile unter Codelite unter
Linux.
Die Konfiguration der SPI-Protokolls klappt jedoch nicht, da der
Compiler die Registernamen (z.B. UBRRn, XCKn_DDR, UCSRnC etc.) nicht
auflösen kann. Alle Standards wie PORTx, DDRx, Timer und andere kann er
auflösen.
Ist das ein bekanntes Problem oder mache ich etwas falsch? Angeblich
soll der Atmega32u2 von avr-libc unterstützt werden.
Ich wäre sehr dankbar für einen kleinen Hinweis
Mit Gruß
Mike
Mike schrieb:> da der> Compiler die Registernamen (z.B. UBRRn, XCKn_DDR, UCSRnC etc.) nicht> auflösen kann.
Richtiger Include-File für den Prozessor?
Auch im Makefile den richtigen Prozessor gesetzt?
Ohne Deinen Code und Makefile ist das alles nur Glaskugel.
Hallo,
vielen Dank für deine Antwort.
Den gesamten Code anzuhängen dürfte schwierig werden. Der Fehler lässt
sich aber sehr gut einschränken und vielleicht ist das ja ein bekannter
Bug oder eine bekannte Problematik.
Die USART-Init wurde 1:1 von Atmel übernommen. Da steht grob (wegen
Urheberrechts...)
void Init( void )
{
UBRRn = 0;
XCKn_DDR |= (1<<XCKn);
UCSRnC = (1<<UMSELn1)|(1<<UMSELn0);
UCSRnB = (1<<RXENn)|(1<<TXENn);
UBRRn = foo;
}
keine Registerbezeichnung wird beim build aufgelöst.
In der Makefile steht
MCU = atmega32u2
diese ist laut avr-libc auch so definiert.
Was genau meinst du mit: Include-File für den Prozessor? Ich habe die
io.h, interrupt.h und stdlib.h included. Gibt es da noch was
prozessorspezifisches?
Der Rest funktioniert. Nur die Register für die USART-Konfiguration für
SPI will nicht erkannt werden. Und ich möchte nicht wegen nur eines
Chips wieder zu Win zurück :(
Gruß
Mike
Das kleine n steht im Atmel-Code als Platzhalter für die UART Nummer.
Also 0 falls der Chip mindestens eine UART hat, 1 falls es noch eine
zweite gibt.
Hi
>Das kleine n steht im Atmel-Code als Platzhalter für die UART Nummer.>Also 0 falls der Chip mindestens eine UART hat, 1 falls es noch eine>zweite gibt.
Es gibt aber auch AVRs bei denen gibt es nur eine USART und die heißt
auch so. Und die Register nennen sich dann auch nur UBRR, UDR, UCSRA,
UCSRB ... .
Dazu gehört auch der Atmega32u2.
MfG Spess
spess53 schrieb:> Es gibt aber auch AVRs bei denen gibt es nur eine USART und die heißt> auch so
Die heissen dann nicht ...1.., obwohl lt. Pinout so bezeichnet?
Hatte ich noch nicht, deshalb frage ich ...
Hi
>Die heissen dann nicht ...1.., obwohl lt. Pinout so bezeichnet?>Hatte ich noch nicht, deshalb frage ich ...
Das trifft auf ältere AVRs (z.B. ATMega8/16/32) zu. Und im Pinout taucht
auch keine USART-Nummer auf.
Beim Atmega32u2 muss ich mich allerdings korregieren. Dort heißt die
USART wirklich USART1 und die Register UDR1, UCSR1A, UCSR1B, UCSR1C,
UCSR1D, UBRR1H und UBRR1L.
MfG Spess
Hallo,
das mit den "n" war mir bekannt. Nur leider die exakte Nummerierung
nicht.
Mittlerweile frisst der Compiler nun einen Teil des Codes. Exakt:
UBRR1 = 0;
DDRD |= (1 << PD5);
UCSR1C |= (1 << UMSEL11) | (1 << UMSEL10);
UCSR1B |= (1 << RXEN1) | (1 << TXEN1);
UBRR1 = foo;
Und so ganz vollständig scheint das alles auch nicht zu sein. So
existiert das angegebene Register XCKn_DDR wohl gar nicht. Der Versuch,
den Pin als Ausgang zu deklarieren "DDRD |= (1 << PD5)" bringt leider
keinen Effekt. Der µC schreibt nun zwar auf dem USART einzelne Bytes
aus, erzeugt dazu aber kein XCK-Signal. Der Pegel bleibt kostant auf
high.
Einen Schluss gegen GND oder Versorgung habe ich ausgeschlossen.
Hat einer einen Hinweis?
Mit Gruß
Mike
Mike schrieb:> Mittlerweile frisst der Compiler nun einen Teil des Codes. Exakt:>> UBRR1 = 0;> DDRD |= (1 << PD5);> UCSR1C |= (1 << UMSEL11) | (1 << UMSEL10);> UCSR1B |= (1 << RXEN1) | (1 << TXEN1);>> UBRR1 = foo;>> Und so ganz vollständig scheint das alles auch nicht zu sein.
Doch, das ist es. Nur leider nicht korrekt. In Zeile 2 und 3 mußt du den
Zuweisungsoperator "=" verwenden und nicht "|=".
Ok, ich hatte mir gespart das DB des Atmega32u2 anzuschauen.
Ich benutze im Normalfall Eclipse mit AVR-Plugin, da schreibe ich
einfach UBBR und bekomme angezeigt welche es wirklich gibt. (muß ich
noch SHIFT SPACE drücken? Erlich, ich weiß es nicht, das machen meine
Fingenr vermutlich schon automatisch. Und hier auf dem Apfelbrett kann
ich's nicht ausprobieren)
Und wenn man Code hat, der auf verschiedenen AVR's laufen muß, dann kan
man per #if(def) abprüfen welches es aktuell ist. Oder man definiert es
gleich auf den gewünschten Namen um.
Mike schrieb:> UBRR1 = foo;
Was steht denn in "foo" ?
Mike schrieb:> So existiert das angegebene Register XCKn_DDR wohl gar nicht.
Die Transferleitung, das "n" durch eine "1" zu ersetzen hast Du
geleistet?
Ich vermute mal, wenn Du das gemacht hast wird es auch erkannt.
Der Pin muss als Ausgang geschaltet sein, das sonst auf einen externen
Takt vom "slave" gewartet wird (so zumindest deute ich das Datenblatt -
dessen Lektüre nicht dümmer macht ...)
Mike schrieb:> Ist das ein bekanntes Problem
Es ist ein bekanntes Problem, dass man aus dem Datenblatt nicht nur
irgendwas herauskopieren, sondern die Zeilen davor und danach noch
lesen und verstehen sollte...
> oder mache ich etwas falsch?
Du verwendest Code ohne ihn zu verstehen.
Mike schrieb:> Und ich möchte nicht wegen nur eines Chips wieder zu Win zurück :(
Diesen Satz möchte ich mir nochmal auf der Zunge zergehen lassen.
Du solltest versuchen, die Toolchain zu verstehen. Es sind nur ein
paar Textdateien, die das Verhalten des Controllers und das darauf
laufende Programm beschreiben. Die kann man öffenen und zur Not darin
editieren. Wenn dieser eine Chip tatsächlich nicht unerstützt werden
würde, dann könnte man sich dort die fehlenden paar Register einfach
definieren. Denn das sind nur Buchstabenhaufen, keine
Naturkonstanten...
Mike schrieb:> So existiert das angegebene Register XCKn_DDR wohl gar nicht.
Auch das ist nur ein Buchstabenhaufen, der von dieser "n" Thematik
zusätzlich betroffen ist. Wenn du da mal eine 1 einsetzt und dann Google
bemühst (https://www.google.de/search?q=XCK1_DDR), dann findest du raus,
dass damit nur ein define für ein Richtungsregister gemeint ist, also
z.B. #define XCK1_DDR DDRD