Soft-PWM Problem

OP #3765648
Lesenswert?

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?
Angehängte Dateien:
#3765657
Lesenswert?

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.//
#3765678
Lesenswert?

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 ?
Moderator Persönliche Seite #3765683
Lesenswert?

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
...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren