I'm trying to learn to use the Capacitive Sensing Module (CSM) on the PIC16F727. I've had some minor success getting the CSM set up and running, and with reading the count from TMR1 to an LCD module.

I'm using (trying) Darrel's Instant Interrupts to run an ISR when TMR2 matches PR2, but I clearly don't understand what I'm doing yet...

Here's the part that works so far:
I've got the CSM oscillator running and I can see the triangle wave on pin B0. I've got a wire and "touchpad" connected to it, and when I touch the pad the oscillator slows way down, so that part is working great.


Here's what I'm *trying* to do at this point :

Timer1 is used to count pulses on the cap sensing oscillator. It is set up so that Timer2 controls the gate of Timer1 and starts/stops the Timer1 counter.

Timer2 counts until it matches the value in the PR2 register, then stops Timer1 and triggers an interrupt.

The ISR reads the count in the Timer1 register and stores it in a variable called "timercount", then it resets the registers to 0, resets Timer2 to 0, clears the Timer2 interrupt flag, and restarts the timers.

The main loop is supposed to read the contents of "timercount" and display it on an LCD so I can read the change in timercount when a finger touches the sensing pad.


Here's the problems I'm having (so far):

First, the Interrupt seems to "steal the show" and the program never enters the main loop and displays the data on LCD, UNLESS I put a "goto Main" inside the ISR routine. Then it will display my value on the LCD.

Second, the count in TMR1 seems to be entirely dependent on the length of the "pause" in the main loop. With 100mS pause the timer reads about 15,000 counts, with a 200mS pause it reads about 29,000 counts. What's up with that? The ISR zeros the timers each time through.

I've read sections 11-14 (using the timers and CSM) of the 16F727 datasheet (41341B.pdf) *repeatedly*, as well as AN1103 and AN1171 which explain using the CSM in the 16F727. Hey, I even managed to make Darrels "Blinky light" interrupt example work for me, but alas, I seem unable to pull it all together and make the touch sensor routine work. I figured I'd start by reading the count in TMR1 to an LCD so I can see what's happening..

I've been hammering away at this for quite a while and starting to feel rather lost.

Here's the code I've got so far if someone would *please* be so kind as to take a look and offer advice..

Code:
'-------------------------------------------------------------------------------
'Trying to learn to use the Capacitive Sensing Module on a 16F727 --------------
'-------------------------------------------------------------------------------

@  __config _CONFIG1, _DEBUG_OFF & _PLL_EN & _BORV_2_5 & _BOR_ON & _CP_OFF & _MCLRE_OFF & _PWRT_EN & _WDT_OFF & _INTOSCIO
@  __config _CONFIG2, _VCAP_RA0

Include "MODEDEFS.BAS"    ' Include Shiftin/out modes
INCLUDE "DT_INTS-14.bas"  ' Base Interrupt System
INCLUDE "ReEnterPBP.bas"  ' Include if using PBP interrupts

DEFINE LCD_DREG PORTA    ' Set LCD Data port
DEFINE LCD_DBIT 4        ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTA   ' Set LCD Register Select port
DEFINE LCD_RSBIT 2       ' Set LCD Register Select bit
DEFINE LCD_EREG PORTC    ' Set LCD Enable port                                                   
DEFINE LCD_EBIT 0        ' Set LCD Enable bit
DEFINE LCD_BITS 4        ' Set LCD bus size (4 or 8 bits)
DEFINE ADC_BITS 8        ' Set number of bits in ADC result
DEFINE ADC_CLOCK 3       ' Set clock source for ADC (rc = 3)
DEFINE ADC_SAMPLEUS 100  ' Set ADC sampling time in microseconds 
DEFINE OSC 4

OSCCON = $10         'set oscillator to 4 Mhz

TRISA= %00000000     'Set 'em all to outputs
ANSELA= %00000000	 'Set 'em all to digital
TRISB= %11111111   	 'all input
ANSELB= %11111111    'all analog
TRISC= %00000000     'Set portC all outputs   

CPSCON0 = %10001101  'Cap sense on, high range oscillator
CPSCON1 = %00000000  'Cap sense channel input 0 is selected

'-----Alias Pins
RW           var    PORTC.3   'Read/Write line for the LCD

'-----Allocate Variables
timercount   var    word   ' A place to store the count from TMR1

'-----Set up Interrrupts
ASM
INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
        INT_Handler   TMR2_INT,  _CheckCount,   PBP,  yes
     endm    
    INT_CREATE               ; Creates the interrupt processor
ENDASM

@ INT_ENABLE  TMR2_INT     ; enable Timer 2 interrupts



low rw          'LCD Read/Write line low (write)
Pause 200       'Let the LCd wake up
lcdout $fe, 1   'Clear LCD

'----- Timer Setup
T2CON.2 = 1     'TMR2 on
T2CON.0 =1      'adjust prescaler
PR2 = $B4       ' w/prescale=1:1, $B4 sets 125us scan rate.  '= 10110100
PIR1.1 = 0      'Clear the TMR2 interupt flag
PIE1.1 = 1      'Turn TMR2 interrupt enable on
T1CON = %11010101 'clock=CAPOSC, prescale=1:2, dedicated OSC disabled, no external clock synchronize, timer on
T1GCON = %11100010 'Timer1 gate init/ Toggle Mode
PIR1.7 = 0   'Clear Gate Interrupt Flag
PIR1.1 = 0   'clear the TMR2 interupt flag
PIE1.7 = 1 'Enable Gate Interrupt

Goto main   'Just get it going...

'---[TMR2 - interrupt handler]--------------------------------------------------
    disable   'I think I need to kill the interupts here..?
CheckCount:
    T2CON.2 = 0   'stop timer2
    T1CON.0 = 0   'stop timer1
    timercount = TMR1L + TMR1H << 8   'stuff the contents of the timer register into a word
    TMR1L = 0     'reset counter to 0...
    TMR1H = 0     'upper 1/2 too
    TMR2 = 0       'rest timer 2
    PIR1.1 = 0   'Clear TMR2 Interrupt Flag
    T1CON.0 = 1  'restart timer1
    T2CON.2 = 1  'restart timer2
  '  gosub main    'if I don't add this, I never seem to get out of the interrupt and return to the main routine...
@ INT_RETURN
    enable     're-enable interrupts
    
'----Main loop-----------------------------------------------------------
Main:
    LCDOUT $fe,2, " Count= ", dec timercount,"    ",$fe,$C0,"  TMR2 = ", dec timertemp,"    "
    pause 100   'changing the duration of the pause also changes the count on timer1.  Why?
    return    
  
GOTO Main

    end

Thanks very much,

Steve