Hallo zusammen, nachdem ich gestern meine ATTinys wieder ans Laufen bekommen habe, gibt es heute ein Code-Problem. Ich habe (versucht) ein kleines Test-Programm für einen ATTiny85 zu schreiben, um per Soft-PWM einen Servo an PB4 anzusteuern. Leider scheint meine Berechnung irgendwo einen einen Haken zu haben, denn die PWM ist zu langsam (50ms statt der gewünschten 20ms) und die Pulsbreiten dementsprechend zu lang, so dass der Poti am Anschlag klebt, statt sich hin und her zu bewegen. Eine Änderung am OCR1A bringt genau gar nichs. Egal, ob ich 0x64, 0x32 oder 0x16 ins Register schreibe, die Frequenz bleibt... Wo liegt der Fehler?
Hallo Dominik, Du hast das Datenblatt nicht gelesen. ein attiny85 vergleicht im CTC Mode sein TOP Zählerwert gegenüber OCR1C ! Aber das OCR1C kann keine Overflow-Interrupts auslösen ! Somit läuft der Zähler TCNT1 weiter an OCR1A vorbei, der dann einen Interrupts Event signalisiert und erst nach weiteren (256-OCR1A) Schritten fängt TCNT1 = 0. //Bit 7 – CTC1 : Clear Timer/Counter on Compare Match When the CTC1 control bit is set (one), Timer/Counter1 is reset to $00 in the CPU clock cycle after a compare match with OCR1C register value. If the control bit is cleared, Timer/Counter1 continues counting and is unaffected by a compare match.//
:
Bearbeitet durch User
Hallo Dominik, hier ist noch ein Fehler:
1 | if(i<arraysize){ |
2 | i++; |
3 | }
|
4 | else{ |
5 | i = 0; |
6 | }
|
Es gibt einen Durchlauf mit i=arraysize. Das ist ein Fehler, denn der Index |i| greift auf ein Element im Array |servo_pulse[| zu das nicht existiert ! Wo hast Du den so programmieren gelernt ?
:
Bearbeitet durch User
Außerdem: uint8_t arraysize = sizeof(servo_pulse) / sizeof(uint8_t); Was rechts vom Gleichheitszeichen steht, ist eine Konstante, die der Compiler schon ausrechnen kann. Der Wert landet in einer globalen Variable. Daher wird der Compiler vorraussichtlich den Vergleich später mit der Variablen machen statt mit der Konstanten. Daher besser:
1 | #define ARRAYSIZE (sizeof(servo_pulse) / sizeof(uint8_t))
|
2 | |
3 | ....
|
4 | if (i < ARRAYSIZE - 1){ // -1: Hier den anderen Fehler glattgebügelt |
5 | ...
|
:
Bearbeitet durch Moderator
Zeige bitte noch dein komplettes Programm, so können andere auch deinem Erfolg folgen. Ok ?
:
Bearbeitet durch User
Hallo Dominik, noch ein Fehler, natürlich liefert dieser "Teiler" keine 1ms Ticks:
1 | OCR1A = 0x64; |
Wie man das richtig berechnet steht im Datenblatt ! Man wer liest den das überhaupt ?
Anbei das geänderte Programm, dass es jetzt tut, aber was meinst du, dass der "Teiler" keine 1ms-Ticks liefert? Mal davon abgesehen, dass es OCR1C statt OCR1A heißen muss? 1MHz Systemtakt / 100 = 10kHz = 0.1ms oder verrechne ich mich da jetzt?
Dominik R. schrieb: > 1MHz Systemtakt / 100 = 10kHz = 0.1ms oder verrechne ich mich da jetzt? > OCR1C = 0x64; //1MHz/100 = 10kHz Interruptfrequenz = alle 0.1ms Falsch gerechnet - wo bleibt die Null ? OCR1C = 0x64 - 1; //1MHz/100 = 10kHz
:
Bearbeitet durch User
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.