OK, I was gonna sit on this for a few more days until I had a chance to perfect it a little more, but here it is now in it's crude form. I'm sure it needs lots of fixing to be "good" code, but it's functional as is and hopefully will give a starting place for folks who want to play with the capacitive sensing module on the 16F72X PIC's. Please feel free to critique it and fix it up. I need the education...
This program sets up Capacitive Sensing pin0 (CPS0/RB0) on the 16F726 / 16F727 to be a "Touch Sensor" pin
When the sensor pad is touched, the raw count (from TMR1) will drop below the running average and a LED on PORTA.1 will flash. If the finger is held on the pad long enough, eventually the running average will catch up with the current value and the LED will turn off.
Relevant Data Sheets for the CSM module include:
http://ww1.microchip.com/downloads/e...Doc/41341B.pdf 16F72X / 16LF72X Data Sheet.
http://ww1.microchip.com/downloads/e...tes/01101a.pdf AN1101 "Introduction to Capacitive Sensing "
http://ww1.microchip.com/downloads/e...tes/01103a.pdf AN1103 'Software Handling for Capacitive Sensing"
http://ww1.microchip.com/downloads/e...tes/01171B.pdf AN1171 "Using the Capacitive Sensing Module on the PIC16F72X"
Crude Code follows.... Enjoy!
Steve
------------
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 8
OSCCON = $10 'set oscillator to 8 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 : LOW rw 'Read/Write for LCD
LED var PORTA.1 'LED to display when button is pressed
'-----Allocate Variables
timercount var word ' raw count from TMR1
timerave var word ' long term average of timercount
AvgCount var word : AvgCount = 32 'number of samples to average
'-----Set up Interrrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1GATE_INT, _CheckCount, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1GATE_INT ; enable Timer 2 interrupts
High LED
Pause 200 'Let the LCd wake up
lcdout $fe, 1 'Clear LCD
lcdout $fe, 2, " Awake! "
pause 500
'----- Timer Setup
T2CON = %01110110 'bit7=unimplemented, bit6-3=postscaler, bit2=TMRON, bit1-0=prescaler
PR2 = %11111111 'give PR2 a number for TMR2 to match
PIR1.1 = 0 'Clear the TMR2 interupt flag
PIE1.1 = 1 'Turn TMR2 interrupt enable on
T1CON = %11000101 'Timer clock source=CAPOSC, prescale=1:1, 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
Goto main 'Just get it going...
'---[TMR2 - interrupt handler]--------------------------------------------------
disable
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
Gosub Fingercheck
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
@ INT_RETURN
enable
'----Average the timercount result----------------------------------------------
Fingercheck:
timerave = timerave - (timerave/AvgCount) 'average the count so you have a reference to compare....
timerave = timerave + (timercount/AvgCount) '...with yimercount
If timerave - (timerave /40) > timercount then 'If timercount drops more than 2.5% below the average, signal that a button is pressed.
low LED 'make the LED do a little dance.
pause 50
High LED
pause 25
endif
If timercount > timerave +50 then 'do a "fast recovery" on the average when finger is removed.
timerave = timercount
endif
return
'----Main loop-----------------------------------------------------------
Main:
LCDOUT $fe,2, " Count= ", dec timercount," ",$fe,$C0,"Average = ", dec timerave," "
pause 50
GOTO Main
end
Bookmarks