- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 17

Thema: Timer und PWM

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    38
    Beiträge
    199

    Timer und PWM

    Anzeige

    Powerstation Test
    Moin!!! Ich lese mich grade durch den artikel AVR PWM auf der Seite www.microcontroller.net und bin grade bei "Clear Timer on Compare".
    Für mich klingt völlig logisch das man den Takt der vom Prescaler kommt damit bequem teilen kann. Ich mache mir nur die ganze Zeit gedanke, weil da steht:
    Für PWM:

    Wenn eingestellt ist, dass der OC-Ausgang bei jedem Match umschaltet (toggle), entspricht der eingestellt Wert dem Pulsweitenverhältnis. Bei OCRnx=128 des 8 Bit T/C wäre also etwa die Hälfte der Zeit der Pin eingeschaltet.
    Meiner meinung nach ist das keine PWM, da die einschalt und ausschaltzeit doch immer 1:1 ist.
    Wenn der zähler z.B. bis 128 zählt und der OC-Ausgang ausschaltet, läuft der Zähler doch neu los und der OC-Ausgang schaltet auch bei 128 wieder ein (toggle halt).

    Dadrunter kommt dann gleich der Abschnitt
    Fast PWM.
    Dort steht
    Zählt von BOTTOM bis TOP, wobei TOP entweder 0xFF oder OCRnx sein kann.

    Bei einem Match wird im

    a) nicht-invertierenden Modus der Zähler gelöscht, und bei BOTTOM gesetzt

    b) invertierenden Modus der Zähler gesetzt, und bei BOTTOM gelöscht.

    Klingt theoretisch kompliziert, praktisch invertiert es nur den Ausgang.
    Dazu:
    Was heißt der Zähler wird gelöscht? Oder soll das heißen der Ausgang wird z.B. im nicht-invertierendem modus bei Match auf 0 gesetzt, bei Bottom wieder auf 1? Dann wäre das ja auf jeden Fall eine PWM, falls der Zähler dann bis 0xff weiterzählt bevor er wieder bei Bottom anfängt.

    Hoffe ihr habt meine Frage überhaupt verstanden
    MfG Jan

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    38
    Beiträge
    199
    Hab hier jetzt mal ein kleines Programm geschrieben. Funktioniert natürlich mal wieder gar nix!!!

    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #define CPU_F 1000000UL
    
    int main(void)
    {
    while(1)
      {
      DDRB |= (1<<DDB3);		//Damit ist PB4 (OC0 PWM-Ausgang) als Ausgang gesetzt
      PORTB |= (1<<PB3);
    
      TCCR0 |= ((1<<WGM00) | (1<<WGM01));		//hier stelle ich Modus 3 ein (fast PWM)
      TCCR0 |= ((1<<COM00) | (1<<COM01));		//Set OC0 on Compare Match, Clear OC0 on Top
      TCCR0 |= ((1<<TSC00) | (1<<TSC02));		//Takt kommt vom Vorteiler (prescaler) setzt
    											//die ZählerFrequenz auf ca. 1kHz (teilung durch 1024)
      TCNT0 = 0xff;	//Zähler soll von 0 bis 255 zählen
      OCR0 = 0x80;	//Match soll bei 128 erfolgen, Match ist doch aber gleich Top, oder?
    				//(bottom = 0), (Match = 128), (Top=Max=255)???
      }
    }
    
    //LED müsste ca. halb hell leuchten
    Kann mir jemand sagen wieso? Kann mir jemand was zu meinem Beitrag oben sagen, stimmen die Kommentare?
    Hoffe irgendjemand kann mir helfen.
    MfG Jan

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Hallo Jan,
    dann unterhalten wir zwei uns mal wieder

    CTC hast Du recht, dieser Modus ist eigentlich nicht dazugedacht PWM zu erzeugen, sonder einen ziemlich genauen Takt.
    PWM kommt erst richtig gut, wenn der Timer frei durchlaufen kann, und Du nur die Pulsweite mit OCR verstellst...
    Fast PWM...
    Ja ich benutze den eigentlich nur, die anderen sind mir zu kompliziert
    Aber auf die schnelle erklärt:
    Du kannst Ihn einstellen, daß der Ausgang bei Bottom HIGH geht, und bei Comparematch LOW, das wäre dann der normale Modus, oder aber bei Bottom LOW und bei Compare Match HIGH das wäre dann der invertierte Modus...
    Uff, ich hoffe, daß es soweit richtig ist, habe im Moment keine Lost Dattenblatt rauszuholen...
    Zu deinem Programm,
    mach den Timerinit außerhalb der while(1) Schleife, so ist das Käse, ich weiß nicht, ob er das mag ständig eingestellt zu werden
    Den TCNT0 würde ich auch in Ruhe lassen.
    Gruß Sebastian
    P.S. Was hast Du für Kontroller, bist Dir sicher, daß der Timer 0 PWM hat ?
    P.P.S Hm, wird wohl so sein, wenn der Kompiler nicht jamert...
    Software is like s e x: its better when its free.
    Linus Torvald

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    38
    Beiträge
    199
    Jetzt hab ich wieder ein richtig blödes Problem.
    Hab einen Neuen Ordner angelegt. Da hab ich mein Prog (pwm.c) reingespeichert. Hab mir einen neuen Makefile gemacht (die gleichen einstellungen wie beim alten) und den auch da rein gespeichert.
    Wenn ich auf Makeall drücke kommt die Meldung:

    make.exe: *** No rule to make target `obj/main.o', needed by `pwm.elf'. Stop.

    > Process Exit Code: 2
    > Time Taken: 00:01

    Das is bestimmt wieder was richtig blödes. Aber ich komm wieder nicht klar.

    Der Code jetzt:

    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #define F_CPU 1000000UL
    
    int main(void)
    {
    DDRB |= (1<<DDB3);		//Damit ist PB4 (OC0 PWM-Ausgang) als Ausgang gesetzt
    PORTB |= (1<<PB3);
    
    TCCR0 |= ((1<<WGM00) | (1<<WGM01));		//hier stelle ich Modus 3 ein (fast PWM)
    TCCR0 |= ((1<<COM00) | (1<<COM01));		//Set OC0 on Compare Match, Clear OC0 on Top
    TCCR0 |= ((1<<TSC00) | (1<<TSC02));		//Takt kommt vom Vorteiler (prescaler) setzt
    											//die ZählerFrequenz auf ca. 1kHz (teilung durch 1024)
    
    while(1)
      {
      
      OCR0 = 0x80;	//Match soll bei 128 erfolgen, Match ist doch aber gleich Top, oder?
    				//(bottom = 0), (Match = 128), (Top=Max=255)
      }
    }
    
    //LED müsste ca. halb hell leuchten
    Ach ja. Ich hab ein ATMega32
    Im datenblatt steht 8-bit Timer/Counter0 with PWM.

    Bis jetzt bin ich ja immer gut ums Datenblatt rumgekommen, aber heut hab ich´s echt mal gelesen

    MfG Jan

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    make.exe: *** No rule to make target `obj/main.o', needed by `pwm.elf'. Stop.
    main.o pwm.elf ist hier nicht was faul ??
    Ach ja OCR0 kannst Du auch aus der main werfen...
    Ehm und TCCR0 könntest Du auch in einer Zeile setzen, dann aber ohne |
    Das ist gut ins Dattenblatt zu schauen, man muß nicht unbedingt alle Seiten Lesen, nur das was einen interessiert...
    Gruß Sebastian

    P.S. Dein Programm sieht schon nicht schlecht aus, man sieht, das Du Dattenblatt gelesen hast
    P.P.S die DDR Register kannst Du auch ohne | setzen.
    Software is like s e x: its better when its free.
    Linus Torvald

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    38
    Beiträge
    199
    Ja, würde nur gern wissen was da schon wieder faul ist.
    ORC0 aus der main werfen?
    Du meinst sicher aus der While-schleife, oder?
    TCCR0 in eine Zeile ohne | ?
    So?
    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #define F_CPU 1000000UL
    
    int main(void)
    {
    DDRB = (1<<DDB3);	//geaendert
    PORTB |= (1<<PB3);
    
    TCCR0 |=(1<<WGM00)(1<<WGM01)		
    		(1<<COM00)(1<<COM01)      //geaendert
    		(1<<TSC00)(1<<TSC02);	
    										
    OCR0 = 0x80;      //geaendert
    
    while(1)
      {
      }
    }
    
    //LED müsste ca. halb hell leuchten
    MfG

    P.S. Wenn ich mein Programm als main.c speichere geht das alles mit brennen und so. Jetzt Funzt alles aber man sieht die LED sogar blinken. Ich probiers mal mit ner kleineren vorfrequenzteilerzahl.

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    38
    Beiträge
    199
    Was jetzt noch cool wäre, wäre wenn die led heller und dunkler werden würde. Ich kann ja leider keine variable nehmen, die ich von 00 bis ff hochzählen kann. Da gibts doch bestimmt etwas, oder?

    Gruß Jan

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Du meinst sicher aus der While-schleife, oder?
    Ja das meinte ich (vielleicht sollte man nicht zu viel gleichzeitig machen...)
    Code:
    PORTB |= (1<<PB3); 
    
    TCCR0 |=(1<<WGM00)(1<<WGM01)       
          (1<<COM00)(1<<COM01)      //geaendert 
          (1<<TSC00)(1<<TSC02);
    Warum veroderst Du alles?
    Code:
    PORTB = (1<<PB3); 
    
    TCCR0 =(1<<WGM00)(1<<WGM01)       
          (1<<COM00)(1<<COM01)      //geaendert 
          (1<<TSC00)(1<<TSC02);
    So finde ich das schon besser....
    Ich kann ja leider keine variable nehmen, die ich von 00 bis ff hochzählen kann. Da gibts doch bestimmt etwas, oder?
    Warum kannst Du keine Variablen nehmen ?

    Code:
    uint8_t pwm=0;
    while(1){
    OCR0 =pwm++;
    _delay_ms(10);
    }
    zum Beispiel...
    oder ?
    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    38
    Beiträge
    199
    Aber mit der PWM Variablen wird doch dezimal hochgezählt. Kann das Register OCR0 denn z.B. mit 250 was anfanden? Wenn ja, woher weiß das denn, wenn ich OCR0 = 80; schreibe, ob ich dezimal 80 oder hexadezimal 80 (was ja dezimal 128 sind) meine? Oder nimmt das die informationen aus der Variablen, und weis dadurch das die uint ist das das dezimal ist?
    Oder denke ich nur wieder zu konfus?

    Gruß Jan

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Oder denke ich nur wieder zu konfus?


    Wenn Du OCR0 = 80 schreibst wird der dezimale Wert geschrieben,
    Wenn Du OCR0 = 0x80 schreibts wird hex 0x80 dez 128 geschrieben
    Im Endefekt ist es doch egal ob so oder so, wenn es Spaß macht kannst Du mein Beispiel von oben hexadezimal schreiben
    Code:
    uint8_t pwm=0x00; 
    while(1){ 
    OCR0 =pwm++; 
    _delay_ms(10); 
    }
    Der Kompile weiß anhand 0x wie Du das meinst
    Software is like s e x: its better when its free.
    Linus Torvald

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad