Hallo, ich habe einen ATmega328 (Arduino Nano) und möchte diesen gerne auf 1MHz laufen lassen. Mein Programm konnte unter den 16MHz vom Auslieferunszustand wunderbar den DS18B20 und das 1602LCD betreiben. Als ich den PID Regler von der Atmel Application Note 221 integrieren wollte, stand drin, dass man den PID Rechenzyklus auf ca. 1 Hz bringen soll. Also den Timer Prescaler für den PID auf 1024 gesetzt und F_CPU auf 1000000UL gesetzt und die Fuses für den Internen 8MHz Oszillator und CLKDIV8 aktiviert. Jetzt geht gar nix mehr. Weder Display noch DS18B20. Wenn ich die CKOUT Fuse aktiviere, kann ich an PB0 den 8MHz Tackt messen. Warum ändert sich dieser Tackt nicht, wenn ich die Fuse CLKDIV8 aktiviere und deaktiviere? Das müsste doch 100% Code-Unabhängig sein. Egal was ich da für einen Mist zusammengeschrieben habe. Weil wenn ich die CKOUT Fuse setze und resette, kann ich das ja sofort am Oszi messen. Warum geht das mit dem Tacktdividierer nicht? Umgebung: AtmelStudio 7 Programmer: AVR Dragon über ISP Kann mir jemand helfen? Danke
Laut Datenblatt sollte das gehen: "If the system clock prescaler is used, it is the divided system clock that is output. " Hast du das Ding mal kurz Stromlos gemacht, nachdem du die Fuses geändert hast?
Danke Stefan, dass Du das genauso siehst. Ja, ich habe sogar die verschiedenen Delaytimes bei den 8MHz Fuses ausprobiert und jedesmal einen Power-Reset gemacht. Bringt leider nix. Der schwingt stur auf 8 Mhz. Im DaBla konnte ich auch keinen Verweis finden, dass man noch andere Fuses o.ä. setzen muss?! Grüße Jch
Jch schrieb: > PID Rechenzyklus auf ca. 1 Hz bringen soll. Das macht man auf anderem Wege, als den SystemTakt runter zu setzen. Dafür verwendet man z.B. einen der Timer. Jch schrieb: > Warum ändert sich dieser Tackt nicht, wenn ich die Fuse CLKDIV8 > aktiviere und deaktiviere? Muss es ! Also machst du was falsch. Sicher, dass du nicht nur den Simulator befummelst?
Arduino Fanboy D. schrieb: >> PID Rechenzyklus auf ca. 1 Hz bringen soll. > > Das macht man auf anderem Wege, als den SystemTakt runter zu setzen. > Dafür verwendet man z.B. einen der Timer. Ähm ja. Aber bei 16 MHz und 8 Bit Timer und 1024er Prescaler komme ich leider nicht wirklich nahe an den 1Hz Tackt ran und warum sollte ich nicht den Systemtackt reduzieren dürfen? 1 MHz braucht weniger Leistung als 16 MHz und den Quarz brauche ich nicht für die Genauigkeit. Wenn ich den 128 kHz Oszillator auswähle, geht mein Tackt auf die 128kHz runter, aber auch hier geht der CLKDIB8 nicht. Also auf 16kHz geht der Pin nicht runter. Auch meine PWM Timer ändern ihren Tackt nicht, egal ob den DIV8 aktiviere oder nicht. Und der 1 MHz Tackt hätte noch den Vorteil, dass mein PWM MOSFET nicht so heiss werden würde, weil der für die Heizung keine besonders hohe frequenz schalten muss. Grüße Jch
Arduino Fanboy D. schrieb: > Jch schrieb: >> Warum ändert sich dieser Tackt nicht, wenn ich die Fuse CLKDIV8 >> aktiviere und deaktiviere? > Muss es ! das denke ich auch, aber was mache ich falsch? Gibts da geheime Hinterürchen? Arduino Fanboy D. schrieb: > Sicher, dass du nicht nur den Simulator befummelst? Nein, ansonsten könnte ich ja weder mit den 8MHz und 128 kHz am Oszi spielen, noch würde ich mit dem CLKOUT Pin rumspielen können. Und man kann auf dem Display den RESET beim flashen erkennen. Grüße Jch
Problem gelöst. Ob das die Ursche war, möchte ich Bezweifeln. Ich habe einen Chip Erase gemacht und einfach nochmal mit den Fuses gespielt. Nach dem Chip Erase konnte ich einfach so zwischen CLKVIV8 und nicht-CLKDIV8 wechseln und am Oszi tut sich auch was. Sehr merkwürdig. Ich dachte der Code auf dem Chip ist hierfür irrelevant. Sobald ich wieder den Code auf den µC hochlade, bin ich wieder bei 8 MHz. Irgendwer überschreibt mir die Fuses. Kann das an den Toolchain Compilereinstellungen liegen? Wenn ja, wo muss ich da suchen? Bzw. nach was muss man da Googlen? Das ist komplettes Neuland für mich
1 | -x c -funsigned-char -funsigned-bitfields -DDEBUG -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.4.351\include" -I"../Config" -I"../include" -I"../utils" -I"../utils/assembler" -I".." -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -Wall -mmcu=atmega328p -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\Atmel\ATmega_DFP\1.4.351\gcc\dev\atmega328p" -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" |
Jch schrieb: > Irgendwer überschreibt mir die Fuses. Ich tippe eher darauf, dass dein eigenes Programm den Prescaler CLKPR verändert und dadurch die Fuse unwirksam macht.
Jch schrieb: > Sehr merkwürdig. Ich dachte der Code auf dem Chip ist hierfür > irrelevant. GCC power.h -> https://www.nongnu.org/avr-libc/user-manual/group__avr__power.html Der Bootloader wird anscheinend auch immer mit programmiert? Jch schrieb: > Irgendwer überschreibt mir die Fuses. Kann das an den Toolchain > Compilereinstellungen liegen? Wird die .elf Datei oder die .hex hochgeladen?
Stefan ⛄ F. schrieb: > Jch schrieb: >> Irgendwer überschreibt mir die Fuses. > > Ich tippe eher darauf, dass dein eigenes Programm den Prescaler CLKPR > verändert und dadurch die Fuse unwirksam macht. Tatsächlich im Init vom PID-Code wird der CLKPR auf Prescaler 1 gesetzt. Somit muss ich mein Verständnis über fuses nochmal updaten. Ich dachte Fuses sind mächtiger als der Code. Somit habe ich nicht im Code danach gesucht. Holger L. schrieb: > Der Bootloader wird anscheinend auch immer mit programmiert? naja, das war noch eine Arduino-Leiche. Ich nutze keinen Bootloader. Holger L. schrieb: > Jch schrieb: >> Irgendwer überschreibt mir die Fuses. Kann das an den Toolchain >> Compilereinstellungen liegen? > > Wird die .elf Datei oder die .hex hochgeladen? ich nehme die .hex. Würde die .elf einen Unterschied machen? Die ist doch nur dazu da um andere Einstellungen wie z.B.Fuses auch mit zu flashen oder? Danke schonmal. Da wäre ich warscheinlich so schnell nicht draufgekommen
Jch schrieb: > Somit muss ich mein Verständnis über fuses nochmal updaten. Ich dachte > Fuses sind mächtiger als der Code. Sind sie. Aber du solltest mal nachlesen, was die CLKDIV8-Fuse eigentlich tut. Oliver
"388025I–AVR–02/09 ATmega48P/88P/168P/328P Seite 38 The CKDIV8 Fuse determines the initial value of the CLKPS bits. If CKDIV8 is unprogrammed,the CLKPS bits will be reset to “0000”. If CKDIV8 is programmed, CLKPS bits are reset to“0011”, giving a division factor of 8 at start up. This feature should be used if the selected clocksource has a higher frequency than the maximum frequency of the device at the present operat-ing conditions. Note that any value can be written to the CLKPS bits regardless of the CKDIV8Fuse setting. The Application software must ensure that a sufficient division factor is chosen ifthe selected clock source has a higher frequency than the maximum frequency of the device atthe present operating conditions. The device is shipped with the CKDIV8 Fuse programmed" mfG
:
Bearbeitet durch User
Jch schrieb: > Tackt > ... > Tacktdividierer Jch schrieb: > 1Hz Tackt > ... > Systemtackt > ... > 1 MHz Tackt
@Jch Hallo! Ich habe hier auch den Arduino Nano V3 und hab mal nachgeschaut ob die 1Mhz für den Internen Oszilator überhaupt gibt. Leider Nein. Aber vllt. hilft dir das weiter: Bei gestztem CLKDIV8 einfach mal F_CPU 8MHz, 4MhZ und 1Mhz mit den Werten Spielen und beobachten was passiert. #ifndef F_CPU // kann auch im Makefile definiert sein //#define F_CPU 16000000UL // Takt als LONG definieren, da zu groß für Integer #define F_CPU 1000000UL // Takt als LONG definieren, da zu groß für Integer #endif #include <avr/io.h> // Namen der IO Register #include <util/delay.h> // Funktionen zum warten // Achtung, damit delay richtig funktioniert muß mit Optimierung compiliert werden int main(void) { unsigned char test_c; // LED an Port PB0 ist Low Aktiv angeschlossen PORTB = 0x01; // Nur Pin PB0 aktiv DDRB = 0x01; // PB0 als Ausgang definieren while (1) { PORTB &= ~(1<<PB0); _delay_ms(200); PORTB |= (1<<PB0); _delay_ms(200); } }
@Jch Was passiert wenn Bei gestztem CLKDIV8 und 16 Mhz mit dem Blinkprogramm? Richtig! Die Blinkfrequenz wird langsammer. Es dürfte deinem Ziel schon näher kommen! Gute Nacht!
der nixwois schrieb: > // Takt als LONG definieren, da zu groß für > Integer Der Kommentar ist falsch!
Auf jeden Fall! 1. long ist auch ein Integer 2. long wird automatisch verwendet, wenn das Literal nicht in int passt 3. Das U könnte allerdings sinnvoll sein
@Arduino Fanboy D. Komm mal runter, ist ja wirklich schlimm mit dir. Es ist Entschleunigung angesagt. ;->
Oliver S. schrieb: > Jch schrieb: >> Somit muss ich mein Verständnis über fuses nochmal updaten. Ich dachte >> Fuses sind mächtiger als der Code. > > Sind sie. Aber du solltest mal nachlesen, was die CLKDIV8-Fuse > eigentlich tut. ich habe es im DaBla nachgelesen, aber anscheinend anders interprätiert, als es gedacht ist. Christian S. schrieb: > Note that any value can be > written to the CLKPS bits regardless of the CKDIV8Fuse setting. ich habe das so verstanden, als ob man beim CLKPS z.B. ein Prescaler von 8 einstellen kann und die CKDIV8-Fuse das nochmal dividiert, sodass man auf einen Prescaler von 64 kommt. der nixwois schrieb: > Hallo! > Ich habe hier auch den Arduino Nano V3 und hab mal nachgeschaut ob die > 1Mhz > für den Internen Oszilator überhaupt gibt. Leider Nein. danke dafür, aber wenn ich ein Oszi habe und den Clock direkt auf einen Pin herausführen kann, muss ich kein Blinklicht mitstoppen ;-) Klar hat der 328 keinen echten 1 MHz Clock, sondern nur einen vom 8 Mhz RC welcher durch 8 geteilt wird durch die Fuse (oder durch andere Werte mit dem Höllenregister) Ich habe doch schon in folgendem Beitrag die Lösung geschrieben: Jch schrieb: > Stefan ⛄ F. schrieb: >> Jch schrieb: >>> Irgendwer überschreibt mir die Fuses. >> >> Ich tippe eher darauf, dass dein eigenes Programm den Prescaler CLKPR >> verändert und dadurch die Fuse unwirksam macht. > > Tatsächlich im Init vom PID-Code wird der CLKPR auf Prescaler 1 gesetzt. > Somit muss ich mein Verständnis über fuses nochmal updaten. Ich dachte > Fuses sind mächtiger als der Code. Somit habe ich nicht im Code danach > gesucht. Dieses Problem mit dem Takt ist gelöst, aber im Moment kämpfe ich noch mit den Rückgabewerten vom PID Regler. Aber das ist eine andere Geschichte...
Hi >ich habe das so verstanden, als ob man beim CLKPS z.B. ein Prescaler von >8 einstellen kann und die CKDIV8-Fuse das nochmal dividiert, sodass man >auf einen Prescaler von 64 kommt. Nein. Es gibt nur einen Prescaler. Beim setzen der CKDIV8-Fuse wird dieser auf einen Teiler von 8 gestellt. Mit dem Setzen eines anderen Prescalers wird das überschrieben. MfG Spess
>ich habe es im DaBla nachgelesen, aber anscheinend anders interprätiert, >als es gedacht ist. >Christian S. schrieb: >Note that any value can be >written to the CLKPS bits regardless of the CKDIV8Fuse setting. >ich habe das so verstanden, als ob man beim CLKPS z.B. ein Prescaler von 8 >einstellen kann und die CKDIV8-Fuse das nochmal dividiert, sodass man auf >einen Prescaler von 64 kommt." Also liegt es am fremdländischen Englisch. Der Satz heißt: Beachte, daß jeder Wert in die clkps-Bits geschrieben werden kann, ohne Beachtung der/Rücksicht auf die Fuse-Einstellung. Das bedeutet, daß die Fuse überschrieben werden kann. Sie stellt nur einen Anfangswert beim Start dar, der durch das Programm jederzeit geändert werden kann. Man kann es auch so verstehen, wie Du oben geschrieben hast. Das wäre eigentlich naheliegend, entspricht aber nicht dem Wortlaut des Autors. MfG
:
Bearbeitet durch User
spess53 schrieb: > Nein. Es gibt nur einen Prescaler. Beim setzen der CKDIV8-Fuse wird > dieser auf einen Teiler von 8 gestellt. Mit dem Setzen eines anderen > Prescalers wird das überschrieben. Hallo, ich arbeite mich auch gerade in die Clock/Timer-Geschichten ein und habe in der Docu gefunden, dass neben dem System-Clock-Prescaler Timer0/1 und Timer2 jeweils noch einen "eigenen" Prescaler haben (können). Verstehe ich das richtig? Gruß Rainer
Der ADC UART TWI SPI haben auch noch Teiler! Gibt also Mengen davon. Alle diese hängen (meist) am Systemtakt. Sind also dem CLKPS untergeordnet. Rainer V. schrieb: > dass neben dem System-Clock-Prescaler Nicht neben, sondern unter, in der Hierarchie.
Rainer V. schrieb: > Verstehe ich das richtig? Tust du, das hat aber mit dem Thema des Threads wenig zu tun. Oliver
:
Bearbeitet durch User
Hallo, ich bin gerade dabei den PID Regler einzubinden. Er funktioniert halbwegs, aber der Integrierer ist zu fleissig. Wie kann ich das Anti-Wind-Up einprogrammieren? In der AVR221 AppNote (https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en591227) ist der Quellcode für den PID Regler. Wo sollte ich jetzt dem Integrator einen Strich durch die Rechnung machen?
1 | |
2 | // Calculate Iterm and limit integral runaway
|
3 | temp = pid_st->sumError + errors; |
4 | if (temp > pid_st->255) {//maxSumError; |
5 | i_term = 255;//MAX_I_TERM; |
6 | pid_st->sumError = pid_st->255;//maxSumError; |
7 | } else if (temp < -pid_st->0) {//maxSumError; |
8 | i_term = 0;//-MAX_I_TERM; |
9 | pid_st->sumError = -pid_st->0;//maxSumError; |
10 | } else { |
11 | pid_st->sumError = temp; |
12 | i_term = pid_st->I_Factor * pid_st->sumError; |
13 | }
|
Die auskommentierten Werte sind die aus dem originalen Code und die 0 und 255 kommt von mir. Was mache ich falsch? Weil so funktioniert es nicht. Der C++ Code ist mir bisher noch nicht geläufig. Ich will ja den Ausgang vom Regler auf 256 skalieren, weil es auf einem PWM Ausgang geht. Grüße Jch
Oliver S. schrieb: > Tust du, das hat aber mit dem Thema des Threads wenig zu tun. Ja, ich weiss, aber der TO hat die Timer-Prescaler wohl nicht auf dem Schirm und ich habe mich eben gefragt, ob ich da mit meinen "Erkenntnissen" ganz falsch liege. Sorry und danke :-) Rainer
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.