AnsweredAssumed Answered

LPC1769 - using Timer external match to generate PWM

Question asked by Tomas Frcek on Jul 1, 2019
Latest reply on Jul 2, 2019 by jeremyzhou



I'm trying to generate a PWM signal with both flexible duty cycle and frequency using TIMER3 peripheral. I can't use the PWM peripheral, because it's output pins aren't wired in the target PCB.


I have a simple TIMER3 initialization with hard coded PWM output so far, but I can't get any output on the external match pins:


void InitPWMTimer(void)
    // TIMER3 power.
    LPC_SC->PCONP |= (0x01 << 23);

    // TIMER3 clock = system clock (100 MHz).
    LPC_SC->PCLKSEL1 = (LPC_SC->PCLKSEL1 & ~(0x3 << 14)) | (0x1 << 14);

    // P0.10 pin function set to MAT3.0.
    LPC_PINCON->PINSEL0 |= (0x3 << 20);

    // Reset TIMER3.
    LPC_TIM3->TCR = 0x2;

    // Clear interrupt flags MR0..MR3.
    LPC_TIM3->IR = 0xF;

    // EMCR0 configured to toggle output level on MAT3.0 on MR0 match.
    LPC_TIM3->EMR = (0x3 << 4);

    // Prescaler set to generate 100Hz PWM with the hard coded values fed to MR0.
    LPC_TIM3->PR = 0xA;


    // Set the initial MR0 value and activate interrupt on MR0 match.
    LPC_TIM3->MR0 = 3000U;
    LPC_TIM3->MCR = 0x3;
    // Start the timer.
    LPC_TIM3->TCR = 0x1;


void TIMER3_IRQHandler(void)
    uint32_t tim3_ir = LPC_TIM3->IR;
    uint32_t tim3_emr = LPC_TIM3->EMR;

    if((tim3_ir & 0x1) == 0x1)
        // MR0 match, clears interrupt flag.
        LPC_TIM3->IR |= 0x1;


        // Depending on the MAT3.0 output value (read from EMR), set new MR0 value (here to generate 70% PWM).

        // Toggling of the output value should be done by the TIMER peripheral itself (set in the EMR control field).
        if ((tim3_emr & 0x1) == 0U)
            LPC_TIM3->MR0 = 7000U;
            LPC_TIM3->MR0 = 3000U;


The interrupt gets fired normaly, I can see the MR0 value changing, but I can't get any result on the output pin. 


Any ideas?