Autor Tema: mTouch en PIC24FJ256GB110  (Leído 1285 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado aripod

  • PIC16
  • ***
  • Mensajes: 170
mTouch en PIC24FJ256GB110
« 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 del pic, la nota de aplicacion AN1250 y PIC24F Family Reference Manual, Sect. 11 Charge Time Measurement Unit (CTMU).
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!!
« Última modificación: 23 de Septiembre de 2012, 16:02:48 por aripod »