softfilt_test.c - Implements a software filter for input pulses less than a specified duration.ΒΆ
 
#include "pic24_all.h"
 
 
Use RB9 as the test output (TOUT).
#define CONFIG_TOUT() CONFIG_RB9_AS_DIG_OUTPUT()
#define TOUT  (_LATB9)
 
Use RB8 as the raw test input (TIN).
#define CONFIG_TIN_RAW()  CONFIG_RB8_AS_DIG_INPUT();
#define TIN_RAW (_RB8)
 
 
Define the time, in ms, between Timer3 interrupts.
#define ISR_PERIOD (1)
The software filter only passes changes in the TIN input if the TIN input is stable for MIN_STABLE number of milliseconds
#define MIN_STABLE (15)
The minimum number of timer3 interrupts that TIN must be stable for in order for a new value to pass through the filter.
#define MIN_STABLECOUNT  (MIN_STABLE/ISR_PERIOD)
uint16_t u16_stableCountTIN = 0;
uint8_t u8_rawTIN = 0;
uint8_t u8_oldrawTIN = 0;
 
 
Debounced switch value that is set in the timer ISR. Any variable written by an ISR, and accessed outside of the ISR should be declared volatile.
volatile uint8_t u8_valueTIN = 0;
 
Interrupt Service Routine for Timer3
void _ISR _T3Interrupt(void) {
  u8_rawTIN = TIN_RAW;     //sample the switch
  if (u8_rawTIN != u8_oldrawTIN) {
    //changed values, zero the stability counter
    u16_stableCountTIN = 0;
    u8_oldrawTIN = u8_rawTIN;
  } else {
    u16_stableCountTIN++;
    if (u16_stableCountTIN >= MIN_STABLECOUNT) {
      //new value is ready!
      u8_valueTIN = u8_rawTIN;
    }
  }
  _T3IF = 0;                 //clear the timer interrupt bit
}
void  configTimer3(void) {
Ensure that Timer2,3 configured as separate timers.
  T2CONbits.T32 = 0;     // 32-bit mode off
T3CON set like this for documentation purposes.
  T3CON = T3_OFF |T3_IDLE_CON | T3_GATE_OFF
          | T3_SOURCE_INT
          | T3_PS_1_1;
Subtract 1 from ticks value assigned to PR3 because period is PRx + 1.
  PR3 = msToU16Ticks(ISR_PERIOD, getTimerPrescale(T3CONbits)) - 1;
Start with a cleared timer2 value.
  TMR3  = 0;
Enable Timer3 interrupts.
  _T3IF = 0;
  _T3IP = 1;
  _T3IE = 1;
Start the timer only after all timer-related configuration is complete.
  T3CONbits.TON = 1;
}
uint8_t u8_oldvalueTIN = 0;
 
Define the pulse width of TOUT in ms.
#define TPW  (20)
int main(void) {
  configBasic(HELLO_MSG);
TOUT drives TIN.
  TOUT = 0;
  CONFIG_TIN_RAW();
  CONFIG_TOUT();
  configTimer3();
  while (1) {
    TOUT = !TOUT;
    DELAY_MS(TPW);
    if (u8_valueTIN != u8_oldvalueTIN) {
      u8_oldvalueTIN = u8_valueTIN;
      outString("*");
    }
  }
}