Forum: Mikrocontroller und Digitale Elektronik Soft PWM, finde den Fehler nicht


von Strahlex (Gast)


Lesenswert?

Hallo, hab gerade an einem Software PWM gearbeitet um 2 Servos 
anzusteuern. Mein Problem ist jetzt das meine Servos immer gleichzeitig 
geschalten werden, finde den Fehler einfach nicht.

Hier ist der Code:
1
//ocr values and ports for ocr
2
volatile uint8_t ocr[2],
3
                pwm_port[2],
4
                array_size;
5
6
ISR(TIMER1_COMPA_vect)
7
{
8
    static bool on = true;
9
    static uint8_t next_ocr = 1;
10
11
    uint8_t i,
12
            temp,
13
            tmp_array_size = array_size,
14
            tmp_ocr[tmp_array_size],
15
            tmp_pwm_port[tmp_array_size];
16
    uint16_t next = (uint16_t)T_PWM;
17
18
    for (i = 0; i < tmp_array_size; i++)                //copy arrays to tmp
19
    {
20
                tmp_ocr[i] = ocr[i];
21
                tmp_pwm_port[i] = pwm_port[i];
22
    }
23
24
    if (on)
25
    {
26
        temp = PWM_STEPS;
27
        for (i = 0; i < tmp_array_size; i++)             //search for the smallest ocr
28
        {
29
            PORTD |= (1 << tmp_pwm_port[i]);
30
            if (tmp_ocr[i] < temp)
31
            {
32
                temp = tmp_ocr[i];
33
                next_ocr = i;
34
            }
35
        }
36
37
        next *= temp + 1;
38
        on = false;
39
    }
40
    else
41
    {
42
        //PORTD &= (0 << pwm_port[next_ocr]);
43
44
        uint8_t old_ocr = next_ocr;
45
        temp = PWM_STEPS;
46
        for (i = 0; i < tmp_array_size; i++)
47
        {
48
            if (tmp_ocr[i] == tmp_ocr[old_ocr])             //checks for all ports to be set (including the current
49
            {
50
                PORTD &= (0 << tmp_pwm_port[i]);
51
            }
52
            else if ((tmp_ocr[i] > tmp_ocr[old_ocr]) &&
53
                     (tmp_ocr[i] < temp))               //search next ocr port
54
            {
55
                temp = tmp_ocr[i];
56
                next_ocr = i;
57
            }
58
        }
59
60
        if (next_ocr == old_ocr)                     //if next_ocr is unchanged go back to 0
61
        {
62
            next *= PWM_STEPS - (tmp_ocr[old_ocr] +1);
63
            on = true;
64
        }
65
        else
66
        {
67
            next *= tmp_ocr[next_ocr] - tmp_ocr[old_ocr];
68
        }
69
70
    }
71
72
    OCR1A += next;
73
}

von Julian B. (julinho)


Lesenswert?

Sieht auf den erste Blick ein bißchen umständlich aus für die Anwendung. 
Ich denke einiges von dem Code muß nicht in der Interrupt-Routine 
berechnet werden.
Wenn Du sowieso einen Timer nur für den PWM benutzt, warum dann kein 
Hardware-PWM. Bei zwei Servos reicht ein Timer aus und die Sache wird 
zum Dreizeiler!!!

von kolabier (Gast)


Lesenswert?

ich verstehe deinen code auch nicht.
jedenfalls wird "0 << tmp_pwm_port[i]" immer 0 sein

von Strahlex (Gast)


Lesenswert?

@julinho: Hardware PWM wär natürlich für die 2 Servos möglich, aber da 
später noch mehr angesteuert werden soll woltte ich gleich eine 
Interrupt Routine schreiben. Optimiert muss das ganze natürlich schon 
noch werden.

@kolabier: Danke, das dürfts gewesen sein.

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
Noch kein Account? Hier anmelden.