-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 18

Thema: PWM ansteuern / programmieren

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    29.12.2006
    Alter
    56
    Beiträge
    19

    PWM ansteuern / programmieren

    Anzeige

    ich habe da mal einige fragen zu pwm und hoffe das mir jemand helfen kann.

    1.
    ich habe einen atmega128 und habe gelesen das er 6 pwm ports hat.

    - nun kann ich aber nirgends finden welche ports das sind

    - ich kann nichts darüber finden wie man dann das pwn aktiviert und
    entsprechend programmiert

    2.
    wie kann man pwm softwaretechnisch realisieren. man findet zwar an mehreren stellen code-auszüge doch leider immer nicht ganz vollständig



    ich wäre echt dankbar wenn mir jemand weiterhelfen könnte.
    vielleicht hat sogar jemand ein code-beispiel. in c.

    es muss doch jemand geben der seine motoren über pwm in C ansteuert.

    gruß orko

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.03.2007
    Beiträge
    176

    Re: PWM ansteuern / programmieren

    Zitat Zitat von orko512
    2.
    wie kann man pwm softwaretechnisch realisieren. man findet zwar an mehreren stellen code-auszüge doch leider immer nicht ganz vollständig
    gruß orko
    hab nur eine LED Steuerung in HW PWM

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Er hat sogar 8 PWM-Kanäle!
    Wenn du mit Ports die Pins des Chips meinst sind das alle die, an denen OCxx dran steht. Steht für Output-Compare.

    Zur Programmierung der PWM-Kanäle würde ich dir empfehlen die entsprechenden Seiten im Datenblatt zu sehen. Es kommt schließlich drauf an, welchen Kanal du mit welcher Frequenz und und welcher Auflösung ansteuern willst.

    Hier ist ein relativ komplexes Beispiel einer Anwendung des PWM für einen Mega8. entscheidend ist das richtige Setzen der Register TCCR...

    Code:
    #include <avr/io.h>
    #include <inttypes.h>
    #include <avr/interrupt.h> 
    #include <avr/signal.h>
    
    void pwminit(){
    TCCR1B =  (1<<WGM13) | (1<<WGM12) | (1<<CS10);
    // WGM* = Fast PWM Mode 14
    // CS10 = Prescaler = 1
    TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0) | (1<<WGM11);
    // COM* = OC1A/B sind aktiv, bei Comparematsch wird der Ausgang gesetzt bei TOP gelˆscht
    // WGM* = ICR1 = Obergrenze
    TIMSK =  (1<<TOIE1) | (1<<OCIE1B);
    // OCIE1B = Output Compare Interrupt Enable 1B
    // TOIE1 = Timer Overflow Interrupt Enable
    ICR1 = 200;
    OCR1B = 100;
    OCR1A = 0; 	
    };
    
    int main(void) {
    
    pwminit();
    SREG |= (1<<7);
    DDRB = 0b00111111;
    DDRC = 0b00111000;
    DDRD = 0b11111110;
    PORTB |= ((1<<1) | (1<<0));
    for(;;){};
    }

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    29.12.2006
    Alter
    56
    Beiträge
    19
    hi moritz,

    danke für die hinweise.

    ich werde mich mit den infos mal ans werk machen und versuchen meine motoren zum laufen zu bekommen.

    gruß orko

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Hi Orko,

    wir können ja mal versuchen das zusammen hinzukriegen.
    Also wen ich das richtig verstehe willst du den Hardware-PWM benutzen und keinen interrupt auslösen.
    Dann müssten wir klären welche Auflösung 8...10 Bits oder variabel und welche Frequenz du benutzen willlst.

    hier mal das Datenblatt:
    http://www.atmel.com/dyn/resources/p...ts/doc2467.pdf

    Wenn du nichts dagegen hast nehmen wir einfach mal den Timer/Counter0. Der hat eine 8-Bit Auflösung.

    OK?

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    29.12.2006
    Alter
    56
    Beiträge
    19
    hi rco,

    danke für dein angebot.

    würde ich gerne in anspruch nehmen.

    Hier mal kurz ne beschreibung was ich eigemtlich machen will:

    ich möchte meinen robi mit zwei lego-motoren fahren.
    diese möchte ich über pwm ansteuern. ich habe inzwischen mal einige versuche mit software pwm gestartet. die laufen auch, aber sind im prinzip nur schleifen in denen ich hochzähle und den ausgang dann setze oder nicht setze.
    alles ohne timer und interrupt.
    läuft zwar ist aber auf dauer keine gute lösung.

    nun habe ich gelesen das es auch hardware pwm gibt, die mein atmega128 unterstützt.

    ich habe auch schon danach gegoogelt und auch einige infos gefunden.
    leider verstehe ich es trotzdem nicht wie das ganze abläuft.
    in den meisten beispielen werden dann irgendwelche register gesetzt.
    wofür diese dann jeweils sind, steht leider meist nicht dabei.
    klar könnte ich mir ein beispiel nehmen und solange rumdocktorn bis es läuft, ich würde aber gerne verstehen was ich da mache und nicht einfach nur kopieren.

    also wenn du lust hättest einen anfänger (der auch auf anhieb nicht immer gleich alles versteht) zu helfen würde ich mich echt freuen.

    gruß orko

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Hi Orko,

    also wenn du zwei Motoren ansteuern willst, dann verwenden wir nicht Timer0, da der nur einen Ausgang hat.
    Das siehst du im Datenblatt auf Seite 2 (OC0).

    Wir verwenden besser Timer1, dann brauchen wir nur einen Timer.
    Wir hätten sogar 3 (OC1A-OC1C) zur Verfügung.

    Der Vorteil bei der PWM-Ansteuerung eines Motors ist, dass wir in Sachen Frequenz und Genauigkeit nicht festgelegt sind.

    Im folgenden werden wir uns jetzt durchs Datenblatt und durch die Register arbeiten. (Ich hoffe, dein Englisch ist gut )

    Ab Seite 111 wird es also interessant. Wobei, da am Anfang erstmal sehr viel über die prinzipielle Funktionsweise geht. Danach noch etwas Assembeler etc. Für uns erstmal nicht interessant. Wenn du Lust hast, kanst du dich da ja mal durcharbeiten.

    Der Vorteil des des Hardware-PWMs ist ja, dass außer der Initialisierung keine Rechenzeit verschwendet wird. das ganze läuft vollkommen im Hintergrund.

    Auf Seite 135 findest du jetzt erstmal einen Überblick über die möglichen Einstellungen der Timer.
    Da wir keine besonderen Ansprüche an den PWM haben, würde ich vorschlagen, dass wir ihn im Mode 5,6 oder 7 betreiben, je nachdem, welche Auflösung du haben willst. Das ist der Fast PWM. Der ist am einfachsten zu erklären.

    Was heißt das jetzt:
    Der Counter1 zählt mit einer Frequenz, die wir später festlegen, bis zu einer Grenze (entweder 256, 512 oder 1024). Wobei, wenn der Counter bei 256, 512, 1024 ankommt wieder auf Null springt. Das ist ein einfacher Überlauf. Jetzt haben wir 3 Register, in die wir Werte schreiben. Wenn der Counter1 auf einen Zahl = einem der 3 Register kommt, wird ein Ausgang gesetzt oder gelöscht, je nachdem wie wir das noch einstellen.
    Der Counter1 Zählt also einfach und vergleicht, ob der Wert, an dem ein Ausgang gesetzt werden soll, schon erreicht ist. Kommt der Counter an seine Obergrenze, so setzt oder löscht er den Zustand des Ausgangs automatisch.

    Schau dir am besten mal die Seiten 124 und 125 dazu an.

    Timer und PWM beruhen nur auf einem Counter, der immer nach einer bestimmten Zeit seinen Wert inkrementiert.

    Bei welcher Frequenz betreibst du den AVR eigentlich?

    Ist soweit alles klar? Kommst du mit, sonst stell Fragen.
    Wie du siehst, kommst du um das Datenblatt nicht herum.

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    29.12.2006
    Alter
    56
    Beiträge
    19
    hi rco,

    super von dir. ist ja wie ein online-kurs.

    ich fange gleich mal an zu fragen.
    sollte ich irgendwo einen fehler machen bitte gleich anmarkern.

    >> (Ich hoffe, dein Englisch ist gut)
    ob mein englisch reicht???
    sieht eher schlecht aus.

    >>also wenn du zwei Motoren ansteuern willst, dann verwenden wir nicht
    >>Timer0, da der nur einen Ausgang hat.
    >>Das siehst du im Datenblatt auf Seite 2 (OC0).

    verstehe ich das richtig:
    wenn an den pins OC0 steht dann sind die für Timer0?
    entsprechend für die anderen TimerX.

    danach hätte ich einen
    timer0 mit einen ausgang (oc0)
    timer1 mit drei ausgängen (oc1a, oc1b, oc1c)
    timer2 mit einem ausgang (oc2)
    timer3 mit drei ausgängen (oc3a, oc3b, oc3c)

    also insgesamt 4 timer.

    >>Auf Seite 135 findest du jetzt erstmal einen Überblick über die
    >>möglichen Einstellungen der Timer

    buh... ganz schön viele infos.

    >>Der Counter1 zählt bis zu einer Grenze (entweder 256, 512 oder 1024)

    wenn ich das richtig verstehe ist das nun abhängig vom modus.
    modus 5 = 8bit = 256
    modus 6 = 9bit = 512
    modus 7 = 10bit = 1024

    in der tabelle61 auf seite 135 steht nun welche bits ich in den timer laden muss damit ich den entsprechenden modus setze.
    richtig??????

    für modus 7:
    WGMn3 = 0
    WGMn2(CTCn) = 1
    WGMn1(PWMn1) = 1
    WGMn0(PWMn0) = 1

    das bedeutet = Fast PWM, 10-bit


    wie sieht das jetzt softwaretechnisch aus??
    ich möcht timer1 benutzen.
    er soll in modus 7 betrieben werden.

    genau hier hört es jetzt bei mir auf.
    ich schaue in das datenblatt und komme nicht weter.
    ich finde Timer/Counter1 Control und
    Timer/Counter3 Control
    gibt es denn mehrere??

    nun gleich noch ne frage:
    wenn ich mir so einige beispiele anschaue finde ich dort zum setzen des modus folgendes:
    TCCR1A|= (1<<WGM10);
    TCCR1A|= (1<<WGM11);
    TCCR1B|= (1<<WGM12);
    TCCR1B|= (1<<WGM13);

    warum werden wgm10 und wgm 11 in TCCR1A gesetzt und
    wgm12 und wgm13 in TCCR1B ?????
    im datenblatt kann ich dazu nichts finden.


    >>Wenn der Counter1 auf einen Zahl = einem der 3 Register kommt, wird >>ein Ausgang gesetzt oder gelöscht,
    Ist das dann immer der ausgang der zu dem timer gehört???
    in meinem fall (OC3A/AIN1) = PE3??

    >>Bei welcher Frequenz betreibst du den AVR eigentlich?
    mit 4 mhz;start-up time: 6 ck + 64ms
    schon kommt die nächte frage:
    wo ist der unterschied zwischen 6ck +0ms, 6ck +4ms und 6ck +64ms??


    So ich glaube ich mache jetzt hier erstmal schluss und
    freue mich schon auf eine antwort.
    ich hoffe das du nicht verzweifelst wenn du meine fragen liest.

    gruß und ein schönes wochenende

    orko

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    22.09.2006
    Ort
    Nürnberg
    Alter
    27
    Beiträge
    66
    @RCO
    Ich hätte auch eine Frage dazu:
    ich benutze zwar das Mega2650, aber im Prinzip dürfte das ja das gleiche sein.

    Wenn ich z.B. Timer1 nehme, wie kann ich einstellen, welcher Pin (A,B oder C) dann geschalten wird? und wie lege ich für diese Pins einen Vergleichswert fest?

    Bene
    Wer Visionen hat, sollte zum Arzt gehen.
    Helmut Schmidt

    Unsere Webseite: GMG Robotik

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Zitat Zitat von orko512
    verstehe ich das richtig:
    wenn an den pins OC0 steht dann sind die für Timer0?
    entsprechend für die anderen TimerX.
    Genau.

    Zitat Zitat von orko512
    danach hätte ich einen
    timer0 mit einen ausgang (oc0)
    timer1 mit drei ausgängen (oc1a, oc1b, oc1c)
    timer2 mit einem ausgang (oc2)
    timer3 mit drei ausgängen (oc3a, oc3b, oc3c)

    also insgesamt 4 timer.
    Genau, deshalb steht im Datenblatt auch 8 PWM-Channels.

    Zitat Zitat von orko512
    wenn ich das richtig verstehe ist das nun abhängig vom modus.
    modus 5 = 8bit = 256
    modus 6 = 9bit = 512
    modus 7 = 10bit = 1024

    in der tabelle61 auf seite 135 steht nun welche bits ich in den timer laden muss damit ich den entsprechenden modus setze.
    richtig??????

    für modus 7:
    WGMn3 = 0
    WGMn2(CTCn) = 1
    WGMn1(PWMn1) = 1
    WGMn0(PWMn0) = 1

    das bedeutet = Fast PWM, 10-bit

    wie sieht das jetzt softwaretechnisch aus??
    ich möcht timer1 benutzen.
    er soll in modus 7 betrieben werden.
    Zitat Zitat von orko512
    nun gleich noch ne frage:
    wenn ich mir so einige beispiele anschaue finde ich dort zum setzen des modus folgendes:
    TCCR1A|= (1<<WGM10);
    TCCR1A|= (1<<WGM11);
    TCCR1B|= (1<<WGM12);
    TCCR1B|= (1<<WGM13);
    Genau so gehts. Man kann es allerdings kompakter schreiben:
    TCCR1A = (1<<WGM11) | (1<<WGM10);
    TCCR1B = (1<<WGM12);

    Zitat Zitat von orko512
    warum werden wgm10 und wgm 11 in TCCR1A gesetzt und
    wgm12 und wgm13 in TCCR1B ?????
    im datenblatt kann ich dazu nichts finden.
    Warum? Keine Ahnung. Wo du was setzten muss, findest du aber im Datenblatt (Seite 133 und 136).
    Es gibt auch noch eine Übersicht auf Seite 365ff.

    Zitat Zitat von orko512
    >>Wenn der Counter1 auf einen Zahl = einem der 3 Register kommt, wird >>ein Ausgang gesetzt oder gelöscht,
    Ist das dann immer der ausgang der zu dem timer gehört???
    in meinem fall (OC3A/AIN1) = PE3??
    Genau. Das passiert natürlich nur, wenn die Register so eingestellt sind, dass die Pins gesetzt werden sollen.
    Vielleicht möchte man ja auch nur einen Interrupt auslösen und den PWM garnicht nutzen.
    Was mit den Pins passiert, kann man für OC1A über COM1A1 und COM1A0 einstellen (siehe seite 134).
    Das werden wir auch noch machen müssen.

    Zitat Zitat von orko512
    ich schaue in das datenblatt und komme nicht weter.
    ich finde Timer/Counter1 Control und
    Timer/Counter3 Control
    gibt es denn mehrere??
    Timer1 und Timer3 werden quasi genau gleich angesteuert.
    Das kleine n ist dann durch 1 oder 3 zu ersetzen.

    Zitat Zitat von orko512
    >>Bei welcher Frequenz betreibst du den AVR eigentlich?
    mit 4 mhz;start-up time: 6 ck + 64ms
    schon kommt die nächte frage:
    wo ist der unterschied zwischen 6ck +0ms, 6ck +4ms und 6ck +64ms??
    Ich weiß leider nicht, was mit 6ck + 64ms gemeint ist. ck steht für cycles, aber sonst...
    4Mhz ist das Entscheidende.

    OK, wenn ich nichts übersehen habe, sollte das hier zur Initialisierung des Timers reichen:

    TCCR1A = (1<<WGM11) | (1<<WGM10) | (1<<COM1A1) | (1<<COM1B1) | (1<<COM1A0) | (1<<COM1B0);
    TCCR1B = (1<<WGM12) | (1<<CS11);

    OCR1AH = 0;
    OCR1AL = 128;
    OCR1BH = 0;
    OCR1BL = 128;

    WGM setzt den entsprechenden Modus (10-Bit Fast-PWM), COM regelt das Setzen/Löschen der Pins:
    "Set OCnA/OCnB/OCnC on compare match, clear OCnA/OCnB/OCnC at BOTTOM, (inverting mode)"

    CS regelt den Prescaler. Hier ist nur CS11 gesetzt. Aus der Tabelle auf Seite 137 entnehmen mir nun,
    dass CS11 bedeutet, dass der Takt durch 8 geteilt wird.
    ==> 4 Mhz / 8 = 500 kHz
    Der Timer wird allso alle 1/500k s erhöht.
    Da der Timer auf 10 Bit (1024) gesetzt ist, ergibt sich eine Frequenz von 500k/1024 Hz (=488,28... Hz).

    Mit welcher Frequenz du einen Motor am besten ansteuert weiß ich leider nicht.

    OCR setzt den Wert an dem der Ausgang gesetzt wird. Der "inverting mode" eignet sich eignetlich nicht so gut für deinen Zweck,
    war aber einfacher als Erklärung.

    OK, soweit alles klar?

    @Bene: Ich hoffe, dass das was ich oben geschrieben hat dir weiterhilft.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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