Hello,
I am trying change the PMW frequency on pins 7, 8, and 9 to 20kHz. I used to be able to change it by changing PWM_FREQUENCY and TC_FREQUENCY in the variant.h file.
* PWM
*/
#define PWM_INTERFACE PWM
#define PWM_INTERFACE_ID ID_PWM
#define PWM_FREQUENCY 20000
#define PWM_MAX_DUTY_CYCLE 255
#define PWM_MIN_DUTY_CYCLE 0
#define PWM_RESOLUTION 8
/*
* TC
*/
#define TC_INTERFACE TC0
#define TC_INTERFACE_ID ID_TC0
#define TC_FREQUENCY 20000
#define TC_MAX_DUTY_CYCLE 255
#define TC_MIN_DUTY_CYCLE 0
#define TC_RESOLUTION 8
For some reason this method is not working any more. I am using Arduino 1.8.5 with SAM 1.6.11 installed. Reboot Arduino software does nothing.
Is there a different way of changing the PWM frequency?
There are numerous example sketches of PWM programming in the DUE subforum. All you need is the Greynomad pinout diagram plus the PWM section of Sam3x datasheet. An other solution would be using PWM_lib from antodom.
Here is an example with PWMH0 at 1 MHz with a duty cycle of 50%:
/******************************************************************************/
/* PWMH0 1 MHz */
/******************************************************************************/
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
PMC->PMC_PCER1 |= PMC_PCER1_PID36; // PWM power ON
PIOC->PIO_PDR |= PIO_PDR_P3; // Set PWM pin to a peripheral
PIOC->PIO_ABSR |= PIO_PC3B_PWMH0; // Set PWM pin peripheral type B for PWMH0 (Arduino pin 35)
PWM->PWM_CLK = PWM_CLK_PREB(0) | PWM_CLK_DIVB(2); // select Frequency for clock B: Mck/2 = 42 MHz
PWM->PWM_CH_NUM[0].PWM_CMR = PWM_CMR_CPRE_CLKB; // The period is left aligned, clock source as CLKB on channel 0
PWM->PWM_CH_NUM[0].PWM_CPRD = 42; // Set the PWM frequency 42 MHz/42 = 1 MHz
PWM->PWM_CH_NUM[0].PWM_CDTY = 21; // Set the PWM duty cycle = (CPRD/CDTY) * 100 %
PWM->PWM_IER1 = PWM_IER1_CHID0; // Interrupt on PWM Channel 0 counter
NVIC_EnableIRQ(PWM_IRQn); // Enable interrupt
PWM->PWM_ENA = PWM_ENA_CHID0; // Enable PWM channel 0
}
void loop() {
}
void PWM_Handler() {
static uint32_t Count;
PWM->PWM_ISR1; // Read and Clear status register
if (Count++ == 1000000) {
PIOB->PIO_ODSR ^= PIO_ODSR_P27; // Toggle LED_BUILTIN every 1 Hz
Count = 0;
}
}
ard_newbie:
/******************************************************************************/
/* PWMH0 1 MHz /
/*****************************************************************************/
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
PMC->PMC_PCER1 |= PMC_PCER1_PID36; // PWM power ON
PIOC->PIO_PDR |= PIO_PDR_P3; // Set PWM pin to a peripheral
PIOB->PIO_ABSR |= PIO_PC3B_PWMH0; // Set PWM pin peripheral type B for PWMH0 (Arduino pin 35)
PWM->PWM_CLK = PWM_CLK_PREB(0) | PWM_CLK_DIVB(2); // select Frequency for clock B: Mck/2 = 42 MHz
PWM->PWM_CH_NUM[0].PWM_CMR = PWM_CMR_CPRE_CLKB; // The period is left aligned, clock source as CLKB on channel 0
PWM->PWM_CH_NUM[0].PWM_CPRD = 42; // Set the PWM frequency 42 MHz/42 = 1 MHz
PWM->PWM_CH_NUM[0].PWM_CDTY = 21; // Set the PWM duty cycle = (CPRD/CDTY) * 100 %
PWM->PWM_IER1 = PWM_IER1_CHID0; // Interrupt on PWM Channel 0 counter
NVIC_EnableIRQ(PWM_IRQn); // Enable interrupt
PWM->PWM_ENA = PWM_ENA_CHID0; // Enable PWM channel 0
}
void loop() {
}
void PWM_Handler() {
static uint32_t Count;
PWM->PWM_ISR1; // Read and Clear status register
if (Count++ == 1000000) {
PIOB->PIO_ODSR ^= PIO_ODSR_P27; // Toggle LED_BUILTIN every 1 Hz
Count = 0;
}
}
I tried this code and there is nothing scoped on pin 35.
Yes, it's PIOC->PIO_ABSR |= PIO_PC3B_PWMH0; !!