Go Down

Topic: Aumentare frequenza PWM su Arduino due (Read 166 times) previous topic - next topic

tino85

Salve, ho la necessità di aumentare la frequenza del segnale PWM sul pin 10 di arduino due.
Ho cercato in rete ma non sono riuscito a trovare qualcosa che funzionasse.


ard_newbie

#1
Jan 21, 2019, 01:17 pm Last Edit: Jan 21, 2019, 01:18 pm by ard_newbie
Un semplice esempio di PWM sul pin 10:

Code: [Select]

/******************************************************************/
/* Timer Counter 2 Channel 1, namely TC7, 1 Hz frequency on Pin 10*/
/******************************************************************/
void setup() {

  pinMode(LED_BUILTIN, OUTPUT);
  tc_setup();

}

void loop() {

}

void tc_setup() {

  PMC->PMC_PCER1 |= PMC_PCER1_PID34;                       // TC7 power ON : Timer Counter 2 channel 1 IS TC7 - see page 38

  PIOC->PIO_PDR |= PIO_PDR_P29;                            // Set the pin to the peripheral (page 859)
  PIOC->PIO_ABSR |= PIO_PC29B_TIOB7;                       // Peripheral type B

  TC2->TC_CHANNEL[1].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1  // MCK/2 = 42 M Hz, clk on rising edge
                              | TC_CMR_WAVE               // Waveform mode
                              | TC_CMR_WAVSEL_UP_RC       // UP mode with automatic trigger on RC Compare
                              | TC_CMR_EEVT_XC0           // TIOB as output
                              | TC_CMR_BCPB_CLEAR         // Clear TIOB7 on RB compare match
                              | TC_CMR_BCPC_SET;          // Set TIOB7 on RC compare match


  TC2->TC_CHANNEL[1].TC_RC = 42000000;  //<*********************  Frequency = (Mck/2)/TC_RC = 1Hz
  TC2->TC_CHANNEL[1].TC_RB = 21000000;  //<********************   Duty cycle = (CDTY/CPRD)  * 100 %


  TC2->TC_CHANNEL[1].TC_IER = TC_IER_CPCS;                 // Interrupt on RC compare match
  NVIC_EnableIRQ(TC7_IRQn);                                // Enable interrupt
  TC2->TC_CHANNEL[1].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Software trigger TC7 counter and enable
}

void TC7_Handler() {

  TC2->TC_CHANNEL[1].TC_SR;                               // Read and clear status register
  PIOB->PIO_ODSR ^= PIO_ODSR_P27;                       // Toggle LED every 1 Hz
}


tino85

#2
Jan 21, 2019, 05:04 pm Last Edit: Jan 21, 2019, 05:06 pm by tino85
Ciao ard_newbie e grazie per la risposta, ho provato a capire l'esempio che hai postato, ma non mi è chiarissimo, perchè questa sarebbe la mia prima manipolazione di registri. Voglio comunque cercare di capirci qualcosa in più :)

Ti spiego cosa dovrei fare, la frequenza dovrei cambiarla nel momento in cui richiamo una funzione che ho definito io e quando la funzione termina il suo lavoro la frequenza dovrebbe ritornare al valore di default.

Intanto, è possibile una cosa del genere?

Prendendo spunto dall'esempio che hai postato, la frequenza rimarrebbe cambiata per tutto il tempo dell'esecuzione del programma, dico bene?

Dimenticavo...analogWrite continuerà a funzionare normalmente dopo questa modifica?

ard_newbie


La frequenza è modificabile modificando TC_RC.

tino85

Code: [Select]
void SetStep(byte ing){
 
  vin = ing;
  vpwm = (255*vin)/5;
 
  }

void Step(){

  tempo = 0;
  via = millis();
  start_sam = millis();

  while( tempo <= 4000){

    tempo = millis()-via;
 
    digitalWrite(DIR, LOW);
    digitalWrite(DIR2, HIGH);
    analogWrite (PWM, vpwm);
   

    end_sam = millis();
    sam_time = (end_sam - start_sam);

    if(sam_time >= sampling){

      start_sam = millis();     
      AggiornaPosizione();
      //Serial.println((int)tempo, DEC);
      Serial.println((float)angolo, DEC);

    }
 
  } 


Questo è il codice che ho scritto io, dovrei inserire tc_setup() in SetStep e poi chiamare la funzione tc7_handler in Step?

Go Up