Hi
I'm trying to get two Interrupt Service Routines to measure pulse width on two separate Port T lines, 2 and 3, using the Input Capture function on a DP256-based board from Wytec. When I test either channel separately, by removing the external signal from the pin, I can read the remaining signal. However, when I plug in both lines, only the signal for Channel 2 (on PT2) comes through. I'm not sure what I'm doing wrong and would really appreciate any pointers. (ISR code is quoted below)
Thanks!
James
/* ---------------------------------------------------- * ISR for Input Capture 2, connected to Port T, pin 2. * * Uses global variables: glb_edge_rising_ch2, glb_edge_falling_ch2 * & glb_pulse_width_ch2 * * Original Source: * Based on Valvano's starter code from IC_DP512.mcp. * Masking trick from Huang's text, section 8.1-8.5 * * Modified by James A. Smith * ---------------------------------------------------- */void interrupt 10 IC2Han(void){ /* Now that interrupt was generated, was it a rising edge?*/ if(TCTL4_EDG2A==1){ /* it was a rising edge */ glb_edge_rising_ch2 = TC2; /* Now set to look for the other falling edge next time. */ TCTL4 = (TCTL4 | 0x20) & ~0x10; // Mask so that either edge of // Ch. 3 will be enabled (as per its ISR) and // just the falling edge of Ch. 2 ("B" is falling edge). /* when the new pulse comes in, calculate things */ glb_total_period_ch2 = glb_edge_rising_ch2 - glb_edge_rising_old_ch2; glb_edge_rising_old_ch2 = glb_edge_rising_ch2; /* update */ } else{ /* falling edge */ glb_edge_falling_ch2 = TC2; /* now set to look for the rising edge next time. */ TCTL4 = (TCTL4 | 0x10) & ~0x20; // Mask so that either edge of // Ch. 3 will be enabled (as per its ISR) and // just the rising edge of Ch. 2 ("A" is falling edge). /* Only calculate the width after a falling edge was found */ glb_pulse_width_ch2 = glb_edge_falling_ch2 - glb_edge_rising_ch2; } TFLG1_C2F = 1; // clear timer flag for Channel 2.}/* ---------------------------------------------------- * ISR for Input Capture 3, connected to Port T, pin 3. * * Uses global variables: glb_edge_rising_ch3, glb_edge_falling_ch3 * & glb_pulse_width_ch3 * * Original Source: * Based on Valvano's starter code from IC_DP512.mcp. * Masking trick from Huang's text, section 8.1-8.5 * * Modified by James A. Smith * ---------------------------------------------------- */void interrupt 11 IC3Han(void){ /* Now that interrupt was generated, was it a rising edge?*/ if(TCTL4_EDG3A==1){ /* it was a rising edge */ glb_edge_rising_ch3 = TC3; /* Now set to look for the other falling edge next time. */ TCTL4 = (TCTL4 | 0x80) & ~0x40; // Mask so that either edge of // Ch. 2 will be enabled (as per its ISR) and // just the falling edge of Ch. 3 ("B" is falling edge). /* when the new pulse comes in, calculate things */ glb_total_period_ch3 = glb_edge_rising_ch3 - glb_edge_rising_old_ch3; glb_edge_rising_old_ch3 = glb_edge_rising_ch3; /* update */ } else{ /* falling edge */ glb_edge_falling_ch3 = TC3; /* now set to look for the rising edge next time. */ TCTL4 = (TCTL4 | 0x40) & ~0x80; // Mask so that either edge of // Ch. 2 will be enabled (as per its ISR) and // just the rising edge of Ch. 3 ("A" is falling edge). /* Only calculate the width after a falling edge was found */ glb_pulse_width_ch3 = glb_edge_falling_ch3 - glb_edge_rising_ch3; } TFLG1_C3F = 1; // clear timer flag for Channel 3.}
Solved! Go to Solution.
TFLG1_C3F = 1; // clear timer flag for Channel 3.
Comment is wrong. It should be clear ALL TFLG1 flags. These flags are cleared be writing '1' to flag. You can't write just C3F without writing whole TFLG1 register. You ordered to set C3F and preserve other CxF flags. This means CPU has to read TFLG1, perform OR with bitpattern that has C3F set, then write resulting bitpattern back to TFLG1. What happens when C1F is set? .. Right, both C1F and C3F and all other flags that were set will be cleared!!!!!!!
TFLG1_C3F = 1; // WRONG
TFLG1_C3F = 0; // WRONG
TFLG1 |= TFLG1_C3F_MASK; // WRONG
TFLG1 &= ~TFLG1_C3F_MASK; // WRONG
TFLG1 = TFLG1_C3F_MASK; // OK
TFLG1 &= TFLG1_C3F_MASK; // OK
TFLG1_C3F = 1; // clear timer flag for Channel 3.
Comment is wrong. It should be clear ALL TFLG1 flags. These flags are cleared be writing '1' to flag. You can't write just C3F without writing whole TFLG1 register. You ordered to set C3F and preserve other CxF flags. This means CPU has to read TFLG1, perform OR with bitpattern that has C3F set, then write resulting bitpattern back to TFLG1. What happens when C1F is set? .. Right, both C1F and C3F and all other flags that were set will be cleared!!!!!!!
TFLG1_C3F = 1; // WRONG
TFLG1_C3F = 0; // WRONG
TFLG1 |= TFLG1_C3F_MASK; // WRONG
TFLG1 &= ~TFLG1_C3F_MASK; // WRONG
TFLG1 = TFLG1_C3F_MASK; // OK
TFLG1 &= TFLG1_C3F_MASK; // OK
Thanks! Just tested your solution and it worked!