@MartinL is there a way to do what you did using the data array "uint16_t data[]" but with a switch case or if statements using a counter? So if i want to update the duty cycle for the following code using a switch case or if statements:
This is what I'm working with:
// Enable synchronous, complementary output, single-slope PWM at 5Hz on 3 channels (0 to 2), at varying duty cycle
uint16_t data[] = { 65535, 0, 0, 65535, 65535, 0, 0, 65535, 0, 0, 65535, 65535, 0, 0, 65535, 65535, 0, 65535};
void setup() {
// Set-up 6 PWM outputs on 3 complementary channels on on pins D34, D35, D36, D37, D38, and D39 for channels 0 through to 2 respectively
PMC->PMC_PCER1 |= PMC_PCER1_PID36; // Enable PWM
PIOC->PIO_ABSR |= PIO_ABSR_P6 | PIO_ABSR_P4 | PIO_ABSR_P2; // Set the port C PWM pins to peripheral type B
PIOC->PIO_ABSR |= PIO_ABSR_P7 | PIO_ABSR_P5 | PIO_ABSR_P3;
PIOC->PIO_PDR |= PIO_PDR_P6 | PIO_PDR_P4 | PIO_PDR_P2; // Set the port C PWM pins to outputs
PIOC->PIO_PDR |= PIO_PDR_P7 | PIO_PDR_P5 | PIO_PDR_P3;
PWM->PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(255); // Set the PWM clock A rate to 1MHz (84MHz/255)
PWM->PWM_SCM |= PWM_SCM_UPDM_MODE2 | // Automatically load the duty-cycle register with the PDC each timer cycle
PWM_SCM_SYNC2 | PWM_SCM_SYNC1 | PWM_SCM_SYNC0; // Set the PWM channels as synchronous
PWM->PWM_CH_NUM[0].PWM_CMR = PWM_CMR_CPRE_CLKA; // Enable single slope PWM and set the clock source as CLKA for all synchronous channels
PWM->PWM_CH_NUM[0].PWM_CPRD = 65535; // Set the PWM frequency 329411MHz/(65536) = 5Hz for all synchronous channels
for (uint8_t i = 0; i < 3; i++) // Loop for each PWM channel (8 in total)
{
PWM->PWM_CH_NUM[i].PWM_CDTY = 0; // Set the PWM duty cycle to 50%
}
NVIC_SetPriority(PWM_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority for the PWM controller to 0 (highest)
NVIC_EnableIRQ(PWM_IRQn); // Connect PWM Controller to Nested Vector Interrupt Controller (NVIC)
PWM->PWM_IER2 = PWM_IER2_WRDY; // Enable interrupt when Write Ready (WRDY) is set
PWM->PWM_TPR = (uint32_t)data; // Set the address of the transmit data pointer
PWM->PWM_TCR = 18; // Set the length of the transmit data
PWM->PWM_TNPR = (uint32_t)data; // Set the next transmit data pointer
PWM->PWM_TNCR = 18; // Set the next transmit counter
PWM->PWM_PTCR |= PWM_PTCR_TXTEN; // Enable the Peripheral DMA Controller
PWM->PWM_ENA = PWM_ENA_CHID0; // Enable all synchronous PWM channels
}
void loop() {}
void PWM_Handler()
{
PWM->PWM_TNPR = (uint32_t)data; // Set the next transmit data pointer
PWM->PWM_TNCR = 18; // Set the next transmit counter
PWM->PWM_ISR2; // Clear the interrupt status register 2
}
Instead of a data array i would like to use a switch case or if statements to change the duty cycle values. The duty cycle must change every period in the same pattern seen in the data array. Something like this:
int count = 0;
switch(count)
{
case 1:
//Update duty cycle
break;
case 2;
//Update duty cycle
break;
//......
case 6;
//Update Duty cycle
break;
}