Forum: Mikrocontroller und Digitale Elektronik Software PWM Tutorial Erklärung


von Markus H. (dustin_84)


Lesenswert?

Hallo allerseits

Ich habe mal vor 10 Jahren C gelernt und es ist in der zwischenzeit 
einiges an Wissen abhanden gekommen,...

Kurz zu meiner Bastelei:
Ich möchte eine rgb lichtschlange mit pwm ansteuern und das über einen 
tiny,...


Ich versuche momentan das Software PWM Tutorial zu verstehen:

ich hänge ab:
// nur zum Testen, im Anwendungsfall löschen

wozu brauch ich ein array? (denke mal um im bsp von led ein fading 
hinzubekommen)
und wie hängt das array mit memcpy zusammen??
und wie gebe ich an welchen pin ich als pwm ausgang haben möchte?


stimmt die (von mir gedachte) Erklärung:
memcpy(pwm_setting, t1, 8);
pwm_setting ist der zeiger wos hingehen soll, t1 das array das kopiert 
werden soll und 8 die anzahl der Bytes von t1?

vielen dank füre euer Hilfe
lg Markus




// Defines an den Controller und die Anwendung anpassen

#define F_CPU 8000000L                  // Systemtakt in Hz
#define F_PWM 100                       // PWM-Frequenz in Hz
#define PWM_STEPS 255                   // PWM-Schritte pro 
Zyklus(1..255)
#define PWM_PORT PORTD                  // Port für PWM
#define PWM_DDR DDRD                    // Datenrichtungsregister für 
PWM

// ab hier nichts ändern, wird alles berechnet

#define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt

#if (T_PWM<(152+5))
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder 
PWM_STEPS verkleinert werden
#endif

#if PWM_STEPS > 255
    #error PWM_STEPS zu gross
#endif

// includes

#include <stdint.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>

// globale Variablen

volatile uint8_t pwm_setting[8];                    // Einstellungen für 
die einzelnen PWM-Kanäle

// Timer 1 Output COMPARE A Interrupt

ISR(TIMER1_COMPA_vect) {
    static uint8_t pwm_cnt=0;
    uint8_t tmp=0, i=0, j=1;

    OCR1A += (uint16_t)T_PWM;

    for (; i<8; i++) {
      if (pwm_setting[i] > pwm_cnt) tmp |= j;
            j<<=1;
  }
    PWM_PORT = tmp;                         // PWMs aktualisieren
    if (pwm_cnt==(uint8_t)(PWM_STEPS-1))
        pwm_cnt=0;
    else
        pwm_cnt++;
}

int main(void) {

    // PWM einstellen

    PWM_DDR = 0xFF;         // Port als Ausgang

    // Timer 1 OCRA1, als variablem Timer nutzen

    TCCR1B = 1;             // Timer läuft mit vollem Systemtakt
    TIMSK |= (1<<OCIE1A);   // Interrupt freischalten

    sei();                  // Interrupts global einschalten

/*********************************************************************/
// nur zum Testen, im Anwendungsfall löschen

    volatile uint8_t tmp;
const uint8_t t1[8]={27, 40, 3, 17, 150, 99, 5, 9};
const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};
const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};
const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};
const uint8_t t5[8]={0, 0, 0, 0, 0, 0, 0, 9};
const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};

// Messung der Interruptdauer
    tmp =0;
    tmp =0;
    tmp =0;

// Debug

    memcpy(pwm_setting, t1, 8);

    memcpy(pwm_setting, t2, 8);

    memcpy(pwm_setting, t3, 8);

    memcpy(pwm_setting, t4, 8);

    memcpy(pwm_setting, t5, 8);

    memcpy(pwm_setting, t6, 8);

/*********************************************************************/
    while (1)
    {
    }

    return 0;
}

: Verschoben durch User
von Karl H. (kbuchegg)


Lesenswert?

Bitte stell deine Fragen nicht in die Codesammlung.

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.