Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Capacitive sensing Moduele with PIC16F727

Status
Not open for further replies.

JChandra

Newbie level 4
Joined
Feb 25, 2011
Messages
6
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,375
Hi,

I am trying to program the PIC16F727 for Capacitive touch sensors. I have read the application notes regarding CSM from Microchip. I programmed according to AN1178. But it wasn't successful. I never get into the loop for change in frequency measurement.

How can I debug the code in real time?

Does anyone has the code which is working? please share!!

Thank you
 

do you want to measure frequency using CSM?

as per application note:

set up timer 1:
TRISA = 0x30;
ANSELA = 0x30; // CPS7, CPS6 initialized as analog inputs
TRISB = 0x3F;
ANSELB = 0x3F; // CPS0-CPS5 initialized as analog inputs
TRISD = 0xFF;
ANSELD = 0xFF; // CPS8-CPS15 initialized as analog inputs
CPSCON0 = 0x8C; // Cap sense on, high range oscillator,
CPSCON1 = 0x00; // Cap sense channel input 0 is selected

then configure and start ADC
then calculate the frequency according to ADC value..
 

Hi,

I programmed according to Application note AN1171 and AN1103. I have copied my code below. When I am debugging this code in MPLAB Sim it is working. But when I programmed this to the hardware, it is not working. It always goes into the "Button is unpressed" condition statements.

When I tried to debug the code with the hardware using PICKIT2, TMR0 and TMR1 increments rapidly (which is not the case with MPLABSIM). I also measured the frequencies on the respective pin, there is a frequency drop. But no success on the hardware.

Is there anything wrong in my code? Please help me!!!!!!!!

//---------------------
//Prototypes
//---------------------
void init(void);
void interrupt_ISR(void);
void setNextChannel(void);
void restartTimers(void);


/******************************************
Main Program
******************************************/

void main (void)
{
CLRWDT();
init();
while(1) {};
}

//----------------------------------------------
//Initializing variables
//----------------------------------------------
void init(void)
{

/****************************************************************************
Capsense channels
7 6 5 4 3 2 1 0
PORT A CPS7 CPS6
PORT B CPS5 CPS4 CPS3 CPS2 CPS1 CPS0
PORT D CPS15 CPS14 CPS13 CPS12 CPS11 CPS10 CPS9 CPS8
*****************************************************************************/

TRISA = 0b00110000;
ANSELA = 0b00110000; //CPS7, CPS6 initialized as analog inputs
TRISB = 0b00111111;
ANSELB = 0b00111111; //CPS0-CPS5 initialized as analog inputs
TRISD = 0b11111111;
ANSELD = 0b11111111; //CPS8-CPS15 initialized as analog inputs





//Capsense module
CPSCON0 = 0b10001100; //bit 7: Capasitive sensing module is operating; //0x8C; // Cap sense on, high range oscillator,
//bits<3:2>: 11=Oscillator is in high range. Current is nominally 18uA
//bit 1: 0=Oscillator is sinking current(Current flowing into the pin)
//bit 0: TOXCS Timer0 external clock source select bit. Timer0 clock source is controlled by Fosc/4 if TOCS=0 (in Option reg bit 5
CPSCON1 = 0x00; //Cap sense channel input 0 is selected
index = CPSCON1;

//Timer0 Time base
OPTION_REG = 0b11000001; // capacitance module with TMR0 as timer. So set-it up through the Option Register. The prescaler is also connected to TMR0.
// Bit 5: TOCS TMR0 Source is internal instruction clock (Fosc/4)
//Bit 3: Prescaller assigned to TMR0 module
// Bits <2:0>: Prescaller rate is 1:4
T0IF = 0;
T0IE = 1; //Start to scan first channel

//Timer1 Timer resource
T1CON = 0b11000101; //Setup TMR1 module Control register
//Bits <7:6>: Timer 1 source is Capacitive Sensing Oscillator
// Bits <5:4>: Prescaller is 1:1
//Bit 3: LP oscillatos is deactivated
// Bit 2: No synchronization
// Bit 0: TMR1ON 0 Timer 1 is stopped
T1GCON = 0b11100001; // Setup Timer 1 Gate module
// Bit 7: TMR1GE 1 Gate controls the counting function of TMR1
// Bit 6: Gate polarity is Active HIGH
// Bit 5: Gate input is through Toggle FF
// Bits <4:3>: No single pulse mode
// Bits <1:0>: Gate source is Timer0 overflow
TMR1GIF = 0;
TMR1GIE = 1;

//Interrupt enable
GIE = 1; //enable Global interrupts

//Initialize Button detection variables
for (index=0; index<NUM_BTTNS; index++)
{
raw_data[index] = 0;
average[index] = 0;
}
}

//-----------------------------------------------------
//Interrupt Service Routine
//-----------------------------------------------------
void interrupt ISR(void)
{
CLRWDT();
if (T0IE && T0IF) //are TMR0 interrupts enabled and is the TMR0 interrupt flag set?
{
T0IF=0; //TMR0 interrupt flag must be cleared in software to allow subsequent interrupts

}

if (TMR1GIF && TMR1GIE) //Timer1 Gate interrupt
{
// Perform touch reading

TMR1GIF = 0; // clear intpt flag
TMR1ON = 0; // Timer1 off

raw_data[index] = TMR1L + (unsigned int)(TMR1H << 8); //read the Timer1 value


threshold = average[index]>>2; //define threshold below average 1/2 = 50% below average

if (raw_data[index] < average[index])// - threshold))
{
//Button is pressed
switch (index)
{
case 0: Buttons.BTN0 = 1; break;
case 1: Buttons.BTN1 = 1; break;
case 2: Buttons.BTN2 = 1; break;
case 3: Buttons.BTN3 = 1; break;
case 4: Buttons.BTN4 = 1; break;
case 5: Buttons.BTN5 = 1; break;
case 6: Buttons.BTN6 = 1; break;
case 7: Buttons.BTN7 = 1; break;
case 8: Buttons.BTN8 = 1; break;
case 9: Buttons.BTN9 = 1; break;
case 10: Buttons.BTN10 = 1; break;
case 11: Buttons.BTN11 = 1; break;
case 12: Buttons.BTN12 = 1; break;
case 13: Buttons.BTN13 = 1; break;
case 14: Buttons.BTN14 = 1; break;
case 15: Buttons.BTN15 = 1; break;
default: break;
}
}
else
{
//Button is unpressed
switch (index)
{
case 0: Buttons.BTN0 = 0; break;
case 1: Buttons.BTN1 = 0; break;
case 2: Buttons.BTN2 = 0; break;
case 3: Buttons.BTN3 = 0; break;
case 4: Buttons.BTN4 = 0; break;
case 5: Buttons.BTN5 = 0; break;
case 6: Buttons.BTN6 = 0; break;
case 7: Buttons.BTN7 = 0; break;
case 8: Buttons.BTN8 = 0; break;
case 9: Buttons.BTN9 = 0; break;
case 10: Buttons.BTN10 = 0; break;
case 11: Buttons.BTN11 = 0; break;
case 12: Buttons.BTN12 = 0; break;
case 13: Buttons.BTN13 = 0; break;
case 14: Buttons.BTN14 = 0; break;
case 15: Buttons.BTN15 = 0; break;
default: break;
}


//Calculate average
//According to AN1103

average[index] = average[index] +\ (raw_data[index] - average[index])/16;

}

setNextChannel(); //Set for next channel
restartTimers(); //Restart the timers
}
}

//----------------------------------------
//Set for next channel
//----------------------------------------
void setNextChannel(void)
{
if (index < NUM_BTTNS-1)
index = index++;
else
index =0;
CPSCON1 = index;
}

//-----------------------------------------
//Restart timers
//-----------------------------------------
void restartTimers(void)
{
TMR1L = 0; //Reset Timer 1
TMR1H = 0;
TMR1ON = 1; //Restart Timer 1
TMR0 = 0; //Reset Timer 0
T0IF = 0; //Clear Timer0 interrupt
}
 

Hi,

I programmed according to Application note AN1171 and AN1103. I have copied my code below. When I am debugging this code in MPLAB Sim it is working. But when I programmed this to the hardware, it is not working. It always goes into the "Button is unpressed" condition statements.

When I tried to debug the code with the hardware using PICKIT2, TMR0 and TMR1 increments rapidly (which is not the case with MPLABSIM). I also measured the frequencies on the respective pin, there is a frequency drop. But no success on the hardware.

Is there anything wrong in my code? Please help me!!!!!!!!

//---------------------
//Prototypes
//---------------------
void init(void);
void interrupt_ISR(void);
void setNextChannel(void);
void restartTimers(void);


/******************************************
Main Program
******************************************/

void main (void)
{
CLRWDT();
init();
while(1) {};
}

//----------------------------------------------
//Initializing variables
//----------------------------------------------
void init(void)
{

/****************************************************************************
Capsense channels
7 6 5 4 3 2 1 0
PORT A CPS7 CPS6
PORT B CPS5 CPS4 CPS3 CPS2 CPS1 CPS0
PORT D CPS15 CPS14 CPS13 CPS12 CPS11 CPS10 CPS9 CPS8
*****************************************************************************/

TRISA = 0b00110000;
ANSELA = 0b00110000; //CPS7, CPS6 initialized as analog inputs
TRISB = 0b00111111;
ANSELB = 0b00111111; //CPS0-CPS5 initialized as analog inputs
TRISD = 0b11111111;
ANSELD = 0b11111111; //CPS8-CPS15 initialized as analog inputs





//Capsense module
CPSCON0 = 0b10001100; //bit 7: Capasitive sensing module is operating; //0x8C; // Cap sense on, high range oscillator,
//bits<3:2>: 11=Oscillator is in high range. Current is nominally 18uA
//bit 1: 0=Oscillator is sinking current(Current flowing into the pin)
//bit 0: TOXCS Timer0 external clock source select bit. Timer0 clock source is controlled by Fosc/4 if TOCS=0 (in Option reg bit 5
CPSCON1 = 0x00; //Cap sense channel input 0 is selected
index = CPSCON1;

//Timer0 Time base
OPTION_REG = 0b11000001; // capacitance module with TMR0 as timer. So set-it up through the Option Register. The prescaler is also connected to TMR0.
// Bit 5: TOCS TMR0 Source is internal instruction clock (Fosc/4)
//Bit 3: Prescaller assigned to TMR0 module
// Bits <2:0>: Prescaller rate is 1:4
T0IF = 0;
T0IE = 1; //Start to scan first channel

//Timer1 Timer resource
T1CON = 0b11000101; //Setup TMR1 module Control register
//Bits <7:6>: Timer 1 source is Capacitive Sensing Oscillator
// Bits <5:4>: Prescaller is 1:1
//Bit 3: LP oscillatos is deactivated
// Bit 2: No synchronization
// Bit 0: TMR1ON 0 Timer 1 is stopped
T1GCON = 0b11100001; // Setup Timer 1 Gate module
// Bit 7: TMR1GE 1 Gate controls the counting function of TMR1
// Bit 6: Gate polarity is Active HIGH
// Bit 5: Gate input is through Toggle FF
// Bits <4:3>: No single pulse mode
// Bits <1:0>: Gate source is Timer0 overflow
TMR1GIF = 0;
TMR1GIE = 1;

//Interrupt enable
GIE = 1; //enable Global interrupts

//Initialize Button detection variables
for (index=0; index<NUM_BTTNS; index++)
{
raw_data[index] = 0;
average[index] = 0;
}
}

//-----------------------------------------------------
//Interrupt Service Routine
//-----------------------------------------------------
void interrupt ISR(void)
{
CLRWDT();
if (T0IE && T0IF) //are TMR0 interrupts enabled and is the TMR0 interrupt flag set?
{
T0IF=0; //TMR0 interrupt flag must be cleared in software to allow subsequent interrupts

}

if (TMR1GIF && TMR1GIE) //Timer1 Gate interrupt
{
// Perform touch reading

TMR1GIF = 0; // clear intpt flag
TMR1ON = 0; // Timer1 off

raw_data[index] = TMR1L + (unsigned int)(TMR1H << 8); //read the Timer1 value


threshold = average[index]>>2; //define threshold below average 1/2 = 50% below average

if (raw_data[index] < average[index])// - threshold))
{
//Button is pressed
switch (index)
{
case 0: Buttons.BTN0 = 1; break;
case 1: Buttons.BTN1 = 1; break;
case 2: Buttons.BTN2 = 1; break;
case 3: Buttons.BTN3 = 1; break;
case 4: Buttons.BTN4 = 1; break;
case 5: Buttons.BTN5 = 1; break;
case 6: Buttons.BTN6 = 1; break;
case 7: Buttons.BTN7 = 1; break;
case 8: Buttons.BTN8 = 1; break;
case 9: Buttons.BTN9 = 1; break;
case 10: Buttons.BTN10 = 1; break;
case 11: Buttons.BTN11 = 1; break;
case 12: Buttons.BTN12 = 1; break;
case 13: Buttons.BTN13 = 1; break;
case 14: Buttons.BTN14 = 1; break;
case 15: Buttons.BTN15 = 1; break;
default: break;
}
}
else
{
//Button is unpressed
switch (index)
{
case 0: Buttons.BTN0 = 0; break;
case 1: Buttons.BTN1 = 0; break;
case 2: Buttons.BTN2 = 0; break;
case 3: Buttons.BTN3 = 0; break;
case 4: Buttons.BTN4 = 0; break;
case 5: Buttons.BTN5 = 0; break;
case 6: Buttons.BTN6 = 0; break;
case 7: Buttons.BTN7 = 0; break;
case 8: Buttons.BTN8 = 0; break;
case 9: Buttons.BTN9 = 0; break;
case 10: Buttons.BTN10 = 0; break;
case 11: Buttons.BTN11 = 0; break;
case 12: Buttons.BTN12 = 0; break;
case 13: Buttons.BTN13 = 0; break;
case 14: Buttons.BTN14 = 0; break;
case 15: Buttons.BTN15 = 0; break;
default: break;
}


//Calculate average
//According to AN1103

average[index] = average[index] +\ (raw_data[index] - average[index])/16;

}

setNextChannel(); //Set for next channel
restartTimers(); //Restart the timers
}
}

//----------------------------------------
//Set for next channel
//----------------------------------------
void setNextChannel(void)
{
if (index < NUM_BTTNS-1)
index = index++;
else
index =0;
CPSCON1 = index;
}

//-----------------------------------------
//Restart timers
//-----------------------------------------
void restartTimers(void)
{
TMR1L = 0; //Reset Timer 1
TMR1H = 0;
TMR1ON = 1; //Restart Timer 1
TMR0 = 0; //Reset Timer 0
T0IF = 0; //Clear Timer0 interrupt
}

I think you need init code in while(1) loop.....I had not tried this code....just gaussing bcz once control comes to while(1) only the control change will happen at the time of interrupt ...but not the time when you pressed button...in case you will miss your touch signal....I think your ISR expect the raw_data[index] data input for checking the condition
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top