Estoy tratando de hacer un teclado de 4x4 usando el modulo CTMU (mtouch) que viene con el PIC24FJ256GB110. Estoy leyendo correctamente 14 de las 16 teclas (AN2 a AN15). Usando la misma idea para todas las teclas, cuando veo los valores correspondientes a AN0 y AN1, siempre devuelve cero.
La configuracion del CTMU y del ADC son:
//setup CTMU
//CTMUCON
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; //Edge 2 programmed for a negative edge response
CTMUCONbits.EDG2SEL1 = 1; //Edge2 Src = OC1 (don’t care)
CTMUCONbits.EDG2SEL0 = 1;
CTMUCONbits.EDG1POL = 1; //Edge 1 programmed for a positive edge response
CTMUCONbits.EDG1SEL1 = 1; //Edge1 Src = Timer1 (don’t care)
CTMUCONbits.EDG1SEL0 = 1;
//CTMUICON
CTMUICON = 0x110; //55uA
CTMUICONbits.ITRIM = 0; //Nominal - No Adjustment
//setup A/D converter
AD1PCFGL = 0x0000; //Todos los pines configurados como entradas analogicas.
AD1CON1 = 0x8000; //CTMU event &
AD1CON2 = 0x0000; // Configure A/D voltage reference
// and buffer fill modes.
// Vr+ and Vr- from AVdd and AVss (VCFG<2:0>=000),
// Inputs are not scanned,
// Interrupt after every sample
AD1CON3 = 0x0000; // Configure sample time = 1Tad,
// A/D conversion clock as Tcy
AD1CSSL = 0; // No inputs are scanned.
IFS0bits.AD1IF = 0; // Clear A/D conversion interrupt.
AD1CHS0 = 0x0000;
//AD1CHS0bits.CH0SB4 = 0;
AD1CON1bits.ADON = 1; //Turn On A/D
CTMUCONbits.CTMUEN = 1; //Enable CTMU
Estoy usando las dos siguientes tablas:
const int index[] = { //UNO en el canal deseado, el resto CERO.
0x0004, /* Tecla 1 - AN2 */
0x0080, /* Tecla 2 - AN7 */
0x0800, /* Tecla 3 - AN11 */
0x8000, /* Tecla 4 - AN15 */
0x0008, /* Tecla 5 - AN3 */
0x0040, /* Tecla 6 - AN6 */
0x0400, /* Tecla 7 - AN10 */
0x4000, /* Tecla 8 - AN14 */
0x0010, /* Tecla 9 - AN4 */
0x0000, /* Tecla 10 - AN0 */ //NO ANDA EL AN0
0x0200, /* Tecla 11 - AN9 */
0x2000, /* Tecla 12 - AN13 */
0x0020, /* Tecla 13 - AN5 */
0x0001, /* Tecla 14 - AN1 */ //NO ANDA EL AN1
0x0100, /* Tecla 15 - AN8 */
0x1000, /* Tecla 16 - AN12 */
};
const int canal[] = { //Numero del canal a usar.
2, /* Tecla 1 - AN2 */
7, /* Tecla 2 - AN7 */
11, /* Tecla 3 - AN11 */
15, /* Tecla 4 - AN15 */
3, /* Tecla 5 - AN3 */
6, /* Tecla 6 - AN6 */
10, /* Tecla 7 - AN10 */
14, /* Tecla 8 - AN14 */
4, /* Tecla 9 - AN4 */
0, /* Tecla 10 - AN0 */
9, /* Tecla 11 - AN9 */
13, /* Tecla 12 - AN13 */
5, /* Tecla 13 - AN5 */
1, /* Tecla 14 - AN1 */
8, /* Tecla 15 - AN8 */
12, /* Tecla 16 - AN12 */
};
Cada 50mS hago esto:
for(i=0; i<16; i++)
teclado = LeerCTMU(i);
Donde LeerCTMU es:
AD1PCFGL = 0xFFFF; //set all A/D channels to digital I/O pins
TRISB = 0x0000;
LATB = 0x0000;
PORTB = 0x0000; //set all channels to logical 0 outputs
AD1CHS = canal;
AD1PCFGL = ~index;
Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop();
TRISB=index;
AD1CON1bits.SAMP = 1; //Manual sampling start
CTMUCONbits.IDISSEN = 1; //drain charge on the circuit
DELAY; //wait for 125us
CTMUCONbits.IDISSEN = 0; //end drain of circuit
CTMUCONbits.EDG2STAT = 0;
CTMUCONbits.EDG1STAT = 1; //Begin charging the circuit using CTMU current source
DELAY; //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; //Returns the value from the A/D conversion
Cada vez que i vale 9 y 13, ADC1BUF0 devuelve cero, y cuando i vale otro valor (de 0 a 15 salvo 9 y 13) devuelve un valor correcto y puedo detectar si fue o no presionada la tecla correspondiente.
Hay algo que no estoy configurando, para cuando i=9 e i=13 que son AN0 y AN1??
Gracias!!!