- 12V Akku mit 280 Ah bauen         
Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 33

Thema: Soft-PWM erstellen

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    11.10.2007
    Beiträge
    77

    Soft-PWM erstellen

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hi @ll,

    wie erstelle ich eine Soft-PWM?
    Habe was gelesen über Timer... aber ich verstehe es nicht

    Normales PWM habe/benutze ich schon an 2 PB0 und PB1 für 2 Servos.
    Was ich suche, ist jetzt eine Soft-PWM für ansteuerung meines IC L293 D(2 Getriebemotoren).

    Danke!

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    11.10.2007
    Beiträge
    77
    Hi,

    habe mir mal die links angeschaut.
    Zum 2 Link eine frage:

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

    OCRA1 benutze ich doch schon, also klappt das damit nicht oder verstehe ich das jetzt falsch (man kann doch OCRA1 nur 1 mal benutzen)?

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Du kannst jeden freien Timer benutzen.
    Welche PWM-Frequenz möchtest du haben( bei den Servos ist es 50Hz), in wie vielen Stufen möchtest du die Geschwindigkeit einstellen.

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    11.10.2007
    Beiträge
    77
    Ich möchte nur 2 Stufen haben 100% und 50%.
    Mehr soll die 2 Ausgänge nicht machen.

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Dann lässt du den Timer laufen, der toggled bei jedem Überlauf ein Bit, damit hast du deine 50%.

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    11.10.2007
    Beiträge
    77
    Mh,
    ich habe das leider nicht so genau verstanden
    z.B. PWM_DDR = 0xFF; was für ein Ausgangpin an D ist das (Ich brauche z.B. PC4)?
    Hier mal mein Code wie ich mir das vorstelle. Fehlt aber das mit 50% und 100%:

    Code:
    #define F_CPU 8000000L                  // Systemtakt in Hz
    #define F_PWM 100                       // PWM-Frequenz in Hz
    #define PWM_STEPS 256                   // PWM-Schritte pro Zyklus(1..256)
    #define PWM_PORT PORTD                  // Port für PWM
    #define PWM_DDR DDRD                    // Datenrichtungsregister für PWM
    #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össt werden oder F_PWM oder PWM_STEPS verkleinert werden
    #endif
      
    #include <stdint.h>
    #include <string.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
     
    // globale Variablen
    volatile uint8_t pwm_setting[8];                  
     
    // 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
    	DDRD  &= (~ (1<<PD2)|(1<<PD3));  /* Pin D2,D3,als Eingang */ 
        PORTD |= (1<<PD2)|(1<<PD3);    /* Pull Up von PIN D2,D3 aktivieren */  
        
        // Timer 1 OCRA1, als variablem Timer nutzen
     
        TCCR1B = 1;              // Timer läuft mit vollem Systemtakt
        TIMSK |= (1<<OCIE1A);   // Interrupt freischalten
        sei();                   // Interrupts gloabl einschalten
    	
    	  if (!( PIND & (1<<PIND2))) {    /* mache was wenn PinD2 low ist */
                 // Hier: der Getriebemotor an L293D soll mit 100% laufen  
           }
     
     	  if (!( PIND & (1<<PIND3))) {    /* mache was wenn PinD3 low ist */
                 //Hier: der Getriebemotor an L293D soll mit 50% laufen  
           }
     
        return 0;
    }

  8. #8
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    volatile uint8_t takt;

    ISR(TIMER0_OVF_vect){
    takt++;
    }

    int main(void) {
    TCCR0=(1<<CS00); //kein Prescaler
    TIMSK|=(1<<TOIE0); // Overflow Interrupt en
    DDRD=(1<<PD3);// PortD3 wird Ausgang

    if(takt>=10){ //Takt bis 10 zählen
    PORTD^=(1<<PD3); //PortD3 toggelt 50% PWM
    }
    Code:
    Dieses Port-togglen kannst du natürlich weiter verknüpfen.
    
    Du machst am Ende deines Code ein return0, damit beginnst du aber wieder am Anfang bei main. Damit wird immer alles neu initialisiert. Ich mache nach den Einstellungen im main ein for(;;){  und hier kommt mein sich wiederholender Code hinein} ohne return0 am Ende. Der Compiler sollte da auch ein Warning ausgeben.

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.07.2004
    Ort
    Südhessen
    Beiträge
    1.312
    Cool @hubert:
    Code im Zitatfenster und Text im Codefenster

  10. #10
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Tja, kann auch mal passieren, sieht doch gut aus

Seite 1 von 4 123 ... LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen