Go Down

Topic: SAMD21 PWM output starts and stop (Read 2118 times) previous topic - next topic

cbis99

I have written a program section using all the great information that I have found here (Martin L etc) and the PWM output is working and controlling stepper motor via stepper motor controller board with input to pulse input but after 10 speed changes (about 0.5 sec each change) the motor stops.  I can see on serial print to computer the PER value is recalculating as normal but the motor simply stop for maybe 5 moves and then restarts and starts working again for about 10 moves and then stops again and this goes on and on.  It almost seems like a buffer is overflowing or something - not sure.  Any ideas.  Thanks

MartinL

Hi cbis99,

Are you using the buffered period PERB register to change the PWM signal's frequency?

The value of the PERB register is loaded into the period PER register at the beginning of the next timer cycle, thereby preventing any changes to the frequency from causing glitches on your output waveform.

Changes made to the PER register directly (in other words not via PERB), take effect immediately at the output irrespective of the current position in the time cycle.

cbis99

Thanks Martin.  I am using the PER.  I just changed to pins 13 (and 11) and I still get the problem.  I checked the enable to the Pololu stepper board and it is there even when the motor stops.  I will check the PWM tomorrow.  Below is what I have.  I show fixed values here for PER and also CCB3 but in practice they are calculated variables.  I think I have read that other functions also write to TCC0.  I tried to switch to TCC2_TCC3 but the loader said they were not "declared in this scope"??  Am I missing something here maybe?  Thanks again.  I check the PWM but I think I should change the TCC0 register if I can.




digitalWrite(9,LOW); // Disable motor control board
 
  REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) |          // Divide the 48MHz clock source by divisor 1:
                    GCLK_GENDIV_ID(4);            // Select Generic Clock (GCLK) 4
  while (GCLK->STATUS.bit.SYNCBUSY);              // Wait for synchronization

  REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC |           // Set the duty cycle to 50/50 HIGH/LOW
                     GCLK_GENCTRL_GENEN |         // Enable GCLK4
                     GCLK_GENCTRL_SRC_DFLL48M |   // Set the 48MHz clock source
                     GCLK_GENCTRL_ID(4);          // Select GCLK4
  while (GCLK->STATUS.bit.SYNCBUSY);              // Wait for synchronization


  // Sets the Port to Pin 13
     
  PORT->Group[g_APinDescription[13].ulPort].PINCFG[g_APinDescription[13].ulPin].bit.PMUXEN = 1;
 
  // Connect the TCC0 timer to the port outputs - port pins are paired odd PMUO and even PMUXE
  // F & E specify the timers: TCC0, TCC1 and TCC2
 
  PORT->Group[g_APinDescription[11].ulPort].PMUX[g_APinDescription[11].ulPin >> 1].reg = PORT_PMUX_PMUXO_F | PORT_PMUX_PMUXE_F;
 

  // Feed GCLK4 to TCC0 and TCC1
  REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN |         // Enable GCLK4 to TCC0 and TCC1
                     GCLK_CLKCTRL_GEN_GCLK4 |     // Select GCLK4
                     GCLK_CLKCTRL_ID_TCC0_TCC1;   // Feed GCLK4 to TCC0 and TCC1
  while (GCLK->STATUS.bit.SYNCBUSY);              // Wait for synchronization

  // Dual slope PWM operation: timers countinuously count up to PER register value then down 0
  REG_TCC0_WAVE |= TCC_WAVE_POL(0xF) |         // Reverse the output polarity on all TCC0 outputs
                    TCC_WAVE_WAVEGEN_DSBOTH;    // Setup dual slope PWM on TCC0
  while (TCC0->SYNCBUSY.bit.WAVE);               // Wait for synchronization

 
  REG_TCC0_CTRLA |= TCC_CTRLA_PRESCALER_DIV16 |    // Divide GCLK4 by 16 = 3 MHZ before prescale
                    TCC_CTRLA_ENABLE;             // Enable the TCC0 output
  while (TCC0->SYNCBUSY.bit.ENABLE);              // Wait for synchronization
 
 
 REG_TCC0_PER = 2000;      // Set the frequency of the PWM on TCC0 to moderate value to get the PWM engine going
 while(TCC0->SYNCBUSY.bit.PER);

  // The CCBx register value corresponds to the pulsewidth in microseconds (us)

 REG_TCC0_CCB3 = 1000;       // TCC0 CCB3
  while(TCC0->SYNCBUSY.bit.CCB1);

 
 


   digitalWrite(9,HIGH);

MartinL

The reason why the compiler doesn't recongnise the generic clock control register (REG_GCLK_CLKCTRL) definition, might be because it should reference timers TCC2 and TC3: GCLK_CLKCTRL_ID_TCC2_TC3.

Switching to TCC2 however won't make any difference. In any case, TCC0 is the most fully featured of the SAMD21's TCCx counter timers.

Might I ask which Pololu stepper motor board you're using?

cbis99

Thanks Martin.  I am using this one.  Is there a way I can read the value in TCC_0 so I can check it against my calculated value to verify.

Here is the board.  I am using 1/16 stepping and 0.4 Amps for the motor.  The chip and board are cool to the touch.



Electronics » Motion Control Modules » Stepper Motor Drivers »

DRV8834 Low-Voltage Stepper Motor Driver Carrier

 
 


Minimal wiring diagram for connecting a microcontroller to a DRV8834 stepper motor driver carrier (1/4-step mode).
 

 

←Previous













→Next
 



 

cbis99

Martin,

I checked the fault output on the stepper board and it not faulting.  I do not have my scope here but using a volt meter on the "step" input I can see the voltage is 1.6 when the unit is operating (3.3 V at 50% duty cycle sounds about right for the meter) and then drops to zero so the PWM output must be going away. 

cbis99

One last thing - the off time is consistently just about 5 seconds?

cbis99

Martin - I think I got it so don't worry about it.  My board is an Adafruit M0 Feather and I think its slightly different.  I think I have it corrected now.  I also switched the PWM output to pin 10.  Pin 13 on that board is also used as an LED output.  I never configured it but maybe that was interfering somehow.  Now that I changed the wiring if I use what I had before what would be the complement for pin 10.  I'd like to try it just to see.  Thanks again for everything you post.  You're an ace.

Go Up