-         

Ergebnis 1 bis 10 von 10

Thema: Problem mit Fast PWM an Timer2

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    24.09.2006
    Ort
    Nähe Mannheim
    Beiträge
    269

    Problem mit Fast PWM an Timer2

    Anzeige

    Hi
    Ich benötige eine PWM mit mehr als 25kHz, deswegen müsste ich die Fast PWM mit Timer2 benutzen.
    Der verwendete Chip ist ein Atmega32 mit externen 8Mhz Quarz.
    Die entsprechenden Einstellungen des TCCR2 habe ich gefunden aber es funktioniert nicht ?
    Zum testen habe ich eine LEd mit einem 1k vorwiederstand am OC2 ausgang.

    TCCR2 = 0110 1001
    ist: Fast PWM, Prescaler = 1, non-inverting mode
    Zufinden auf Seite 125/126 im Datenblatt des Atmega32
    Die LED macht nun garnix -_-
    Weswegen ist mir ein totales Rätsel.

    Mit diesen einstellungen gehts:
    TCCR2 = 0110 0001
    ist: Phase Correct PWM (sozusagen normal), non-inverting mode, prescaler =1

    Was hab ich vergessen zu ändern ?
    Im Datenblatt habe ich nichts weiteres finden können was zur behebung des Problems helfen könnte -_-

    Mein Testprogramm besteht nur aus den Grundeinstellungen und dem Befehl: Portd = output ;P
    Wie gesagt mit den standard einstellungen (das zweite) geht es einwandfrei aber viel zu langsam (ca 15kHz)

    mfg

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    705
    Mein Testprogramm besteht nur aus den Grundeinstellungen und dem Befehl: Portd = output
    Dann hast Du OCR2 auch nicht auf einen anderen Wert als 0x00 gesetzt?

    Im Fast-PWM-Modus (und COM21:0 = &B10) wird der OC-Ausgang gesetzt wenn der Zähler auf 0X00 überläuft, und resettet wenn er OCR2 erreicht.

    Ist OCR2 also 0X00, wird OC2 immer auf LOW bleiben.

    Setz doch mal OCR2 auf 128 oder so - dann müsstest Du ein schönes Rechtecksignal bekommen!

    Gruß & Co

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    24.09.2006
    Ort
    Nähe Mannheim
    Beiträge
    269
    Arrrg,.. sorry vergessen hinzuschreiben

    OCR2 = 100
    Steht auch mit drin ;P

    Aber danke für die antwort ^^

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    705
    Dann habe ich so auf Anhieb auch keine Idee... aber Respekt für die Uhrzeit Deines letzten Beitrags - das Problem scheint Dir ja keine Ruhe zu lassen

    Wenn mich ein Geisteblitz ereilt, sag´ ich Bescheid...

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.03.2006
    Ort
    WOB
    Beiträge
    630
    Oha, das kenn ich wenn man bis 4 oder 5 Uhr bastelt und sucht...

    Also ich hatte auch Probleme mit einem PWM für ne Displaybeleuchtung neulich. Das war so, dass es in einem bestimmten Modus nicht ging, in anderem Schon. folgendes allerdings geht super:

    (achtung, es ist C und ein AT90CAN12 Aber mit was anderem kann ich dir nicht helfen. Ich denke in der Sache ist es egal

    Aufruf:
    Code:
     // Init PWM interface
      if(initPWM(fast,non_inv,div8));
        else return false;
    Funktion:
    Code:
    /*****************************************************************************
    *
    * Temperature Unit Firmware
    * - PWM functions for display-background-LED
    *
    * Compiler : avr-gcc 4.3.0 / avr-libc 1.6.2 / AVR Studio 4.14
    * size     : 2,70KB
    * by       : Thomas Fuchs, Wolfsburg, Germany
    *            thomas.fuchs@cc-robotics.de
    *
    * License  : Copyright (c) 2009 Thomas Fuchs
    *
    * Tested with AT90CAN128
    ****************************************************************************/
    #include <stdbool.h>
    #include "utils.h"
    #include "pwm.h"
    
    uint8_t PWM_Timer_temp = 0; // save the operation during hard on/off
    
    // Init PWM
    
      /* defines
      #define normal 0
      #define phase_correct 1
      #define fast 2
    
      #define non_inv 0
      #define inv 1
      #define off 2
    
      #define no_div 0
      #define div8 1
      #define div64 2
      #define div256 3
      #define div1024 4
      */
    bool initPWM(uint8_t mode, uint8_t operation, uint8_t clk_div)
    {
      PWM_Value = 0;
      PWM_Timer = 0;
      PWM_DDR |= _BV(PWM_Pin);
    
      switch (mode)
      {
        case 0:
          break;
    
        case 1:
    	  PWM_Timer |= (1<<WGM00);
          break;
    
    	case 2:
          PWM_Timer |= (1<<WGM00);
    	  PWM_Timer |= (1<<WGM01);
          break;
    
    	default:
    	  return false;
      }
    
      switch (operation)
      {
        case 0:
          PWM_Timer |= (1<<COM0A1);
          break;
    
    	case 1:
    	  PWM_Timer |= (1<<COM0A0);
          PWM_Timer |= (1<<COM0A1);
          break;
    
        case 2:
          break;
    
    	default:
    	  return false;
      }
    
      switch (clk_div)
      {
        case 0:
          PWM_Timer |= (1<<CS00);
          break;
    
        case 1:
          PWM_Timer |= (1<<CS01);
          break;
    
        case 2:
          PWM_Timer |= (1<<CS00);
          PWM_Timer |= (1<<CS01);
          break;
    
        case 3:
          PWM_Timer |= (1<<CS02);
          break;
    
        case 4:
          PWM_Timer |= (1<<CS00);
          PWM_Timer |= (1<<CS02);
          break;
    
    	default:
    	  return false;
      }
    return true;
    }
    
      // PWM dimm
    
      /* defines
      #define soft_off 0
      #define soft_on 1
      #define hard_off 2
      #define hard_on 3
      */
    
    void dimmPWM(uint8_t function)
    {
      uint8_t i;
    
      switch (function)
      {
        case 0:
          for (i=255; i>0; i--) // 255 must be configurated value from EEPROM
          {
            PWM_Value = i;
            delay_ms(8);   // delay 10 ms
          }
          break;
    
        case 1:
          for (i=0; i<255; i++) // 255 must be configurated value from EEPROM
          {
            PWM_Value = i;
            delay_ms(8);   // delay 10 ms
          }
          break;
    
        case 2:
          PWM_Timer_temp = (PWM_Timer&0x30);
    	  PWM_Timer &= 0xCF;
          break;
    
    	case 3:
    	  PWM_Timer |= PWM_Timer_temp;
          break;
    
    	default:
    	  return;
      }
    }
    header zu pwm.c:
    Code:
    /*****************************************************************************
    *
    * Temperature Unit Firmware
    * - header file of pwm.c
    *
    * Compiler : avr-gcc 4.3.0 / avr-libc 1.6.2 / AVR Studio 4.14
    * size     : 953Bytes
    * by       : Thomas Fuchs, Wolfsburg, Germany
    *            thomas.fuchs@cc-robotics.de
    *
    * License  : Copyright (c) 2009 Thomas Fuchs
    *
    * Tested with AT90CAN128
    ****************************************************************************/
    #define PWM_DDR DDRB
    #define PWM_Pin 7
    #define PWM_Timer TCCR0A
    #define PWM_Value OCR0A
    
      // Init PWM
    #define normal 0
    #define phase_correct 1
    #define fast 2
    
    #define non_inv 0
    #define inv 1
    #define off 2
    
    #define no_div 0
    #define div8 1
    #define div64 2
    #define div256 3
    #define div1024 4
    
      // PWM dimm
    #define soft_off 0
    #define soft_on 1
    #define hard_off 2
    #define hard_on 3
    
    extern void delay_ms(uint16_t period);	 //delay routine (milliseconds)
    Ich hoffe das hilft dir!
    Gruß Thomas \/

    Alles über AVR, PIC und CAN
    blog.cc-robotics.de

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.111
    So wie da steht, müsste es eigentlich richtig sein. Ich schätze, es leigt am restlichen Code.
    Ohne den kann man wohl kaum weiterhelfen.
    Gruß

  7. #7
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    24.09.2006
    Ort
    Nähe Mannheim
    Beiträge
    269
    Boar das letzte mal wo ich was mit C gemacht habe ist etwa 6 Jahre her und das war C++ im 3D Gamestudio xD
    Eherlich gesagt habe ich nicht ganz kapiert was du da macht, zum Teil habe ich mir mal das Toturial im Wissen bereich durchgelesen. Also im Endeffekt machst du ja nicht viel anders als ich ;P
    Danke für die Antwort ;P


    Das Problem habe ich nicht gefunden aber ich habe es zum laufen gebracht (31kHz).
    Vorher: TCCR2 = 01101001
    Jetzt: TCCR2 = 105
    Das ist genau das gleiche nur eben in Dezimal
    HEX wollte Bascom irgendwie nicht,.. neija was solls nun funktioniert es ^^

    Danke leute ;P

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.111
    Deswegen wollte ich ja den Code sehen.
    Ich weiß nicht, wie es in Bascom ist, aber in C hieße es richtigerweise:
    Code:
    TCCR2 = 0b01101001;
    Das ist übrigens binär und nicht hex. Die Kennzeichnung ist natürlich wichtig. Wie sollte der Compiler auch wissen, ob das jetzt binär ist oder decimal oder was auch immer??? Ohne "0b" würde die Zahl dahinter als oktal interpretiert...
    Daher sollte man immer den relevanten und korrekten Code posten, so, wie er im Programm steht.
    Gruß

  9. #9
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    24.09.2006
    Ort
    Nähe Mannheim
    Beiträge
    269
    Verdammt jetzt ist mir einiges klar xD
    Das es kein Hex ist sondern Binär ist mir schon bewusst ;P Aber warum hat es dann mit dem Modus 2 funktioniert ?
    Hab ja den original Code gepostet ^^

    Jetzt ist mir immerhin der Fehler klar, danke ;P
    Das passiert mir garantiert nicht mehr xD
    mfg



    In Bascom:
    TCCR2 = &B01101001

  10. #10
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.03.2006
    Ort
    WOB
    Beiträge
    630
    hex: 0xF3
    bin: 0b01110101010
    dez: 231

    immer dran denken
    Gruß Thomas \/

    Alles über AVR, PIC und CAN
    blog.cc-robotics.de

Berechtigungen

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