Estoy tratando de implementar un sensor táctil básico utilizando el CTMU en mi PIC24F04KA200. Leyendo la hoja de datos y las notas de aplicación proporcionadas por Microchip esperaba que esto fuera un esfuerzo fácil. En esta pregunta me limitaré a 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 en la parte superior de material de placa de circuito impreso del tamaño de una tarjeta postal. El tipo de cosa que usted compra para DIY su propia placa de circuito. He conectado esto al pin AN4(RA2). Tengo un LED y una resistencia limitadora de corriente conectados a RA4. Los únicos otros elementos del circuito que tengo son una tapa de desacoplamiento de .1uF en los pines de alimentación y el PicKit3 alimentando el circuito (también he probado con una fuente de alimentación independiente).
Lo único que he intentado hacer es seguir el ejemplo de código que da Microchip y esencialmente encender la fuente de corriente para que mi almohadilla de cobre se cargue y medir el voltaje con el A/D (como se explica en la App Note) y cuando toque la almohadilla y la capacitancia aumente se deduciría que el voltaje sería menor y detectaría el toque.
Mi problema es que no obtengo nada del pin y no se está cargando; el valor de mi ADC es siempre cero y en mi osciloscopio sólo muestra 0 voltios. Supongo que mi CTMU no se está encendiendo, ya que la tapa del ADC debería al menos cargarse con él. He buscado en internet y en los foros de Microchip y no he encontrado mucha gente con 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 utilizado este Nota de aplicación para ver ejemplos de código.