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