Sign in

username:

password:



Not a member?

Search msp430



Search tips

Subscribe to msp430



Ads

Discussion Groups

Discussion Groups | MSP430 | Counting pulses... and missing some...

The purpose of this group is to foster exchange of information on the Texas Instruments MSP430 family of microcontrollers and related tools. Everyone welcome, all levels of familiarity/expertise.

Counting pulses... and missing some... - Mike Raines - Sep 16 9:06:15 2008

Folks,

I'm hoping someone can help me understand something fundamental that I'm=20
missing here. I'm using IAR v4.11, the TI MSP-FET430UIF USB tool, and
the MSP430 4619 chip on an experimenter's board.
We have two of these from last year's school and are using them
because our new project will use the=20
4619 chip. I have tried both chips and found no differences.

I'm counting pulses from a square waveform generator. Our target
input frequency is 0 =96 5k Hz.
All the data in the below table was from input frequency of 5 kHz. I
tried two algorithms. h2a is based on a=20
legacy system and monitors port p1.0 in DIO mode, interrupting on
rising edge. ta algorithm uses timerA
capture/compare2, interrupting on rising edge of p 2.0. The
correction algorithm referenced is applicable to the ta algorithm only
and means that on interrupt, I check (CCTL2 & 0x02) to see if data has
changed since last read. If so, I increment the
receivedPulse count, assuming I only missed one pulse. In the
instances where I count more pulses than were sent, I suspect that
the COV bit is being set erroneously, thus indicating a missed pulse
in error. The Synchronized input is also only applicable to the ta
algorithm=20
and means I set the SCS bit which the UM says "synchronizes the
capture signal with the timer clock (recomended)".

The "Missed 600k" column is EITHER the number of times the correction
algorithm code was entered even if=20
receivedPulses was not incremented due to algorithm disabled, OR (in
parentheses) (600k =96 number counted). Since the correction algorithm=20
is not applicable to h2a algorithm, this column is only meaningful for
the ta algorithm. The "Final Deviation 600k" column
is 600k =96 number of pulses counted.

The h2a algorithm gives correct, reliable count only for MCLK speeds
of 4 and 8 mHz. Why does it miss pulses when=20
running MCLK at 5, 6, & 7 MHz?

The ta algorithm gives correct results at 8 MHz. It also works at 3,
4, and 7 MHz if synchronized input and correction algorithms
are used. Why doesn't it work for MCLK at 5 and 6 MHz?

I suspect I'm not understanding some timing or frequency alignment
principles?

Alg MCLK Correct Sync Missed Deviation
Used Speed Used? Used? Pulses From 600,000

h2a 1.049 y (288) -288
h2a 2.097 y (78) -78
h2a 3.146 n (13) -13
h2a 3.146 y (13) -13
h2a 3.28 y (5) -5
h2a 4.19 y (0) 0
h2a 4.19 n (0) 0
h2a 5.24 y (282) -282
h2a 5.24 y (282) -282
h2a 6.29 y (88) -88
h2a 6.29 n (82) -82
h2a 6.29 y (79) -79
h2a 7.34 y (11) -11
h2a 7.34 n (10) -10
h2a 8.39 0 0
ta 2.097 n n 79 -70
ta 2.097 n n 78 -70
ta 2.097 n y 86 -65
ta 2.097 n y 81 -63
ta 2.097 n y 85 -62
ta 2.097 n y 83 -62
ta 2.097 n y (61) -61
ta 2.097 n y 76 -61
ta 2.097 y n 76 7
ta 2.097 y n 83 10
ta 2.097 y y 81 19
ta 2.097 y y 85 21
ta 2.097 y y 83 22
ta 2.097 y y 87 22
ta 3.146 n y 12 -12
ta 3.146 n y 8 -8
ta 3.146 n y 8 -8
ta 3.146 n y 7 -7
ta 3.146 y y 8 0
ta 3.146 y y 9 0
ta 3.146 y n 25 3
ta 4.149 y y 8 0
ta 4.149 y n 25 2
ta 4.194 y y 0 0=20
ta 4.194 y y 0 0
ta 5.24 y y 120 -147
ta 5.24 y n 121 -146
ta 6.29 y y 80 2
ta 6.29 y n 82 8
ta 7.34 y y 12 0
ta 7.34 y n 7 2
ta 8.39 y n 0 0
ta 8.39 y y 0 0

void main(void)
{
WDTCTL =3D WDTPW + WDTHOLD; // Stop Watchdog Timer
SCFQCTL =3D mclkMultiplier; // Set MCLK to=20
FLL_CTL0 =3D XCAP14PF; // Configure load caps
InitializeGlobalVariables();
InitializeSerial();
InitializeRtc();
InitializeSysConfiguration(); // RAM
InitializeKfactorConfiguration(); // RAM
WriteSysConfigurationNv1(); // non volatile segment 1
WriteSysConfigurationNv2(); // non volatile segment 2
P5DIR |=3D 0x02; // Set P5.1 to output direction
P5DIR |=3D BIT7; // Set P5.7 to output for
pulse output
P5SEL &=3D ~(BIT7); // set P5.7 for basic DIO

#if 0 // using port 1.0 for input=20=20
P1DIR &=3D ~(BIT0); // Set p1.0 to input
P1SEL &=3D ~(BIT0); // set to general purpose DIO
P1IES &=3D ~(BIT0); // set for low-to-high trigger
P1IE |=3D BIT0;
#endif // not using port 1.0 for input=20=20
=20=20
P2DIR &=3D !(BIT0); // set p2.0 to input for
flowmeter pulses
P2SEL |=3D BIT0; // set to peripheral
function as opposed to basic DIO
InitializeTimerA();
// InitializeTimerB();
SetUpdateTimer();
__bis_SR_register(GIE); // w/ interrupt
=20
while (1)
{
// DO STUFF
} // end while 1
} // end main

/



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )


RE: Counting pulses... and missing some... - Mike Raines - Sep 16 9:33:36 2008

Hello,

The table got scrambled. Here is another attampt to send table:
The column headers got scrambled. They are:

AlgorithmUsed

MCLKSpeed

CorrectionAlgorithm

SynchronizedInput

Missed600 k

FinalDeviation600 k

h2a 1.049 y (288) -288

h2a 2.097 y (78) -78

h2a 3.146 n (13) -13

h2a 3.146 y (13) -13

h2a 3.28 y (5) -5

h2a 4.19 y (0) 0

h2a 4.19 n (0) 0

h2a 5.24 y (282) -282

h2a 5.24 y (282) -282

h2a 6.29 y (88) -88

h2a 6.29 n (82) -82

h2a 6.29 y (79) -79

h2a 7.34 y (11) -11

h2a 7.34 n (10) -10

h2a 8.39 0 0

ta 2.097 n n 79 -70

ta 2.097 n n 78 -70

ta 2.097 n y 86 -65

ta 2.097 n y 81 -63

ta 2.097 n y 85 -62

ta 2.097 n y 83 -62

ta 2.097 n y (61) -61

ta 2.097 n y 76 -61

ta 2.097 y n 76 7

ta 2.097 y n 83 10

ta 2.097 y y 81 19

ta 2.097 y y 85 21

ta 2.097 y y 83 22

ta 2.097 y y 87 22

ta 3.146 n y 12 -12

ta 3.146 n y 8 -8

ta 3.146 n y 8 -8

ta 3.146 n y 7 -7

ta 3.146 y y 8 0

ta 3.146 y y 9 0

ta 3.146 y n 25 3

ta 4.149 y y 8 0

ta 4.149 y n 25 2

ta 4.194 y y 0 0

ta 4.194 y y 0 0

ta 5.24 y y 120 -147

ta 5.24 y n 121 -146

ta 6.29 y y 80 2

ta 6.29 y n 82 8

ta 7.34 y y 12 0

ta 7.34 y n 7 2

ta 8.39 y n 0 0

ta 8.39 y y 0 0
.

[Non-text portions of this message have been removed]
------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )

RE: RE: Counting pulses... and missing some... - Mike Raines - Sep 16 9:50:31 2008

Hello, One last attempt to send usable table:
Column headers got scrambled. They are:

Algorithm
Used

MCLK
Speed

Correction
Algorithm

Synchro
nized
Input

missed
600 k

Final
Deviation

600 k
h2a 1.049 y (288) -288
h2a 2.097 y (78) -78
h2a 3.146 n (13) -13
h2a 3.146 y (13) -13
h2a 3.28 y (5) -5
h2a 4.19 y (0) 0
h2a 4.19 n (0) 0
h2a 5.24 y (282) -282
h2a 5.24 y (282) -282
h2a 6.29 y (88) -88
h2a 6.29 n (82) -82
h2a 6.29 y (79) -79
h2a 7.34 y (11) -11
h2a 7.34 n (10) -10
h2a 8.39 0 0
ta 2.097 n n 79 -70
ta 2.097 n n 78 -70
ta 2.097 n y 86 -65
ta 2.097 n y 81 -63
ta 2.097 n y 85 -62
ta 2.097 n y 83 -62
ta 2.097 n y (61) -61
ta 2.097 n y 76 -61
ta 2.097 y n 76 7
ta 2.097 y n 83 10
ta 2.097 y y 81 19
ta 2.097 y y 85 21
ta 2.097 y y 83 22
ta 2.097 y y 87 22
ta 3.146 n y 12 -12
ta 3.146 n y 8 -8
ta 3.146 n y 8 -8
ta 3.146 n y 7 -7
ta 3.146 y y 8 0
ta 3.146 y y 9 0
ta 3.146 y n 25 3
ta 4.149 y y 8 0
ta 4.149 y n 25 2
ta 4.194 y y 0 0
ta 4.194 y y 0 0
ta 5.24 y y 120 -147
ta 5.24 y n 121 -146
ta 6.29 y y 80 2
ta 6.29 y n 82 8
ta 7.34 y y 12 0
ta 7.34 y n 7 2
ta 8.39 y n 0 0
ta 8.39 y y 0 0

.

----------
Column headers got scrambled. They are:

Algorithm
Used

MCLK
Speed

Correction
Algorithm

Synchro
nized
Input

missed
600 k

Final
Deviation

600 k
h2a 1.049 y (288) -288
h2a 2.097 y (78) -78
h2a 3.146 n (13) -13
h2a 3.146 y (13) -13
h2a 3.28 y (5) -5
h2a 4.19 y (0) 0
h2a 4.19 n (0) 0
h2a 5.24 y (282) -282
h2a 5.24 y (282) -282
h2a 6.29 y (88) -88
h2a 6.29 n (82) -82
h2a 6.29 y (79) -79
h2a 7.34 y (11) -11
h2a 7.34 n (10) -10
h2a 8.39 0 0
ta 2.097 n n 79 -70
ta 2.097 n n 78 -70
ta 2.097 n y 86 -65
ta 2.097 n y 81 -63
ta 2.097 n y 85 -62
ta 2.097 n y 83 -62
ta 2.097 n y (61) -61
ta 2.097 n y 76 -61
ta 2.097 y n 76 7
ta 2.097 y n 83 10
ta 2.097 y y 81 19
ta 2.097 y y 85 21
ta 2.097 y y 83 22
ta 2.097 y y 87 22
ta 3.146 n y 12 -12
ta 3.146 n y 8 -8
ta 3.146 n y 8 -8
ta 3.146 n y 7 -7
ta 3.146 y y 8 0
ta 3.146 y y 9 0
ta 3.146 y n 25 3
ta 4.149 y y 8 0
ta 4.149 y n 25 2
ta 4.194 y y 0 0
ta 4.194 y y 0 0
ta 5.24 y y 120 -147
ta 5.24 y n 121 -146
ta 6.29 y y 80 2
ta 6.29 y n 82 8
ta 7.34 y y 12 0
ta 7.34 y n 7 2
ta 8.39 y n 0 0
ta 8.39 y y 0 0
[Non-text portions of this message have been removed]
------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )

Re: Counting pulses... and missing some... - Hugh Molesworth - Sep 17 13:01:20 2008


I looked at your file briefly, and see a number=20
of issues. In particular you need to review your understanding of operators=
.

1.In timer CaptureInputPulses () you have the=20
incorrect form of "&" and "&&". This next line is ALWAYS true, for example:
if (TAIV && 0x02) // if this is timerA capture1
Yet you have the correct form on the very next line:
if (CCTL2 & 0x02) // if missed a pulse

2. Timer A is using ACLK; I seem to recall that=20
is only 32.768kHz on that board; if so you would=20
perhaps be better off using a higher frequency to provide greater resolutio=
n.

3. In main() you do this, which is a bug.=20
"!(BIT0)" may evaluate to 0x00 (false), assuming BIT0 is 0x01.
P2DIR &=3D !(BIT0); // set=20
p2.0 to input for flowmeter pulses
You have the correct form, however, in port=20
CaptureInputPulse () (but that function isn't enabled):
P1IFG &=3D ~(BIT0); // clear interrupt flag

4. In port CaptureInputPulse () (even though that=20
function isn't enabled) you read TAR like this:
timeLastPulse.fraction =3D TAR;
This is "flakey", in the sense that depending on=20
the relative timer clock and cpu clock phase and=20
ratio you might incorrectly read TAR (see errata=20
sheets for details). Typically you have to read=20
TAR and verify it is reasonable (read twice or=20
just check that it is an expected value) or=20
better still use the input pulse to capture TAR in CCR1 (for example).

5. Better to process unused interrupt bits if=20
they get set; ie extend your timer isr to clear other ifg bits

6. In general when dealing with flow meters and=20
the like use edge-triggered timers for slow pulse=20
input rates but use counters when dealing with=20
faster rates. Using both together allows fully=20
automatic tracking of both slow and fast pulse input rates.

Good luck; unfortunately I can't spend more time looking at this.
Hugh

At 06:06 AM 9/16/2008, you wrote:
Folks,

I'm hoping someone can help me understand something fundamental that I'm
missing here. I'm using IAR v4.11, the TI MSP-FET430UIF USB tool, and
the MSP430 4619 chip on an experimenter's board.
We have two of these from last year's school and are using them
because our new project will use the
4619 chip. I have tried both chips and found no differences.

I'm counting pulses from a square waveform generator. Our target
input frequency is 0 =AD 5k Hz.
All the data in the below table was from input frequency of 5 kHz. I
tried two algorithms. h2a is based on a
legacy system and monitors port p1.0 in DIO mode, interrupting on
rising edge. ta algorithm uses timerA
capture/compare2, interrupting on rising edge of p 2.0. The
correction algorithm referenced is applicable to the ta algorithm only
and means that on interrupt, I check (CCTL2 & 0x02) to see if data has
changed since last read. If so, I increment the
receivedPulse count, assuming I only missed one pulse. In the
instances where I count more pulses than were sent, I suspect that
the COV bit is being set erroneously, thus indicating a missed pulse
in error. The Synchronized input is also only applicable to the ta
algorithm
and means I set the SCS bit which the UM says "synchronizes the
capture signal with the timer clock (recomended)".

The "Missed 600k" column is EITHER the number of times the correction
algorithm code was entered even if
receivedPulses was not incremented due to algorithm disabled, OR (in
parentheses) (600k =AD number counted). Since the correction algorithm
is not applicable to h2a algorithm, this column is only meaningful for
the ta algorithm. The "Final Deviation 600k" column
is 600k =AD number of pulses counted.

The h2a algorithm gives correct, reliable count only for MCLK speeds
of 4 and 8 mHz. Why does it miss pulses when
running MCLK at 5, 6, & 7 MHz?

The ta algorithm gives correct results at 8 MHz. It also works at 3,
4, and 7 MHz if synchronized input and correction algorithms
are used. Why doesn't it work for MCLK at 5 and 6 MHz?

I suspect I'm not understanding some timing or frequency alignment
principles?

Alg MCLK Correct Sync Missed Deviation
Used Speed Used? Used? Pulses From 600,000

h2a 1.049 y (288) -288
h2a 2.097 y (78) -78
h2a 3.146 n (13) -13
h2a 3.146 y (13) -13
h2a 3.28 y (5) -5
h2a 4.19 y (0) 0
h2a 4.19 n (0) 0
h2a 5.24 y (282) -282
h2a 5.24 y (282) -282
h2a 6.29 y (88) -88
h2a 6.29 n (82) -82
h2a 6.29 y (79) -79
h2a 7.34 y (11) -11
h2a 7.34 n (10) -10
h2a 8.39 0 0
ta 2.097 n n 79 -70
ta 2.097 n n 78 -70
ta 2.097 n y 86 -65
ta 2.097 n y 81 -63
ta 2.097 n y 85 -62
ta 2.097 n y 83 -62
ta 2.097 n y (61) -61
ta 2.097 n y 76 -61
ta 2.097 y n 76 7
ta 2.097 y n 83 10
ta 2.097 y y 81 19
ta 2.097 y y 85 21
ta 2.097 y y 83 22
ta 2.097 y y 87 22
ta 3.146 n y 12 -12
ta 3.146 n y 8 -8
ta 3.146 n y 8 -8
ta 3.146 n y 7 -7
ta 3.146 y y 8 0
ta 3.146 y y 9 0
ta 3.146 y n 25 3
ta 4.149 y y 8 0
ta 4.149 y n 25 2
ta 4.194 y y 0 0
ta 4.194 y y 0 0
ta 5.24 y y 120 -147
ta 5.24 y n 121 -146
ta 6.29 y y 80 2
ta 6.29 y n 82 8
ta 7.34 y y 12 0
ta 7.34 y n 7 2
ta 8.39 y n 0 0
ta 8.39 y y 0 0

void main(void)
{
WDTCTL =3D WDTPW + WDTHOLD; // Stop Watchdog Timer
SCFQCTL =3D mclkMultiplier; // Set MCLK to
FLL_CTL0 =3D XCAP14PF; // Configure load caps
InitializeGlobalVariables();
InitializeSerial();
InitializeRtc();
InitializeSysConfiguration(); // RAM
InitializeKfactorConfiguration(); // RAM
WriteSysConfigurationNv1(); // non volatile segment 1
WriteSysConfigurationNv2(); // non volatile segment 2
P5DIR |=3D 0x02; // Set P5.1 to output direction
P5DIR |=3D BIT7; // Set P5.7 to output for
pulse output
P5SEL &=3D ~(BIT7); // set P5.7 for basic DIO

#if 0 // using port 1.0 for input
P1DIR &=3D ~(BIT0); // Set p1.0 to input
P1SEL &=3D ~(BIT0); // set to general purpose DIO
P1IES &=3D ~(BIT0); // set for low-to-high trigge=
r
P1IE |=3D BIT0;
#endif // not using port 1.0 for input

P2DIR &=3D !(BIT0); // set p2.0 to input for
flowmeter pulses
P2SEL |=3D BIT0; // set to peripheral
function as opposed to basic DIO
InitializeTimerA();
// InitializeTimerB();
SetUpdateTimer();
__bis_SR_register(GIE); // w/ interrupt

while (1)
{
// DO STUFF
} // end while 1
} // end main

/



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )

Re: Counting pulses... and missing some... - Hugh Molesworth - Sep 17 13:07:05 2008

I missed adding a bit to (1): because TAIV is=20
non-zero due to any CCRx interrupt flag set

Hugh

At 10:00 AM 9/17/2008, you wrote:

I looked at your file briefly, and see a number
of issues. In particular you need to review your understanding of operators=
.

1.In timer CaptureInputPulses () you have the
incorrect form of "&" and "&&". This next line is ALWAYS true, for example:
if (TAIV && 0x02) // if this is timerA capture1
Yet you have the correct form on the very next line:
if (CCTL2 & 0x02) // if missed a pulse

2. Timer A is using ACLK; I seem to recall that
is only 32.768kHz on that board; if so you would
perhaps be better off using a higher frequency to provide greater resolutio=
n.

3. In main() you do this, which is a bug.
"!(BIT0)" may evaluate to 0x00 (false), assuming BIT0 is 0x01.
P2DIR &=3D !(BIT0); // set
p2.0 to input for flowmeter pulses
You have the correct form, however, in port
CaptureInputPulse () (but that function isn't enabled):
P1IFG &=3D ~(BIT0); // clear interrupt flag

4. In port CaptureInputPulse () (even though that
function isn't enabled) you read TAR like this:
timeLastPulse.fraction =3D TAR;
This is "flakey", in the sense that depending on
the relative timer clock and cpu clock phase and
ratio you might incorrectly read TAR (see errata
sheets for details). Typically you have to read
TAR and verify it is reasonable (read twice or
just check that it is an expected value) or
better still use the input pulse to capture TAR in CCR1 (for example).

5. Better to process unused interrupt bits if
they get set; ie extend your timer isr to clear other ifg bits

6. In general when dealing with flow meters and
the like use edge-triggered timers for slow pulse
input rates but use counters when dealing with
faster rates. Using both together allows fully
automatic tracking of both slow and fast pulse input rates.

Good luck; unfortunately I can't spend more time looking at this.
Hugh

At 06:06 AM 9/16/2008, you wrote:
Folks,

I'm hoping someone can help me understand something fundamental that I'm
missing here. I'm using IAR v4.11, the TI MSP-FET430UIF USB tool, and
the MSP430 4619 chip on an experimenter's board.
We have two of these from last year's school and are using them
because our new project will use the
4619 chip. I have tried both chips and found no differences.

I'm counting pulses from a square waveform generator. Our target
input frequency is 0 =AD 5k Hz.
All the data in the below table was from input frequency of 5 kHz. I
tried two algorithms. h2a is based on a
legacy system and monitors port p1.0 in DIO mode, interrupting on
rising edge. ta algorithm uses timerA
capture/compare2, interrupting on rising edge of p 2.0. The
correction algorithm referenced is applicable to the ta algorithm only
and means that on interrupt, I check (CCTL2 & 0x02) to see if data has
changed since last read. If so, I increment the
receivedPulse count, assuming I only missed one pulse. In the
instances where I count more pulses than were sent, I suspect that
the COV bit is being set erroneously, thus indicating a missed pulse
in error. The Synchronized input is also only applicable to the ta
algorithm
and means I set the SCS bit which the UM says "synchronizes the
capture signal with the timer clock (recomended)".

The "Missed 600k" column is EITHER the number of times the correction
algorithm code was entered even if
receivedPulses was not incremented due to algorithm disabled, OR (in
parentheses) (600k =AD number counted). Since the correction algorithm
is not applicable to h2a algorithm, this column is only meaningful for
the ta algorithm. The "Final Deviation 600k" column
is 600k =AD number of pulses counted.

The h2a algorithm gives correct, reliable count only for MCLK speeds
of 4 and 8 mHz. Why does it miss pulses when
running MCLK at 5, 6, & 7 MHz?

The ta algorithm gives correct results at 8 MHz. It also works at 3,
4, and 7 MHz if synchronized input and correction algorithms
are used. Why doesn't it work for MCLK at 5 and 6 MHz?

I suspect I'm not understanding some timing or frequency alignment
principles?

Alg MCLK Correct Sync Missed Deviation
Used Speed Used? Used? Pulses From 600,000

h2a 1.049 y (288) -288
h2a 2.097 y (78) -78
h2a 3.146 n (13) -13
h2a 3.146 y (13) -13
h2a 3.28 y (5) -5
h2a 4.19 y (0) 0
h2a 4.19 n (0) 0
h2a 5.24 y (282) -282
h2a 5.24 y (282) -282
h2a 6.29 y (88) -88
h2a 6.29 n (82) -82
h2a 6.29 y (79) -79
h2a 7.34 y (11) -11
h2a 7.34 n (10) -10
h2a 8.39 0 0
ta 2.097 n n 79 -70
ta 2.097 n n 78 -70
ta 2.097 n y 86 -65
ta 2.097 n y 81 -63
ta 2.097 n y 85 -62
ta 2.097 n y 83 -62
ta 2.097 n y (61) -61
ta 2.097 n y 76 -61
ta 2.097 y n 76 7
ta 2.097 y n 83 10
ta 2.097 y y 81 19
ta 2.097 y y 85 21
ta 2.097 y y 83 22
ta 2.097 y y 87 22
ta 3.146 n y 12 -12
ta 3.146 n y 8 -8
ta 3.146 n y 8 -8
ta 3.146 n y 7 -7
ta 3.146 y y 8 0
ta 3.146 y y 9 0
ta 3.146 y n 25 3
ta 4.149 y y 8 0
ta 4.149 y n 25 2
ta 4.194 y y 0 0
ta 4.194 y y 0 0
ta 5.24 y y 120 -147
ta 5.24 y n 121 -146
ta 6.29 y y 80 2
ta 6.29 y n 82 8
ta 7.34 y y 12 0
ta 7.34 y n 7 2
ta 8.39 y n 0 0
ta 8.39 y y 0 0

void main(void)
{
WDTCTL =3D WDTPW + WDTHOLD; // Stop Watchdog Timer
SCFQCTL =3D mclkMultiplier; // Set MCLK to
FLL_CTL0 =3D XCAP14PF; // Configure load caps
InitializeGlobalVariables();
InitializeSerial();
InitializeRtc();
InitializeSysConfiguration(); // RAM
InitializeKfactorConfiguration(); // RAM
WriteSysConfigurationNv1(); // non volatile segment 1
WriteSysConfigurationNv2(); // non volatile segment 2
P5DIR |=3D 0x02; // Set P5.1 to output direction
P5DIR |=3D BIT7; // Set P5.7 to output for
pulse output
P5SEL &=3D ~(BIT7); // set P5.7 for basic DIO

#if 0 // using port 1.0 for input
P1DIR &=3D ~(BIT0); // Set p1.0 to input
P1SEL &=3D ~(BIT0); // set to general purpose DI=
O
P1IES &=3D ~(BIT0); // set for low-to-high trigg=
er
P1IE |=3D BIT0;
#endif // not using port 1.0 for input

P2DIR &=3D !(BIT0); // set p2.0 to input for
flowmeter pulses
P2SEL |=3D BIT0; // set to peripheral
function as opposed to basic DIO
InitializeTimerA();
// InitializeTimerB();
SetUpdateTimer();
__bis_SR_register(GIE); // w/ interrupt

while (1)
{
// DO STUFF
} // end while 1
} // end main

/



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )

RE: Counting pulses... and missing some... - Mike Raines - Sep 17 13:16:40 2008

Hugh, Thanks so much for your response and the time you spent looking at this.
All your points are valid. the disabled code was for the other algorithm. I'll correct all
the mistakes you found. I have also stripped the application down to ground zero by
removing everything except the pulse counting for debugging purposes. I think I was clouding
the issues by testing a bug with flow calculations, serial output ind input, output pulse, etc.
Thanks again,
Mike Raines
________________________________
From: m...@yahoogroups.com [mailto:m...@yahoogroups.com] On Behalf Of Hugh Molesworth
Sent: Wednesday, September 17, 2008 1:07 PM
To: m...@yahoogroups.com
Subject: Re: [msp430] Counting pulses... and missing some...
I missed adding a bit to (1): because TAIV is
non-zero due to any CCRx interrupt flag set

Hugh

At 10:00 AM 9/17/2008, you wrote:

I looked at your file briefly, and see a number
of issues. In particular you need to review your understanding of operators.

1.In timer CaptureInputPulses () you have the
incorrect form of "&" and "&&". This next line is ALWAYS true, for example:
if (TAIV && 0x02) // if this is timerA capture1
Yet you have the correct form on the very next line:
if (CCTL2 & 0x02) // if missed a pulse

2. Timer A is using ACLK; I seem to recall that
is only 32.768kHz on that board; if so you would
perhaps be better off using a higher frequency to provide greater resolution.

3. In main() you do this, which is a bug.
"!(BIT0)" may evaluate to 0x00 (false), assuming BIT0 is 0x01.
P2DIR &= !(BIT0); // set
p2.0 to input for flowmeter pulses
You have the correct form, however, in port
CaptureInputPulse () (but that function isn't enabled):
P1IFG &= ~(BIT0); // clear interrupt flag

4. In port CaptureInputPulse () (even though that
function isn't enabled) you read TAR like this:
timeLastPulse.fraction = TAR;
This is "flakey", in the sense that depending on
the relative timer clock and cpu clock phase and
ratio you might incorrectly read TAR (see errata
sheets for details). Typically you have to read
TAR and verify it is reasonable (read twice or
just check that it is an expected value) or
better still use the input pulse to capture TAR in CCR1 (for example).

5. Better to process unused interrupt bits if
they get set; ie extend your timer isr to clear other ifg bits

6. In general when dealing with flow meters and
the like use edge-triggered timers for slow pulse
input rates but use counters when dealing with
faster rates. Using both together allows fully
automatic tracking of both slow and fast pulse input rates.

Good luck; unfortunately I can't spend more time looking at this.
Hugh

At 06:06 AM 9/16/2008, you wrote:
Folks,

I'm hoping someone can help me understand something fundamental that I'm
missing here. I'm using IAR v4.11, the TI MSP-FET430UIF USB tool, and
the MSP430 4619 chip on an experimenter's board.
We have two of these from last year's school and are using them
because our new project will use the
4619 chip. I have tried both chips and found no differences.

I'm counting pulses from a square waveform generator. Our target
input frequency is 0 5k Hz.
All the data in the below table was from input frequency of 5 kHz. I
tried two algorithms. h2a is based on a
legacy system and monitors port p1.0 in DIO mode, interrupting on
rising edge. ta algorithm uses timerA
capture/compare2, interrupting on rising edge of p 2.0. The
correction algorithm referenced is applicable to the ta algorithm only
and means that on interrupt, I check (CCTL2 & 0x02) to see if data has
changed since last read. If so, I increment the
receivedPulse count, assuming I only missed one pulse. In the
instances where I count more pulses than were sent, I suspect that
the COV bit is being set erroneously, thus indicating a missed pulse
in error. The Synchronized input is also only applicable to the ta
algorithm
and means I set the SCS bit which the UM says "synchronizes the
capture signal with the timer clock (recomended)".

The "Missed 600k" column is EITHER the number of times the correction
algorithm code was entered even if
receivedPulses was not incremented due to algorithm disabled, OR (in
parentheses) (600k number counted). Since the correction algorithm
is not applicable to h2a algorithm, this column is only meaningful for
the ta algorithm. The "Final Deviation 600k" column
is 600k number of pulses counted.

The h2a algorithm gives correct, reliable count only for MCLK speeds
of 4 and 8 mHz. Why does it miss pulses when
running MCLK at 5, 6, & 7 MHz?

The ta algorithm gives correct results at 8 MHz. It also works at 3,
4, and 7 MHz if synchronized input and correction algorithms
are used. Why doesn't it work for MCLK at 5 and 6 MHz?

I suspect I'm not understanding some timing or frequency alignment
principles?

Alg MCLK Correct Sync Missed Deviation
Used Speed Used? Used? Pulses From 600,000

h2a 1.049 y (288) -288
h2a 2.097 y (78) -78
h2a 3.146 n (13) -13
h2a 3.146 y (13) -13
h2a 3.28 y (5) -5
h2a 4.19 y (0) 0
h2a 4.19 n (0) 0
h2a 5.24 y (282) -282
h2a 5.24 y (282) -282
h2a 6.29 y (88) -88
h2a 6.29 n (82) -82
h2a 6.29 y (79) -79
h2a 7.34 y (11) -11
h2a 7.34 n (10) -10
h2a 8.39 0 0
ta 2.097 n n 79 -70
ta 2.097 n n 78 -70
ta 2.097 n y 86 -65
ta 2.097 n y 81 -63
ta 2.097 n y 85 -62
ta 2.097 n y 83 -62
ta 2.097 n y (61) -61
ta 2.097 n y 76 -61
ta 2.097 y n 76 7
ta 2.097 y n 83 10
ta 2.097 y y 81 19
ta 2.097 y y 85 21
ta 2.097 y y 83 22
ta 2.097 y y 87 22
ta 3.146 n y 12 -12
ta 3.146 n y 8 -8
ta 3.146 n y 8 -8
ta 3.146 n y 7 -7
ta 3.146 y y 8 0
ta 3.146 y y 9 0
ta 3.146 y n 25 3
ta 4.149 y y 8 0
ta 4.149 y n 25 2
ta 4.194 y y 0 0
ta 4.194 y y 0 0
ta 5.24 y y 120 -147
ta 5.24 y n 121 -146
ta 6.29 y y 80 2
ta 6.29 y n 82 8
ta 7.34 y y 12 0
ta 7.34 y n 7 2
ta 8.39 y n 0 0
ta 8.39 y y 0 0

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog Timer
SCFQCTL = mclkMultiplier; // Set MCLK to
FLL_CTL0 = XCAP14PF; // Configure load caps
InitializeGlobalVariables();
InitializeSerial();
InitializeRtc();
InitializeSysConfiguration(); // RAM
InitializeKfactorConfiguration(); // RAM
WriteSysConfigurationNv1(); // non volatile segment 1
WriteSysConfigurationNv2(); // non volatile segment 2
P5DIR |= 0x02; // Set P5.1 to output direction
P5DIR |= BIT7; // Set P5.7 to output for
pulse output
P5SEL &= ~(BIT7); // set P5.7 for basic DIO

#if 0 // using port 1.0 for input
P1DIR &= ~(BIT0); // Set p1.0 to input
P1SEL &= ~(BIT0); // set to general purpose DIO
P1IES &= ~(BIT0); // set for low-to-high trigger
P1IE |= BIT0;
#endif // not using port 1.0 for input

P2DIR &= !(BIT0); // set p2.0 to input for
flowmeter pulses
P2SEL |= BIT0; // set to peripheral
function as opposed to basic DIO
InitializeTimerA();
// InitializeTimerB();
SetUpdateTimer();
__bis_SR_register(GIE); // w/ interrupt

while (1)
{
// DO STUFF
} // end while 1
} // end main

/=======================================================================
//=======================================================================

#if 0 // using port 1.0 for input
// Digital I/O input pulse ISR
//#pragma vector=0x0ffE8
#pragma vector=PORT1_VECTOR
__interrupt void CaptureInputPulse(void)
{

if (P1IFG & 0x01) // if this is p1.0 interrupt
{
inputPulses ++; // increment # pulses
received
timeLastPulse.seconds = sysTime.seconds; // record time pulse
received
// timeLastPulse.seconds = RTCSEC; // record time pulse received
timeLastPulse.fraction = TAR;
P1IFG &= ~(BIT0); // clear interrupt flag
} // end if this is p1.0 interrupt

} // end ISR function void CaptureInputPulse(void)

#endif // not using port 1.0 for input

//=======================================================================
//=======================================================================

#if 1 // using Timer A for input pulses

// Timer A0 Capture interrupt service routine
#pragma vector=TIMERA1_VECTOR
__interrupt void CaptureInputPulses (void)
{
if (TAIV && 0x02) // if this is timerA capture1
{

if (CCTL2 & 0x02) // if missed a pulse
{
#if 1 // correct input count // correction algorithm
inputPulses ++; // add missed pulse
#endif // correct input count
missedPulses ++;
CCTL2 &= ~(0x02); // clear flag
} // end if missed pulse

inputPulses ++; // increment # pulses
received
timeLastPulse.seconds = sysTime.seconds; // record time pulse
received
// timeLastPulse.seconds = RTCSEC; // record time pulse received
timeLastPulse.fraction = CCR2;
} // end if timerA capture1

// P5OUT ^= 0x02; // Toggle P5.1 using
exclusive-OR
} // end ISR function CaptureInputPulses (void)

#endif // using Timer A for input pulses

//=======================================================================
//=======================================================================

void InitializeTimerA(void)
{
// CCR0 = 32768-1;
CCR0 = timerACcr0;
TACTL = TASSEL_1+MC_1; // ACLK, upmode
CCTL0 |= CCIE; // enable CCRO interrupt

#if 1 // using Timer A for input pulses

// CCTL1 = 0x4910; // rising edge,p1.2,sync,cap,interrupt enabled

CCTL2 = 0x4910; // rising edge,p2.0,sync,cap,interrupt enabled
// CCTL2 = 0x4110; // rising edge,p2.0,NO sync,cap,interrupt
enabled

#endif // using Timer A for input pulses

sysTime.seconds = 0; // start system timer
// sysTime.seconds = 32752; // Rollover test; zero
for target
sysTime.fraction = 0;

} // end function IntitialzeTimerA(void)

//=======================================================================
//=======================================================================

[Non-text portions of this message have been removed]
------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )