Error MPC5644A Frequency Measurement

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Error MPC5644A Frequency Measurement

913 Views
tgc-yilmaz
Contributor III

Hello,

I'm using a MPC5644A and would like to measure the frequency of a PWM signal. For this,

  • I used to two eMIOS channels and set to OPWFMB and IPM modes.
  • I updated the frequency and duty cycle value of the PWM signal in the first channel.
  • The other channel is used to measure the frequency value. 
  • I externally connected EMIOS0(for IPM) to EMIOS1 (for OPWFMBon EVB board.

But, I have a problem. Normally, the IPM mode must allow the measurement of the period of an input signal by capturing only two consecutive rising edges. The FLAG line mustn't set on this first capture, and on the second and subsequent captures,the FLAG line must be set. But, I have observed that, IPM mode works like IPWM mode and the FLAG line is also set on the falling edges. So,I can not get the right value.
I don't understand why the IPM mode does not work as it is expressed in the reference manual. 
I just copied the code and output:

//****** EMIOS.c ******//

void initEMIOS(void){
   EMIOS.MCR.B.GPRE= 0x9;    /* eMIOS clk= sysclk/(GPRE+1)= 40 MHz/10= 4MHz */
   EMIOS.MCR.B.ETB = 0;          /* External time base is disabled */
   EMIOS.MCR.B.GPREN = 1;    /* Enable eMIOS clock */
   EMIOS.MCR.B.GTBE = 1;       /* Enable global time base */
   EMIOS.MCR.B.FRZ = 0;          /* Disable stopping channels when in debug mode */ 
}

void initEMIOSch1(void){                          /* EMIOS CH 1: Output Pulse Width & Frequency Modulation Buffered*/
   EMIOS.CH[1].CBDR.R = 99;                 /* Period = 1 usec x (99+1) = 100 usec, 10kHz*/
   EMIOS.CH[1].CADR.R = 0;                   /* Duty cycle = 1 usec x (0+1) = 1 usec (1%) */
   EMIOS.CH[1].CCR.B.FREN = 0;           /* Freeze channel counting when in debug mode*/
   EMIOS.CH[1].CCR.B.UCPRE = 11;       /* Channel counter uses divide by (0+1) prescaler */
   EMIOS.CH[1].CCR.B.UCPREN = 1;      /* Channel counter's prescaler is loaded & enabled*/
   EMIOS.CH[1].CCR.B.EDPOL = 1;         /* Polarity is active high */
   EMIOS.CH[1].CCR.B.MODE= 0x5A;     /* Mode= 0PWFMB, next period update, flag on both A1 and B1 match*/ 

 

   SIU.PCR[180].B.PA = 1;                         /* Initialise pad for eMIOS channel. */
   SIU.PCR[180].B.OBE = 1;                      /* Initialise pad for output */
}

 

void initEMIOSch0(void){                           /* EMIOS CH 0: Input Period Mesurement */
   EMIOS.CH[0].CADR.R = 0x00000000;
   EMIOS.CH[0].CBDR.R = 0x00000000;
   EMIOS.CH[0].CCR.B.FREN = 0;            /* Freeze channel counting when in debug mode*/
   EMIOS.CH[0].CCR.B.UCPRE = 11;       /* Channel counter uses divide by (3+1) prescaler */
   EMIOS.CH[0].CCR.B.UCPREN = 1;       /* Channel counter's prescaler is loaded & enabled*/
   EMIOS.CH[0].CCR.B.EDPOL = 1;          /* Polarity is active high - Rising edge */
   EMIOS.CH[0].CCR.B.MODE= 0x05;      /* Mode is IPM */ 
   EMIOS.CH[0].CCR.B.BSL = 0x3;           /* Use internal counter */

 

   SIU.PCR[179].B.PA = 1;                         /* Initialise pad for eMIOS channel. */
   SIU.PCR[179].B.IBE = 1;                        /* Initialise pad for input */
}

 

//****** main.c ******//

#include "MPC5644A.h"
#include "eMIOS.h"

 

unsigned int Pulse_A;
unsigned int Pulse_B;
unsigned int Pulse_width;

 

int main(void) {
   float freqValue;

 

   initEMIOS();
   initEMIOSch1();
   initEMIOSch0();

 
   for (;;) {

      updatePWMDutyandFreq(200.0f, 50.0f);

 

     /* Measure frequency of signal */
     if(!EMIOS.CH[0].CSR.B.FLAG) {                     /* Wait for flag to be set */
           Pulse_A = EMIOS.CH[0].CADR.R;            /* Read pulse width from register A */
           Pulse_B = EMIOS.CH[0].CBDR.R;            /* Read pulse width from register B */
           if(Pulse_B < Pulse_A) {                              /* Normal Case */
                     Pulse_width = Pulse_A - Pulse_B;   /* Calculate period value */
                     freq = 1000000.0f / (float) Pulse_width;

            }
            EMIOS.CH[0].CSR.B.FLAG = 1; /* Clear flag */ 
      }
   }

}

 

Thank you for your help...

Labels (1)
0 Kudos
Reply
1 Reply

717 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

the checking of the flag is wrong, I think. it is true if flag is cleared

you should have either 

if(EMIOS.CH[0].CSR.B.FLAG)      /* if flag is set do */

{

}

or 

 while(!EMIOS.CH[0].CSR.B.FLAG) { };   /* Wait for flag to be set */

BR, Petr

0 Kudos
Reply