mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AT91SAM7S Multichannel-PWM


Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.
Ich habe folgendes Problem. Ich benutze 2 PWM-Kanäle. Mit einem wird ein
Motor betrieben mit dem andren erfolgt eine Sinusausgabe. Sobald beide
Kanäle aktiv sind halbiert sich die Sinusfrequenz. Wenn aber nur der
Sinus-PWM-Kanal läuft, ist die Sinusfrequenz OK. Hier der Quellcode:

in main:
 
PWM_Init(MOTOR_PWM);
PWM_Init(SINE_PWM);


in PWM.c :
void PWM_Init(unsigned int channel)
{   
    // Enable Periphal clock in PMC for PWMC
    AT91F_PWMC_CfgPMC();
    
    // Configure PIO controllers to drive PWM signals
    AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,          
                     ((unsigned int) AT91C_PA0_PWM0) |  
                     ((unsigned int) AT91C_PA1_PWM1) |      
                     ((unsigned int) AT91C_PA2_PWM2),  
         ((unsigned int) AT91C_PA7_PWM3));   
    switch (channel)
    {
     // Motor PWM
     case 0:  // Stop PWM Channel 0
     AT91F_PWMC_StopChannel(AT91C_BASE_PWMC, AT91C_PWMC_CHID0);
     AT91C_BASE_PWMC_CH0->PWMC_CMR = MCKtoPWM | CPD_OFF | CPOL_ON | CALG_ON;

     // setup the period registers
     AT91C_BASE_PWMC_CH0->PWMC_CPRDR = P_MOTOR;

     // setup the duty cycle registers (first value)
     AT91C_BASE_PWMC_CH0->PWMC_CDTYR = P_MOTOR/3;

     //enable PWM channel 0
     AT91F_PWMC_StartChannel( AT91C_BASE_PWMC, AT91C_PWMC_CHID0);
     break;
  
     // PWM  (sine wave)
     case 1: // Stop PWM Channel 1
     AT91F_PWMC_StopChannel(AT91C_BASE_PWMC, AT91C_PWMC_CHID1);
      
     // setup sine wave
     //PWM_InitSinewave();

     // setup the channel mode registers
     AT91C_BASE_PWMC_CH1->PWMC_CMR = MCKtoPWM | CPD_OFF | CPOL_ON | CALG_ON;

     // setup the period registers
     AT91C_BASE_PWMC_CH1->PWMC_CPRDR = EXT_OSC / SINE.PWMFREQ1 / 2;

     // setup the duty cycle registers (first value)
     AT91C_BASE_PWMC_CH1->PWMC_CDTYR = EXT_OSC / SINE.PWMFREQ1 / 4;

     // Prevent any bad state of this register: Read it clear all set bit
     AT91C_BASE_PWMC->PWMC_ISR;

     AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,
                           AT91C_ID_PWMC,
                           AT91C_AIC_PRIOR_HIGHEST,
                           AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,
                           PWM_Interrupt);
   
     AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_PWMC);  
     //enable PWM channel 1
     AT91F_PWMC_StartChannel( AT91C_BASE_PWMC, AT91C_PWMC_CHID1 );
    
     AT91F_PWMC_InterruptEnable(AT91C_BASE_PWMC,AT91C_PWMC_CHID1);
     break;
    }
}


Wo könnte das Problem liegen? Wie gesagt wenn nur der Sinuskanal aktiv
ist ist die Sinusfrequenz richtig.

Autor: Philipp Aigner (st0ne)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,

ich weiß zwar leider das problem nicht warums nicht geht, aber du 
könntest mir nicht den gesammten source zukommen lassen? oder zumindest 
den teil für die pwm-sinus generation mit sinus tabelle? da ich genau 
das mit einem at91sam7 machen möchte :-)

danke
gruß st0ne

Autor: Max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gibt es denn beim multichannelbetrieb was besonderes zu beachten?


@ Phil Nachname
void PWM_Interrupt(void) 
{
  static unsigned int cnt=0;

    // update PWM Register
        AT91F_PWMC_UpdateChannel(AT91C_BASE_PWMC, SINE_PWM, SINE.TABLE_1[cnt]);
      // It is forbidden to continue before updating of the PWM period
      while(AT91C_BASE_PWMC->PWMC_ISR != AT91C_PWMC_CHID1); 
      cnt++;

  if (cnt == SINE.SAMPLES)
  {
    cnt = 0;
  }
}
void PWM_InitSinewave(void)
{
  unsigned char i;
  double helpFreq1;

  SINE.PWMFREQ1 = (SINE.FREQ1 * SINE.SAMPLES);  // [Hz] - sinewave 1 with n sampling points

  for(i=0; i<SINE.SAMPLES; i++) //SINE.SAMPLES=13 also 13 unterschiedliche Tastverhältnisse
   {
    helpFreq1=((2*PI*SINE.FREQ1)/SINE.PWMFREQ1)*i;
   SINE.TABLE_1[i]=(SINE.GAIN/100)*(sin(helpFreq1)+1)*0.5*((EXT_OSC/SINE.PWMFREQ1)/2);
   }  
}

Autor: Max (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem mit der halben Frequenz wurde behoben.
Jetzt gibt es aber ein anderes Problem.
Also ich benutze 4-PWM-Kanäle PA0(LED), PA1(Sinus), PA2(LED) und
PA7(Motor).
Das Sinussignal wird mit Interrupts erzeugt. D.h. es wird immer ein Wert
der Sinustabelle während des PWM-Interrupts in das CUPDR-Register
geschrieben(Code ist im Anhang).
Dabei tritt bei mir folgendes Problem auf: wenn alle PWM-Kanäle (oder
sogar wenn 2) aktiv sind zittert das Sinussignal. Wenn aber nur der
Sinus-PWM-Kanal aktiviert ist, ist  der Sinus stabil.
In Interruptroutine habe ich ein Triggersignal(PA15) für den Oszilloskop
integriert. Diesem ist anzusehen, dass es auch zittert. Daraus schliesse
ich, dass es beim Interruptaufruf Unregelmäßigkeiten gibt.
Dann stellt sich aber die Frage warum beim Einkanalbetrieb(Sinus) alles
stabil ist? Vielleicht ist meine PWM-Initialisierung nicht richtig? Habe
alles schon etliche Male überprüft.

Autor: Philipp Aigner (st0ne)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich nehme mal an das wohl die unterbrechung der interrupts das jittern 
erzeugen...? ich habs momentan mal geschafft die pwm zu initialisieren 
und bin gerade dabei die sinuswerte zu implementieren, sollte heute 
abend dann funktionieren...
da ich auch 2 pwm's benötige, kann ich das auch gleich austesten...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.