Go Down

Topic: PWM Arduino (Read 2252 times) previous topic - next topic

lota

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


freeduino.de

hallo, ich mag mich irren, aber wird bei PWM nicht nur die pulsweite der frequenz variiert und nicht die frequenz selber?

lota

#2
Feb 11, 2009, 09:34 am Last Edit: Feb 11, 2009, 09:34 am by lota Reason: 1
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

lota

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

e2hmqvh

Vielen Dank für die Informationen! :-)

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

Go Up