-
        
+ Antworten
Ergebnis 1 bis 10 von 10

Thema: PWM-IC / parallel in oder SPI

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    15.03.2004
    Ort
    Attnang
    Alter
    39
    Beiträge
    54

    PWM-IC / parallel in oder SPI

    Hallo!
    Ich bin auf der Suche nach einem PWM-IC um Servos anzusteuern.
    Ich würde den gerne parallel oder mit SPI über meinen Microcontroller beschreiben. Mein Controller hat nur 3 PWM-Ausgänge, ich brauche aber 8, deshalb ist eine andere Lösung nötig.
    Danke,
    Alex

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.11.2003
    Beiträge
    991
    Was benutzt du denn für einen Mikroprozessor ?? Bei den schnelleren ( zum Beispiel AVR ) kann man an jedem Pin ein Servo anschließen.

    MfG Kjion

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    15.03.2004
    Ort
    Attnang
    Alter
    39
    Beiträge
    54
    Ich hab den AtMega8, aber ich hab nur noch 2 Timer und 13 Pins frei.
    Mit 2 Timern wird das ganze aber ein bisschen ungenau und viel Rechenaufwand, oder?

    MFG Alex

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.11.2003
    Beiträge
    991
    Naja, welche Timer sind es denn ?? Wenn du noch den 16-Bit Timer frei hast, dann hast du ne Auflösung von über 20 000 Schritten auch wenn Servos das nicht umsetzten können.
    Also nix mit ungenau ! Viel Rechenaufwand ist das auch nicht. Ich kann dir eine fertige Routine dafür geben die ich auf meinem Laufroboter einsetzte ( ist in C geschrieben ). Sie läuft über Interrupt und ist nur relativ kurz, sodass die Rechenzeit zu vernachlässigen ist...

    13 Pins -> 13 Servos mit dem entsprechenden Programm kein Problem

    MfG Kjion

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    15.03.2004
    Ort
    Attnang
    Alter
    39
    Beiträge
    54
    Ja, den 16-Bit-Timer hab ich noch frei.
    Kannst du mich mal in den code einsehen lassen? Danke,
    Alex

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.11.2003
    Beiträge
    991
    Code:
    /* Variablen für die Servoansteuerung */
    volatile unsigned char
    	servo_zaehler;
    volatile unsigned int
    	servo_werte[3];
    
    /*
    *	Timer1  52736 -> 0.8 ms
    *			  41535 -> 1.5 ms
    *			  30336 -> 2.2 ms
    *
    *	Auflösung : 52736 - 30336 = 22400 Schritte
    */
    
    void servo_init(void)
    {
    	/* Timer1 */
    	TCCR1A = 0x00;										// normaler Timermodus ( kein PWM )
    	TCCR1B = 0x00;										// Timer1 deaktivieren
    	TIMSK = (1<<TOIE1) | (1<<TOIE0);					// Timerüberlaufinterrupts aktivieren
    	
    	/* Timer0 */
    	TCCR0 = (1<<CS02) | (1<<CS00);
    	TCNT0 = 0x98;
    }
    
    /****************************[ Interruptroutinen ]******************************/
    
    /* Interrupt wird bei einem Überlauf von Timer0 ausgelöst ( alle 6,656... ms ) 
       Es werden nacheinander die drei Servos des Beins ausgewählt und angesteuert */
    INTERRUPT(SIG_OVERFLOW0)
    {
    	unsigned int temp;
    	
    	servo_zaehler++;
    	if (servo_zaehler > 2)
    		servo_zaehler = 0;
    	
    	switch(servo_zaehler) 							// Signal für die Servos auswählen
    	{
    		case 0:
    			PORTD |= (1<<PD5);
    			break;
    		case 1:
    			PORTD |= (1<<PD6);
    			break;
    		case 2:
    			PORTD |=  (1<<PD7);
    			break;
    		default:
    			servo_zaehler = 0;
    	}
    	
    	temp = servo_werte[servo_zaehler];
    	
    	TCNT1 = temp;
    	TCCR1B = (1<<CS10);								// Timer1 aktivieren, Prescaler = 1
    	
    	TCNT0 = 0x98;									// Timer0 neu laden
    }
    
    /* Interrupt wird bei einem Überlauf von Timer1 ausgelöst
       Setzt das Signal für die Servoansteuerung wieder zurück */
    INTERRUPT(SIG_OVERFLOW1)
    {
    	PORTD &= ~((1<<PD5)|(1<<PD6)|(1<<PD7));			// Servosignal wieder löschen
    	
    	TCCR1B = 0x00;									// Timer1 deaktivieren
    }

    Du müsstest dann nur noch die entsprechenden Werte in das Array laden. Das Beispiel hier ist jetzt für 3 Servos, sollte sich aber auf mindestens 10 erweitern lassen ( Man müsste nur die ganzen anderen Servos in die "case" Anweisung einfügen und den Wert für TCNT0 anpassen, sag wieviele du brauchts, dann kann ich dir den entsprechenden Wert geben ). Es ist jetzt einfach aus meinem Quelltext zusammenkopiert ... ich hoffe man kann trotzdem erkennen worum es geht

    MfG Kjion

  7. #7
    Administrator Robotik Einstein Avatar von Frank
    Registriert seit
    30.10.2003
    Beiträge
    4.943
    Blog-Einträge
    1
    Hi Kjion,

    was macht Dein 2313 Servo-Code? Gehts gut voran?

    Gruß frank

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.11.2003
    Beiträge
    991
    Jaja, kommt

    I2C will noch nicht ganz, ansonsten ist er aber größenteils fertig...

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    15.03.2004
    Ort
    Attnang
    Alter
    39
    Beiträge
    54
    Danke Kjion!
    Ich werds heute abend mal analysieren...
    Schöne Grüße

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    22.11.2003
    Beiträge
    991
    @trickTronic
    Ich sehe du kannst die "temp" Variable aus der INTERRUPT(SIG_OVERFLOW0) - Routine rausschmeißen. Wird von mir in einem weiteren Teil der Routine benötigt, im dem Fall ist sie aber sinnlos...

    also gleich:
    TCNT1 = servo_werte[servo_zaehler];

    MfG Kjion

+ Antworten

Berechtigungen

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