Hello,
I'm using a MPC5644A and would like to measure the frequency of a PWM signal. For this,
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...
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