Ein Sensor mit 3.3V soll am SparkFun ProMicro-Board (3.3V 8MHz) mit atmega32u4-CPU angeschlossen werden. Das SparkFun ProMicro-Board meldete sich im Auslieferungszustand im Gerätemanager als "USB IO-Board" und nach Laden des Treibers per inf-Datei als "SparkFun Pro Micro (COM11)". Der Bootloader meldet sich mit "SparkFun Pro Micro bootloader (COM12)". So weit so gut. Das Anwender-Programm ist ein C-Code-Beispiel von PJRC das auf einem ProMicro-Board mit 5V 16MHz bereits lief. Der Treiber dazu wurde installiert. Zur Anpassung der 16MHz auf 8MHz wurden Anpassungen gemacht im Makefile, main.c, delay.h, usb_serial.h. Der Upload per Bootloader, AVRDUDE klappt. Nur erscheint dann eine Meldung "USB-Gerät wurde nicht erkannt" und unter USB-Controller ist ein "Unknown Device" wo keinerlei VID/PID angezeigt wird. Der Fehler scheint im C-Code zu liegen, nur wo. Der Prescaler stand für 16MHz auf: PLL_CONFIG() (PLLCSR = 0x12). Für 8MHz habe ich umgestellt auf: #define PLL_CONFIG() (PLLCSR = 0x02). Vielleicht hat jemand einen Hinweis um das Problem zu beheben.
Musste man bei der USB Hardware nicht auch ein Bit umsetzen wenn man von 16 auf 8 MHz umstellt? Ist leider eine Weile her dass ich Atmega32U am USB programmiert habe, kann mich also auch irren. Für USB muss eine Menge funktionieren: Takt, Pins, USB/EP0 Interrupt Handler.
Jim M. schrieb: > Musste man bei der USB Hardware nicht auch ein Bit umsetzen wenn man von > 16 auf 8 MHz umstellt? Laut Datenblatt 32u4 sollte die PLL mit 8MHz gefüttert werden um daraus 48MHz für USB zu erzeugen. PJRC betrieb den Teensy mit 16MHz, egal ob 5V oder 3.3V. Daher sah sein Code keine Umstellung auf 8MHz vor. Aufgrund Quarz 8MHz muss der Teiler/2 für PLL raus. Das sollte die Zeile #define PLL_CONFIG() die ich auf (PLLCSR = 0x02) geändert habe bewirken. Es kann ggf. sein dass diese Änderung nicht in einem Schritt geht, so wie PJRC das im Code zeigt. Dann müsste das angepasst werden. > Für USB muss eine Menge funktionieren: Takt, Pins, USB/EP0 Interrupt > Handler. ja. Keine Ahnung wo da noch etwas anzupassen ist.
1 | CLKPR = (0<<CLKPS1) | (0<<CLKPS0); // CPU laeuft mit 16 MHz falls 16MHz-Quarz |
2 | // CPU laeuft mit 8 MHz falls 8MHz-Quarz
|
was soll da passieren? Beschreib mal was du machen willst. Der Code setzt jedenfalls CLKPR= 0x00. Ich bin mir ziemlich sicher, dass du das nicht willst.
Thomas Z. schrieb: > was soll da passieren? Beschreib mal was du machen willst. Danke für den Hinweis Thomas. Diese Zeile ist hier unnötig, sie dient mir als Merker wenn man Prescaler >1 nutzen will. Laut Datenblatt Atmega328p S.38 ist der Clock Division Factor so 1. Mit 16MHz Quarz wird die CPU also mit 16MHz getaktet. Da hier ein 8MHz Quarz da ist wird die CPU mit 8MHz getaktet was nach Datenblatt bei 3.3V Sinn macht.
Dein Pll Macro ist für den atmega32u4 falsch.
1 | #elif defined(__AVR_ATmega32U4__)
|
2 | ...
|
3 | #define PLL_CONFIG() (PLLCSR = 0x12)
|
4 | ...
|
When using a 8MHz clock source, this bit must be set to 0 before enabling PLL (1:1)
Thomas Z. schrieb: > Dein Pll Macro ist für den atmega32u4 falsch. Danke Thomas ! oben hatte ich noch geschrieben: Der Prescaler stand für 16MHz auf: PLL_CONFIG() (PLLCSR = 0x12). Für 8MHz habe ich umgestellt auf: #define PLL_CONFIG() (PLLCSR = 0x02). diese Änderung hatte ich leider im falschen Ordner gemacht, so dass diese nicht wirksam werden konnte. Ohne Dich hätte ich das nicht gefunden weil so nicht vermutet.
Matthias W. schrieb: > #define PLL_CONFIG() (PLLCSR = 0x02) ich bin mir nicht mal sicher ob das korrekt ist. Im Datenblatt steht ja "before enabling PLL"
Thomas Z. schrieb: > ich bin mir nicht mal sicher ob das korrekt ist. Im Datenblatt steht ja > "before enabling PLL" ja Thomas. Das hat mich auch verwirrt. leider ist kein Beispiel mit C-Code im Datenblatt enthalten. PJRC hat das in seinem Beispielcode einfach so gemacht. möglicherweise ist das schlicht falsch. aber der Code scheint doch immerhin bei 16MHz funktioniert zu haben?
ich würde da wahrscheinlich sowas machen
1 | ...
|
2 | // setup the pll for 8MHz
|
3 | PLLCSR = 0x00; // pll disabled |
4 | PLLCSR |= (1 << PLLE); // enable pll |
5 | while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock |
6 | ...
|
und das Macro gar nicht verwenden. Das halte ich für übersichtlicher.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.