TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: aripod en 22 de Septiembre de 2012, 15:26:34

Título: mTouch en PIC24FJ256GB110
Publicado 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

Citar
#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!!