This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

lpc1788 input capture, frequency limit

Hello everyone,

I am using the <LPC1788>, amongst other things, for a frequency measurement.

I'm trying to output a waveform with PWM0

And capture the input to Timer0 to measure the frequency of the waveform.

The waveform I want to output is not a continuous pwm waveform,

I want to implement a limited number of pulses in a large period.

For example, if 0 is a pwm pulse,

000____000____000____ ~~~

The waveform is output as above.
(The period of the entire large waveform is controlled by timer 1)

Capture the desired number of pulses with timer0, then 'disable' pwm0,

We 'enalbe' pwm0 again with timer1.

However, if the waveform of pwm0 is more than 1MHz, input capture does not properly capture the desired pulse, and after some more pulses are output, 'disable' pwm0.

Help me !!!

unsigned int Total_Rate = 10000;

unsigned int PWM0_Freq = 1000000; //Hz
unsigned char PWM0_DutyRate = 50; //%

unsigned char Pulse_Set_PWM0 = 2;

int main(void)
{
        PWM0_Configuration( PWM0_Freq, PWM0_DutyRate );
        Timer0_Configuration( );
        Timer1_Configuration( Total_Rate );

        while (1)
        {

        }
}

void PWM0_Configuration( unsigned int freq, unsigned int dutyrate )
{
        freq = 120000000/freq;
        dutyrate = freq*dutyrate/100;

        PWM_TIMERCFG_Type PWMCfgDat;
        PWM_MATCHCFG_Type PWMMatchCfgDat;

        PWMCfgDat.PrescaleOption = PWM_TIMER_PRESCALE_TICKVAL;
        PWMCfgDat.PrescaleValue = 1;

        PWM_Init( PMW_0, PWM_MODE_TIMER, &PWMCfgDat );

        PINSEL_ConfigPin( 1, 2, 3 );//PWM0.1

        /* Set match value for PWM match channel 0 = freq, update immediately */
        PWM_MatchUpdate( PMW_0, 0, freq, PWM_MATCH_UPDATE_NOW );

        PWMMatchCfgDat.IntOnMatch = ENABLE;
        PWMMatchCfgDat.MatchChannel = 0;
        PWMMatchCfgDat.ResetOnMatch = ENABLE;
        PWMMatchCfgDat.StopOnMatch = DISABLE;
        PWM_ConfigMatch( PMW_0, &PWMMatchCfgDat );

        /* Configure match value for each match channel */
        /* Set up match value = dutyrate */
        PWM_MatchUpdate( PMW_0, 1, dutyrate, PWM_MATCH_UPDATE_NOW );
        /* Configure match option */
        PWMMatchCfgDat.IntOnMatch = DISABLE;
        PWMMatchCfgDat.MatchChannel = 1;
        PWMMatchCfgDat.ResetOnMatch = DISABLE;
        PWMMatchCfgDat.StopOnMatch = DISABLE;
        PWM_ConfigMatch( PMW_0, &PWMMatchCfgDat );
        /* Enable PWM Channel Output */
        PWM_ChannelCmd( PMW_0, 1, ENABLE );

        /* Reset and Start counter */
        PWM_ResetCounter( PMW_0 );
        PWM_CounterCmd( PMW_0, ENABLE );
        /* Start PWM now */
        PWM_Cmd( PMW_0, ENABLE );
}

TIM_TIMERCFG_Type TIM_ConfigStruct;
TIM_MATCHCFG_Type TIM_MatchConfigStruct ;
TIM_CAPTURECFG_Type TIM_CaptureConfigStruct;

void Timer0_Configuration( void )
{
        //Config pin as CAP0.0 function
        PINSEL_ConfigPin( 1, 26, 3 );

        TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
        TIM_ConfigStruct.PrescaleValue  = 1;

        TIM_CaptureConfigStruct.CaptureChannel = 0;
        TIM_CaptureConfigStruct.RisingEdge = ENABLE ;
        TIM_CaptureConfigStruct.FallingEdge = ENABLE;
        TIM_CaptureConfigStruct.IntOnCaption = ENABLE;

        // Set configuration for Tim_config and Tim_MatchConfig
        TIM_Init( LPC_TIM0, TIM_TIMER_MODE, &TIM_ConfigStruct );
        TIM_ConfigCapture( LPC_TIM0, &TIM_CaptureConfigStruct );
        TIM_ResetCounter( LPC_TIM0 );

        /* preemption = 1, sub-priority = 1 */
//      NVIC_SetPriority( TIMER0_IRQn, ((1 << 3) | 2) );

        /* Enable interrupt for timer 0 */
        NVIC_EnableIRQ( TIMER0_IRQn );

        // To start timer 0
        TIM_Cmd( LPC_TIM0, ENABLE );
}

void Timer1_Configuration( unsigned int totla_rate )
{
        LPC_TIM_TypeDef *timer = LPC_TIM1;
        LPC_SC->PCONP |= (0x1<<2);

        timer->TC = 0x00; //Clear Timer Counter
        timer->PR = 0x00; //No prescaler

        timer->MCR = 0x3; //enable interrupt
        timer->MR0 = 120000000/totla_rate; //interrupt every 1ms
        NVIC_EnableIRQ(TIMER1_IRQn);
        timer->TCR = 0x02; //reset timer
        timer->TCR = 0x01; //enable timer counter
}


unsigned int Edge_Counter_PWM0;

void TIMER0_IRQHandler( void )
{
        if (TIM_GetIntCaptureStatus( LPC_TIM0, TIM_MR0_INT))
        {       TIM_ClearIntCapturePending( LPC_TIM0, TIM_MR0_INT);

                Edge_Counter_PWM0++;
                if( Edge_Counter_PWM0 == Pulse_Set_PWM0*2 )
                {       Edge_Counter_PWM0 = 0;
                        PWM_ChannelCmd( PMW_0, 1, DISABLE );
                }
        }
}

void TIMER1_IRQHandler( void )
{
        LPC_TIM1->IR = (1u<<0); // Reset the MR0 Interrupt; Writing a zero has no effect.

        PWM_ChannelCmd( PMW_0, 1, ENABLE );
}