You have several ways to generate a PWM pulse:
- For a fixed 50% duty cycle, you can use PMC_PCKx up to 480 MHz
- For different duty cycles, you can use either Timer Counters (section 36 of Sam3x datasheet), or PWMHx/Lx (section 38 of Sam3x datasheet).
See below a snippet to generate a 1 MHz PWM with a 50% duty cycle:
/******************************************************************************/
/*** 1MHz/ 50% Duty cycle PWM thru TIOA0 ***/
/******************************************************************************/
void setup() {
/************* Timer Counter 0 Channel 0 to generate PWM pulses thru TIOA0 ************/
PMC->PMC_PCER0 |= PMC_PCER0_PID27; // Timer Counter 0 channel 0 IS TC0, TCO power ON
PMC->PMC_PCER0 |= PMC_PCER0_PID12; // PIOB power ON, page 38
PIOB->PIO_PDR |= PIO_PDR_P25;
PIOB->PIO_ABSR |= PIO_ABSR_P25; // PB25 is driven by the TC, peripheral type B, page 858
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
TC0->TC_CHANNEL[0].TC_RC = 42; //<********************* Frequency = (Mck/2)/TC_RC = 1 MHz
TC0->TC_CHANNEL[0].TC_RA = 21; //<******************** Duty cycle = (TC_RA/TC_RC) * 100 = 50 %
TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Software trigger TC0 counter and enable
}
void loop() {
}