TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: aripod en 22 de Septiembre de 2012, 15:26:34
-
Hola a todos. Estoy tratando de usar el modulo CTMU del pic para implementar un teclado de 4x4, guiandome con la hoja de datoshoja de datos (http://ww1.microchip.com/downloads/en/devicedoc/39897b.pdf) del pic, la nota de aplicacion AN1250 (http://ww1.microchip.com/downloads/en/AppNotes/01250a.pdf) y PIC24F Family Reference Manual, Sect. 11 Charge Time Measurement Unit (CTMU) (http://ww1.microchip.com/downloads/en/DeviceDoc/39724b.pdf).
La idea es leer el teclado antes del while para tener una referencia, donde no se apretaria ninguna tecla....y una vez en el ciclo infiinito, leer el teclado y compararlo con la referencia....Cada vez que se lee ya se para referencia o para leer si hay alguna tecla apretada.....se lee una tecla y se espera 1mS para leer la otra, todo por medio de la interrupcion del Timer1.
La lectura logro hacerla segun pude debuggear paso a paso, pero...mi idea era que en ajuste todos los valores de las teclasiban a ser iguales y en la lectura del teclado...si no esta apretada ninguna tecla tambien iban a ser iguales....luego de un par de "vueltas" del ciclo infinito.....el adc devuelve valores "aleatorios" se podria decir.......y tambien...si bien no devuelve cero siempre (a veces si), son valores chicos (menos a 30), siendo que esta configurado el adc para devolver enteros, y al ser de 16 bits.....menor a 30 pareceria demasiado bajo.....
Dejo el codigo para mayor claridad
#include <p24FJ256GB110.h>
#include <timer.h>
_CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & ICS_PGx1 & FWDTEN_OFF & WINDIS_OFF & FWPSA_PR128 & WDTPS_PS1);
_CONFIG2(IESO_OFF & PLLDIV_DIV2 & FNOSC_PRI & FCKSM_CSDCMD & POSCMOD_HS );
#define FCY 10000000UL
#define TIMER1_ON T1CONbits.TON = 1;
#define TIMER1_OFF T1CONbits.TON = 0;
#define COUNT 625 //(2/Fosc)*COUNT = 125uS ->COUNT = 625 (Para 10Mhz)
#define DELAY for(cuenta=0;cuenta<COUNT;cuenta++)
#define ModoEspera 0
#define ModoAjuste 1
#define ModoLectura 2
int LeerCTMU();
void Ajuste(void);
char LeerTeclado(void), modo=ModoEspera;
unsigned int index = 0x0001;
int referencia[16] = {0}, teclado[16] = {0}, cuenta;
char canal=0;
void main(void)
{
int tecla=0;
AD1PCFG = 0xFFFF; //Todos los PCFGx como DIGITALES.
TRISA=0x0000;
TRISB=0x0000;
TRISC=0x0000;
TRISD=0x0000;
TRISE=0x0000;
LATA=0x0000;
LATB=0x0000;
LATC=0x0000;
LATD=0x0000;
LATE=0x0000;
LATCbits.LATC14=1;
//------------Configuracion Timer 1------------//
T1CON = 0x00; //Stops the Timer1 and reset control reg.
TMR1 = 0x00; //Clear contents of the timer register.
PR1 = 0x0271; //Para 1mS //periodo = 2*Preescaler.PR1 //Para 1ms, PR1 = 0x271
IPC0bits.T1IP = 1; // ---------------- //con preescaler 8
IFS0bits.T1IF = 0; // Fosc
IEC0bits.T1IE = 1;
T1CONbits.TCKPS0 = 1; //Preescaler = 8
T1CONbits.TCKPS1 = 0;
TIMER1_OFF;
//------------Configuracion Timer 1------------//
//------------Configuracion CTMU y ADC------------//
//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 = 0x100; //55uA
CTMUICONbits.ITRIM = 0; //Nominal - No Adjustment
//setup A/D converter
AD1PCFGL = 0x0000; //Todos los pines configurados como entradas analogicas.
AD1CON1 = 0x0002;
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 = 0x0100; // 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
//------------Configuracion CTMU y ADC------------//
//------------Conexion Placa-Teclado------------//
/*
Tecla- Pin PIC - Pin Placa
13: AN12 - 41
9: AN8 - 32
5: AN4 - 21
1: AN0 - 25
14: AN13 - 42
10: AN9 - 33
6: AN5 - 20
2: AN1 - 24
15: AN14 - 43
11: AN10 - 34
7: AN6 - 26
3: AN2 - 23
16: AN15 - 44
12: AN11 - 35
8: AN7 - 27
4: AN3 - 22
*/
//------------Configuracion CTMU y ADC------------//
Ajuste();
while(1)
{
tecla=LeerTeclado();
switch(tecla)
{
case 0:
LATE=0x0;
break;
case 1:
LATE=0x1;
break;
case 2:
LATE=0x2;
break;
case 3:
LATE=0x3;
break;
case 4:
LATE=0x4;
break;
case 5:
LATE=0x5;
break;
case 6:
LATE=0x6;
break;
case 7:
LATE=0x7;
break;
case 8:
LATE=0x8;
break;
case 9:
LATE=0x9;
break;
case 10:
LATE=0xA;
break;
case 11:
LATE=0xB;
break;
case 12:
LATE=0xC;
break;
case 13:
LATE=0xD;
break;
case 14:
LATE=0xE;
break;
case 15:
LATE=0xF;
break;
default:
LATCbits.LATC14=1;
break;
}
}
}
void __attribute__((__interrupt__, __shadow__)) _T1Interrupt(void)
{
switch(modo)
{
case ModoAjuste:
referencia[canal] = LeerCTMU();
break;
case ModoLectura:
teclado[canal] = LeerCTMU();
break;
default:
break;
}
index <<= 1;
canal++;
IFS0bits.T1IF = 0;
}
int LeerCTMU(void)
{
//Read CTMU (Get the raw sensor reading)
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
AD1CHS0 = canal;
/////////////////////////// Seleccion CANAL 0 (AN0)
//AD1CHS0bits.CH0SA3 = 0;
//AD1CHS0bits.CH0SA2 = 0;
//AD1CHS0bits.CH0SA1 = 0;
//AD1CHS0bits.CH0SA0 = 0;
//////////////////////////
AD1PCFGL = ~index;
////////////////////////
//AD1PCFGL = 0xFFFE; //Se elige el CANAL analogico
////////////////////////
Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop();
TRISB=index;
////////////////////////
//TRISB=0x0001; //Se selecciona el pin del canal elegido como ENTRADA.
////////////////////////
CTMUCONbits.IDISSEN = 1; //drain charge on the circuit
DELAY; //wait for 125us
CTMUCONbits.IDISSEN = 0; //end drain of circuit
DELAY; //wait for 125us
CTMUCONbits.EDG2STAT = 0;
CTMUCONbits.EDG1STAT = 1; //Begin charging the circuit
//using CTMU current source
DELAY; //wait for 125us
CTMUCONbits.EDG1STAT = 0; //Stop charging circuit
AD1CON1bits.SAMP = 1; //Manual sampling start
DELAY; //wait for 125us
IFS0bits.AD1IF = 0; //make sure A/D Int not set
DELAY; //wait for 125us
AD1CON1bits.SAMP = 0; //and begin A/D conv.
while(!IFS0bits.AD1IF); //Wait for A/D convert complete
AD1CON1bits.SAMP = 0;
IFS0bits.AD1IF=0;
AD1CON1bits.DONE = 0;
return ADC1BUF0; //Returns the value from the A/D conversion
}
void Ajuste(void)
{
modo = ModoAjuste;
TIMER1_ON;
while(canal<16)
{
}
TIMER1_OFF;
index = 0x0001;
canal=0;
modo = ModoEspera;
}
char LeerTeclado(void)
{
char tecla=0, i;
modo = ModoLectura;
TIMER1_ON;
while(canal<16)
{
}
TIMER1_OFF;
index = 0x0001;
canal=0;
modo = ModoEspera;
for(i=0; i<16; i++)
{
if(teclado == referencia)
return i;
}
return 0xFF; //No hay tecla apretada.
}
Muchas gracias!!