Estoy utilizando la MCU PIC16f722 para implementar la detección capacitiva pero tengo problemas para implementarla. Me he referido al Microchip AN1103 para que me ayude con la parte del software. He escrito mi propio código teniendo en cuenta que el sensor capacitivo funciona al detectar una caída en la frecuencia del OSC capacitivo, pero mi código no funciona como se esperaba. ¡Los interruptores se activan sin presionar! o salidas solo voltea al azar. También he intentado implementar diferentes diseños de almohadillas táctiles con diferentes huecos entre ellos al pensar que el error se debió a una interferencia, pero no ayudó. Así que creo que hay un problema en mi código.
Aquí está mi código:
sbit AP0 at RA0_bit; //outputs
sbit AP1 at RA1_bit;
sbit AP2 at RA2_bit;
sbit AP3 at RA4_bit;
volatile bit SWP0,SWP1,SWP2,SWP3;//indicates switch was pressed
unsigned short Timer0_value=0;
unsigned short sensor_No=0;//This indicates the current cap sensor number which is being scanned
float Last_Frequency[4]={0,0,0,0};//this indicates last frequency count
unsigned long trip[4]={500,1090,1090,500};
float current_frequency=0;//this indicates current frequency count
bit first_Read;//this indicates that system has first started so Last_Frequency should hold value of no capacitive load. Nominal frequency.
///this also indicates that all sensor last frequency or nominal frequency is saved in array of Last_Frequency
unsigned short avg_count=0;//this indicates the current avg_count while averaging
void interrupt(){
if(PIR1.TMR1IF==1){
Timer0_value=TMR0;
TMR0=0;
//firstly all sensors nominal frequencies will be stored. This state is indicated by first_Read bit
if(first_Read==0){//Here Last_Frequency[sensor_No] will hold the nominal frequency(averaged)
AP0=~AP0;
AP1=~AP1;
AP2=~AP2;
AP3=~AP3;
if(avg_count<31){//take 30 samples
if(Last_Frequency[sensor_No]!=0){
Last_Frequency[sensor_No]=Last_Frequency[sensor_No]+Timer0_value/0.0131072; //0.0131072 is period of Timer1 will interrupt which is used as a fixed timebase.
}else Last_Frequency[sensor_No]=Timer0_value/0.0131072;
avg_count++;
}else {
Last_frequency[sensor_No]=Last_frequency[sensor_No]/30;
avg_count=0;
sensor_No++;
if(sensor_No>3){
sensor_No=0;//reset cap sensor count
first_Read=1;//all nominal frequencies are stored in Last_Frequency array
AP0=0;
AP1=0;
AP2=0;
AP3=0;
}
CPSCON1=sensor_No;
}
}else{
if(avg_count<31){
if(current_frequency!=0){
current_frequency=current_frequency+Timer0_value/0.0131072;//get current frequency take 30 samples
}else current_frequency=Timer0_value/0.0131072;
avg_count++;
}else{
avg_count=0;
current_frequency=current_frequency/30;//take average
//Below current frequency is compared with stored nominal frequency of selected sensor
if(current_frequency<(Last_Frequency[sensor_No]-trip[sensor_No])){//here 1000 is the calibrated value used to tune sensitivity of sensor according to material over sensor
//button pressed
switch(sensor_No){
case 0: SWP0=1;break;
case 1: SWP1=1;break;
case 2: SWP2=1;break;
case 3: SWP3=1;break;
}
}else if(current_frequency>(Last_Frequency[sensor_No]-trip[sensor_No]+194)){
//button not pressed
switch(sensor_No){
case 0: SWP0=0;break;
case 1: SWP1=0;break;
case 2: SWP2=0;break;
case 3: SWP3=0;break;
}
}
//change sensor no as current sensor was scanned
sensor_No++;
current_frequency=0;//reset
if(sensor_No>3)sensor_No=0;//reset
CPSCON1=sensor_No;
}
}
TMR1L=0;
TMR1H=0;
TMR0=0;
PIR1.TMR1IF=0;
}else {
TMR1L=0;
TMR1H=0;
TMR0=0;
PIR1.TMR1IF=0;
}
}
void main() {
TRISA=0x00;
ANSELA=0x00;
SWP0=0;//Switch is not pressed
SWP1=0;//Switch is not pressed
SWP2=0;//Switch is not pressed
SWP3=0;//Switch is not pressed
first_Read=0;//No first read has done.
//reset all outputs
AP0=0;
AP1=0;
AP2=0;
AP3=0;
//Enable Capacitive sensing module
CPSCON0.CPSON=1;
CPSCON0.CPSRNG1=0;
CPSCON0.CPSRNG0=1;
CPSCON0.T0XCS=1;
OPTION_REG.T0CS=1;
CPSCON1=0x00;//Enable CPS0 channel.at RB0
TRISB=0x00;
TRISB.B0=1; //set RB0 as input as it is capacitive input.
TRISB.B1=1;
TRISB.B2=1;
TRISB.B3=1;
ANSELB=0x00;
ANSELB.B0=1;
ANSELB.B1=1;
ANSELB.B2=1;
ANSELB.B3=1;
//Initialize Timer1 for interrupts to scan cap sensors
TMR1IE_bit=1;
PEIE_bit=1;
GIE_bit=1;
TMR1IF_bit=0;
// Timer1 Registers: Prescaler=1:1; TMR1 Preset=0; Freq=76.29395Hz; Period=0.0131072 s
T1CON.T1CKPS1 = 0; // bits 5-4 Prescaler Rate Select bits
T1CON.T1CKPS0 = 0; // bit 4
T1CON.T1OSCEN = 0; // bit 3 Timer1 Oscillator Enable Control: bit 1=on
T1CON.T1SYNC = 1; // bit 2 Timer1 External Clock Input Synchronization
Control bit:1=Do not synchronize external clock input
T1CON.TMR1CS0 = 0; // Timer 1 clock source is FOSC and not FOSC/4
T1CON.TMR1CS1 = 0; // Timer 1 clock source is FOSC and not FOSC/4
T1CON.TMR1ON = 1; // bit 0 enables timer
TMR1H = 0; // preset for timer1 MSB register
TMR1L = 0; // preset for timer1 LSB register
TMR0=0;
while(1){
///below for each SWPx bit that respective AP(toggle its state)
if(SWP0){
AP0=~AP0;
SWP0=0;//reset this flag
}
if(SWP1){
AP1=~AP1;
SWP1=0;//reset this flag
}
if(SWP2){
AP2=~AP2;
SWP2=0;//reset this flag
}
if(SWP3){
AP3=~AP3;
SWP3=0;//reset this flag
}
};
}
Entonces, ¿dónde estoy cometiendo un error?