Arduino DUE PWM Pulse output

I have a question, when I do a compare match in TC.RA, I set the RA register value to a sine function instead of a fixed value, will it be successfully compare matched?

#define LED_PIN 13//割り込み確認用
#include <math.h>      // 数学関数用ヘッダ
#define PI 3.1415
#define sinsize (256)

int sinwave_u = 0, sinwave_v = 0, sinwave_w = 0;

/*配列に格納*/
float a[200];//u相
float b[200];//v相
float c[200];//w相
float sinwave[200];

int n=0;
int p=0;
int x = 0, y=0, z=0, w=0, j=0, l=0,o=0;
int q = 0;
float t = 0,t1 = 0;
float sintime = 0;
float average = 0 ;
float average1 = 0 ;


/*1相目(u相)の値A0ピン*/    
float value1 = 0;
float volt1 = 0;
float current1 = 0;

/*2相目(v相)の値A1ピン*/    
float value2 = 0;
float volt2 = 0;
float current2 = 0;

/*3相目(w相)の値A2ピン*/    
float value3 = 0;
float volt3 = 0;
float current3 = 0;


void setup(){
  
   Serial.begin(115200);
   tc_setup();
   adc_setup();
   pwm_setup();
   pinMode(LED_PIN,OUTPUT);
   
}


//TC_はタイマカウンターの構造体
//PMCは電源管理コントローラの構造体
//PIO_は並列入出力コントローラの構造体



/*************  Timer Counter 0 Channel 2 to generate PWM pulses thru TIOA2  ************/
void tc_setup() {

  PMC->PMC_PCER0 |= PMC_PCER0_PID27;    //TC0 power ON : Timer Counter 0 channel 2 IS TC0 p.31 ペリフェラルクロックイネーブルレジスタ0
  PMC->PMC_PCER0 |= PMC_PCER0_PID28;    //TC1 "|="は論理和 HIGHにしたい時に使う PID28に対応するビットをHIGHにする
  PMC->PMC_PCER0 |= PMC_PCER0_PID29;    //TC2
  
  TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // チャネル制御レジスタ,カウンタークロックイネーブル
  TC0->TC_CHANNEL[1].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN;
  TC0->TC_CHANNEL[2].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN;
  
  PIOB->PIO_PDR |= PIO_PDR_P25;           // PB25 is no more driven by the GPIO p858 インプット/アウトプットライン
  //PIOB->PIO_PER |= PIO_PER_P25;
  PIOB->PIO_OER |= PIO_OER_P25;
  
  PIOB->PIO_ABSR |= PIO_PB25B_TIOA0;     //ピンをペリフェラル機能に割り当てるには,PIO_PDR の書き込みに加えて,ペリフェラル選択レジスタ(PIO_ABSR ABSR)の書き込みが必要

  TC0->TC_CHANNEL[0].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1  // MCK/2, clk on rising edge
                              | TC_CMR_WAVE               // Waveform mode
                              | TC_CMR_WAVSEL_UPDOWN        // UP mode with automatic trigger on RC Compare
                              | TC_CMR_ACPA_CLEAR          // Clear TIOA0 on RA compare match
                              | TC_CMR_ACPC_SET;           // Set TIOA0 on RC compare match
   
  TC0->TC_CHANNEL[0].TC_RC = 28000;  //<*********************  Frequency = (Mck/2)/TC_RC  Hz = 15 KHz
  TC0->TC_CHANNEL[0].TC_RA =  sinwave_u;  //<********************   Duty cycle = (TC_RA/TC_RC) * 100  %  = 80 %

  uint32_t status;
  status = TC0->TC_CHANNEL[0].TC_SR;  // Read and clear TC0 status register
  status & TC_SR_CPAS;

/*
 TC0->TC_CHANNEL[0].TC_IER = TC_IER_CPCS       // Interrupt on RC compare match
                              | TC_IER_CPAS;    // Interrupt on RA compare match
                             
  NVIC_EnableIRQ(TC0_IRQn);                     // Interrupt enable
                           
  TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Software trigger TC0 counter and enable*/
}

void TC0_Handler()
{
 uint32_t status;
 status = TC0->TC_CHANNEL[0].TC_SR;  // Read and clear TC0 status register

 if(status & TC_SR_CPAS) {
  // Toggle pin 1
 }
 else  if(status & TC_SR_CPCS)
  {
  // Toggle pin 2
 }
}


void adc_setup() {
   pmc_set_writeprotect(false);            // PMC controller write protection disable.
  
  //PMC->PMC_PCER1 |= PMC_PCER1_PID37;                    // ADC power on
  //ADC->ADC_CR = ADC_CR_SWRST;                           // Reset ADC
    ADC->ADC_MR =  ADC_MR_TRGEN_EN                       // Hardware trigger select
                  | ADC_MR_TRGSEL_ADC_TRIG5            // Trigger by PWM Event Line 1 PWMイベントライン1をトリガに設定
                  | ADC_MR_PRESCAL(1);                // ここは0でも1でもどっちでも

  ADC->ADC_CHER = ADC_CHER_CH7 | ADC_CHER_CH6 | ADC_CHER_CH5;   // Enable Channel 7
  //NVIC_EnableIRQ(ADC_IRQn);  // Enable ADC interrupt
  //ADC->ADC_IER = ADC_IER_EOC7;                          // End Of Conversion interrupt enable for channel 7
                            
  

}



void pwm_setup(){
  REG_PMC_PCER1 |= PMC_PCER1_PID36; // ペリフェラルクロックイネーブルレジスタ1
  
  uint16_t CounterPeriod;
  uint16_t DeadTime;

    //キャリア周波数10Hz、デッドタイム約1.2usの場合の設定

    REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1); // PWMクロックレートを84MHzに設定 (84MHz/1)
 
    CounterPeriod = 8400;  //84MHz/5KHz = 16800
    DeadTime = 100;

   REG_PWM_CPRD0 = CounterPeriod; //CPRDは三角波のトップ
  
/*
  TC0->TC_CHANNEL[0].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1   // MCK/2, clk on rising edge
                              | TC_CMR_WAVE                // Waveform mode
                              | TC_CMR_WAVSEL_UP_RC        // UP mode with automatic trigger on RC Compare
                              | TC_CMR_ACPA_CLEAR          // Clear TIOA0 on RA compare match
                              | TC_CMR_ACPC_SET          // Set TIOA0 on RC compare match
                              |  TC_CMR_EEVT_XC0 ;
                              
  TC0->TC_CHANNEL[2].TC_RC = 14;  //<*********************  Frequency = (Mck/8)/TC_RC = 44.1 MHz
  TC0->TC_CHANNEL[2].TC_RA = 7;  //<********************   Any Duty cycle in between 1 and TC_RC
  TC0->TC_CHANNEL[2].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Software trigger TC2 counter and enable
   */                 
   
   REG_PWM_CMR0 = PWM_CMR_CALG | PWM_CMR_CPRE_MCK;  //CALG senter Alg
   REG_PWM_CMR1 = PWM_CMR_DTE | PWM_CMR_CALG | PWM_CMR_CPRE_MCK;
   REG_PWM_CMR2 = PWM_CMR_DTE | PWM_CMR_CALG | PWM_CMR_CPRE_MCK;
   REG_PWM_CMR3 = PWM_CMR_DTE | PWM_CMR_CALG | PWM_CMR_CPRE_MCK;

   REG_PWM_DT1 = PWM_DT_DTH(DeadTime) | PWM_DT_DTL(DeadTime);
   REG_PWM_DT2 = PWM_DT_DTH(DeadTime) | PWM_DT_DTL(DeadTime);
   REG_PWM_DT3 = PWM_DT_DTH(DeadTime) | PWM_DT_DTL(DeadTime);
   
    
   
   //AD変換のためのPWMイベントライン設定
   PWM->PWM_CMP[0].PWM_CMPM = PWM_CMPM_CEN;                       // PWM0の比較を有効化
   PWM->PWM_ELMR[1] = PWM_ELMR_CSEL0;                             // PWMイベントライン1にPWM0を設定
   PWM->PWM_CMP[0].PWM_CMPV = PWM_CMPV_CV(CounterPeriod - 10);  // PWM0のDUTYを設定
   
  NVIC_EnableIRQ(TC0_IRQn);  // TC2 NVIC enable
  NVIC_SetPriority(PWM_IRQn, 0); // PWMコントローラのNVIC(Nested Vector Interrupt Controller)の優先度を0(最高)にする
  NVIC_EnableIRQ(PWM_IRQn); // PWMコントローラをNested Vector Interrupt Controller (NVIC)に接続する。                               
  PWM->PWM_ENA |= PWM_ENA_CHID0 | PWM_ENA_CHID0; // PWMチャンネルを有効にする 
  PWM->PWM_IER1 |= PWM_IER1_CHID0; // イベント割り込みを有効にする
  REG_PWM_IER1 = PWM_IER1_CHID0; // Interrupt on PWM Channel 0 counter
  
   // PWM0~3の開始
  REG_PWM_ENA = PWM_ENA_CHID3 | PWM_ENA_CHID2 | PWM_ENA_CHID1 | PWM_ENA_CHID0;
}





void loop(){

     sinwave_u = (14000 * sin( sintime * 1110*3.14 ) + 14000) ;
     sinwave_v = (14000 * sin( sintime * 2 * PI * 60 + (2*3.1415/3) ) + 14000);
     sinwave_w = (14000 * sin( sintime * 2 * PI * 60 + (4*3.1415/3) ) + 14000);
   
     TC0->TC_CHANNEL[0].TC_RA =  sinwave_u;  
          
  
     if(x==2199){ 
      for(int u=0 ;u>=0 && u<=199;u=u+1){
        Serial.print("U相電流 : ");
        Serial.println(a[u]);
      }
       
      for(int v=0 ;v>=0 && v<=199;v=v+1){
        Serial.print("V相電流 : ");
        Serial.println(b[v]);
       }
        for(int w=0 ;w>=0 && w<=199;w=w+1){
        Serial.print("W相電流 : ");  
        Serial.println(c[w]);
     }

  
     } 
   Serial.println(TC0->TC_CHANNEL[0].TC_RA);
}

void PWM_Handler(){
  if (REG_PWM_ISR1 & PWM_ISR1_CHID0)    // Check if an update condition has occured
  {
    
    ADC_Handler();  
  }
}




void ADC_Handler(){

      
      value1 = ADC->ADC_CDR[7];
      value2 = ADC->ADC_CDR[6];
      value3 = ADC->ADC_CDR[5];
      

     //電流センサ計算部分//
    volt1 = ((value1-17)*(3.3/ 4095.0)) ;
    volt2 = ((value2-17)*(3.3/ 4095.0)) ;
    volt3 = ((value3-17)*(3.3/ 4095.0)) ;
    
    current1 = ((volt1 - 2.5)*40) ;
    current2 = ((volt2 - 2.5)*40) ;
    current3 = ((volt3 - 2.5)*40) ;
       
   
        
      //配列に値を格納//
    
      x++;
     if(2000<=x && x<=2199){
     
     //A/D変換の値を格納//
      a[y] = value1;
      b[z] = value2;
      c[j] = value3;
      
    
     //電流値を格納//
     /* a[y] = current1;
      b[z] = current2;
      c[w] = current3;*/
    
      l++;
      y++;
      z++;
      j++;
     }


   //サイン関数の値の更新
    
    t = t + 2;
    sintime = (t / 10e6);
   
  
    //PIOB->PIO_ODSR ^= PIO_ODSR_P27; //割り込み確認用
   
    if(n%2==0){
      digitalWrite(LED_PIN,HIGH);
      n++;
    }
    else{
      digitalWrite(LED_PIN,LOW);
      n++;
    }
    
    
      
    }

    
      

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.