Estoy tratando de implementar un sensor táctil básico utilizando el CTMU en mi PIC24F04KA200. Al leer la hoja de datos y las notas de aplicación proporcionadas por Microchip, esperaba que esto fuera una tarea fácil. En esta pregunta, solo explicaré lo que estoy haciendo, publicaré mi código C y espero que alguien pueda indicarme la dirección correcta.
He conectado mi sensor, que es una placa de cobre sobre el material de la placa PCB del tamaño de una tarjeta postal. El tipo de cosas que compra para hacer su propia placa de circuito. He conectado esto a la clavija AN4 (RA2). Tengo un LED y una resistencia limitadora de corriente conectada a RA4. Los únicos otros elementos del circuito que tengo son una tapa de desacoplamiento .1uF en los pines de alimentación y el PicKit3 que alimenta el circuito (también lo he intentado con una fuente de alimentación separada).
Todo lo que he intentado hacer es seguir el ejemplo de código dado por Microchip y esencialmente encender la fuente de corriente para permitir que mi almohadilla de cobre cargue y mida el voltaje con A / D (como se explica en la Nota de la aplicación) y cuando Toco la almohadilla y la capacitancia aumenta, lo que seguiría si el voltaje fuera más bajo y detectaría el toque.
Mi problema es que no saco nada del pin y no se está cargando; mi valor de ADC es siempre cero y en mi alcance solo muestra 0 voltios. Supongo que mi CTMU no se enciende, ya que la tapa del ADC debería al menos cargarse con ella. He buscado en los foros de Internet y Microchip y no he encontrado muchas personas que tengan problemas, así que creo que debo estar cometiendo un simple error.
#define CLK 8000000L //8MHZ
#define FCY (CLK/2)
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <libpic30.h>
//#include "p24Fxxxx.h"
#include "uart.h"
#include "p24F04KA200.h"
#pragma config MCLRE = ON, GCP = OFF, FNOSC = FRC, FWDTEN = OFF, ICS = PGx2, PWRTEN = ON, OSCIOFNC = ON
void setup()
{
//setup CTMU
CTMUCONbits.CTMUEN = 0; //make sure CTMU is disabled
CTMUCONbits.CTMUSIDL = 0; //CTMU continues to run in idle mode
CTMUCONbits.TGEN = 0; //disable edge delay generation mode of the CTMU
CTMUCONbits.EDGEN = 0; //edges are blocked
CTMUCONbits.EDGSEQEN = 0; //edge sequence not needed
CTMUCONbits.IDISSEN = 0; //Do not ground the current source
CTMUCONbits.CTTRIG = 0; //Trigger Output is disabled
CTMUCONbits.EDG2POL = 0;
CTMUCONbits.EDG2SEL = 0x3; //Edge2 Src = OC1 (don?t care)
CTMUCONbits.EDG1POL = 1;
CTMUCONbits.EDG1SEL = 0x3; //Edge1 Src = Timer1 (don?t care)
//CTMUICON
CTMUICONbits.ITRIM = 0x3F; //Maximum Positive Adjustment
CTMUICONbits.IRNG = 0x3; //55 uA
CTMUCONbits.CTMUEN = 1; //Enable CTMU
//setup A/D converter
AD1PCFG = 0x0000;
AD1CON1 = 0x0000;
AD1CON1bits.FORM = 0x0; //Unsigned fractional format
AD1CON2 = 0x0000;
AD1CON3 = 0x0000; //bits.ADRC=0;
AD1CON3bits.SAMC = 0xB; //12 TAD
AD1CON3bits.ADCS = 0x60; //Used formula for ADCS with 12 TAD
AD1CHS = 0x04; //select the analog channel 4
AD1CSSL= 0x0000;
AD1CON1bits.ADON = 1; //Turn On A/D
}
unsigned short runCTMU()
{
AD1CON1bits.SAMP = 1; //Manual sampling start
CTMUCONbits.IDISSEN = 1; //drain charge on the circuit
__delay_us(125); //wait 125us
CTMUCONbits.IDISSEN = 0; //end drain of circuit
CTMUCONbits.EDG1STAT = 1; //Begin charging the circuit using CTMU current source
__delay_us(125); //wait for 125us
CTMUCONbits.EDG1STAT = 0; //Stop charging circuit
IFS0bits.AD1IF = 0; //make sure A/D Int not set
AD1CON1bits.SAMP = 0; //and begin A/D conv.
while(!IFS0bits.AD1IF); //Wait for A/D convert complete
AD1CON1bits.DONE = 0;
return ADC1BUF0;
}
unsigned short getVbaseline()
{
unsigned short vRead = 0;
for(k = 0; k < 50; k++)
{
vRead = vRead + runCTMU();
}
return (vRead/50);
}
void main()
{
unsigned short vRead;
unsigned short vBaseline;
setup();
//Set up sensor pin
TRISA = 0x2;
AD1CHS = 0x4; //select AN04 as input
AD1PCFG = ~(0x4);
//get untouched value on start up
vBaseline = getVbaseline();
while(1)
{
vRead = runCTMU();
//Touch sensed
if (vRead < vBaseline)
{
LATAbits.LATA4 = 1; //output LED
//Send ADC value over UART
UART1PutChar(vRead >> 1);
UART1PutChar(vRead);
}
else //Touch not sensed
{
LATAbits.LATA4 = 0;
}
}
}
He usado esta Nota de aplicación para ejemplos de código.