Arduino Forum

Forum 2005-2010 (read only) => International => Deutsch => Topic started by: lota on Feb 10, 2009, 10:14 pm

Title: PWM Arduino
Post by: lota on Feb 10, 2009, 10:14 pm
Hallo,
Ich bin noch neu hier.
Ich habe ein Arduino mit Display und Taster. Dazu hab ich auch einen open source code. Als Frequenzgenerator. Der läuft als Software PWM. 0 bis 1Mhz. Nun möchte ich noch zwei zusätzliche PWM Frequenzen erzeugen. Eventuel als hardware PWM. Wenn es geht auch noch veränderbar über die Taster.
Hat jemand Lust mir dabei zu helfen? Ich hab da keinen Durchblick. Einiges hab ich schon probiert, aber ich kenne mich zu wenig aus. Die Suche im Netz hat auch nicht sehr viel gebracht.
Gruß
Lorenz

Title: Re: PWM Arduino
Post by: bara.munchies on Feb 11, 2009, 02:57 am
hallo, ich mag mich irren, aber wird bei PWM nicht nur die pulsweite der frequenz variiert und nicht die frequenz selber?
Title: Re: PWM Arduino
Post by: lota on Feb 11, 2009, 09:34 am
Hallo,
das stimmt. Normaler weise wird die Pulsweite verändert. Deshalb schrieb ich ja auch Frequenzgenerator. Ich brauch aber noch zwei Rechtecksignale. Die könnte man ja als PWM erzeugen.

Gruß Lorenz
Title: Re: PWM Arduino
Post by: lota on Feb 20, 2009, 08:48 pm
Hallo,
ich hebe hier mal den Code von Timer1 auf Timer2 geändert. Läuft aber nicht. Hat da mal wer einen Tipp warum das so nicht geht?
Code:
unsigned int SetPwm(long lFrequency, int iDuty)
{
 lFrequency *= 2;//When using phase correct mode, you get 1/2 speed waves
 const int DIGITAL_PIN = 9;//this is the digital output pin to use, it can be set to 9 or 10
 const long CPU_FREQUENCY = 16000000;//16MHz
 const int NUM_PRESCALERS = 5;
 const int aiPRESCALER[NUM_PRESCALERS] = {
   1,8,64,256,1024        };
 long alFrequency[NUM_PRESCALERS];//used to store frequency results of different prescalers
 long alCouterTop[NUM_PRESCALERS];//used to store counter top values of different prescalers
 float fPeriod = 1 / (float)lFrequency;//desired period in seconds

 //Initialise only once:
 static bool bOnce = true;
 if(bOnce)
 {
   bOnce = false;

     //Select desired output pin

     sbi(TCCR2A, COM2A1);
   
   

   //Set PWM Type

   sbi(TCCR2B, WGM22);
   sbi(TCCR2A, WGM21);
   sbi(TCCR2A, WGM20);

   //Start PWM2
   
   pinMode(PIN_PWM_OUTPUT, OUTPUT);
 }

 //  Try all different prescalers
 for(int i = 0; i < NUM_PRESCALERS; i++)
 {
   float fQuanta = aiPRESCALER / (float)CPU_FREQUENCY;//counter granularity in seconds
   alCouterTop = fPeriod / fQuanta;
   if(alCouterTop > 256)
     alCouterTop = 256;//limit to 16 bits
   alFrequency = 1 / (fQuanta * alCouterTop);
 }

 //  Look for best prescaler
 int iIndex = 0;
 long lSmallestError = 1000000;
 for(int j = 0; j < NUM_PRESCALERS; j++)
 {
   long lError = (abs)(lFrequency - alFrequency[j]);
   if((lSmallestError > lError))
   {
     if(alCouterTop[j] >= 4)
     {
       lSmallestError = lError;
       iIndex = j;
     }
   }
 }

 //  Configure the prescaler
 switch (iIndex)
 {
 default:
 case 0:// 001 = /1
   cbi(TCCR2B, CS22);
   cbi(TCCR2B, CS21);
   sbi(TCCR2B, CS20);
   break;
 case 1:// 010 = /8
   cbi(TCCR2B, CS22);
   sbi(TCCR2B, CS21);
   cbi(TCCR2B, CS20);
   break;
 case 2:// 011 = /64
   sbi(TCCR2B, CS22);
   cbi(TCCR2B, CS21);
   cbi(TCCR2B, CS20);
   break;
 case 3:// 100 = /256
   sbi(TCCR2B, CS22);
   sbi(TCCR2B, CS21);
   cbi(TCCR2B, CS20);
   break;
 case 4:// 101 = /1024
   sbi(TCCR2B, CS22);
   sbi(TCCR2B, CS21);
   sbi(TCCR2B, CS20);
   break;
 }

 //set PWM2 top
 OCR2A = alCouterTop[iIndex];

 //set PWM duty
 float fDuty = (OCR2A / (float)100);
 iDuty = fDuty * iDuty;
 OCR2B = iDuty;
 
}

Schönes Wochenende!
Lorenz
Title: Re: PWM Arduino
Post by: e2hmqvh on Feb 28, 2009, 05:11 pm
Vielen Dank für die Informationen! :-)

PS: 1 Post, damit ich Bilder Posten kann...  >:(