mTouch

Embed Size (px)

Citation preview

mTouch un teclado capacitivo con slo un PIC

Entre los ltimos PICs que Microchip ha sacado al mercado destaca la incorporacin del mdulo de sensado capacitivo mTouch que incluye todo el hardware necesario para realizar un teclado capacitivo con slo pintar las pistas correspondientes a los botones.

EL primer paso para comenzar es, evidentemente, ir a la pgina de Microchip y revisar la ltima informacin publicada al respecto.aquEn mi caso surgi la posibilidad de cambiar un teclado tradicional PS2 por este nuevo sistema, por lo que monte mi prototipo con un 16LF272 y comenc a probar con el cdigo que Michochip facilita (s, claro, antes hay que leer los datasheets, AN,..) el caso es que contena ms de un fallo que lo hace inoperativo por eso esta primera entrada en el blog, para dejar un cdigo que si funciona a quien le pueda venir bien, seguro que a los que empezis con el tema os ahorra alguna que otra horas de trabajoEste primer diseo ha sido ejecutado siguiendo las recomendaciones del las AN de Microchip con un excelente resultado, asi qued la tarjeta prototipo:

Este es el aspecto del PCB del prototipo, con los componentes en una cara y los pads en la otra, por ltimo un conector soldado directamente al micro para depurar con REAL ICE.

El cdigo est para compilarlo con CCS, que viene gratis en el MPLAB.//****************************************************************************//// Nombre: tecladocap.c// Autor: Flix Sasin// Fecha: enero 2009// Proposito: mostrar el uso del modulo de sensado capacitivo// este programa escanea el estado de las 16 entradas del pic 16LF727// con un intervalo fijo. Se hace una media de la frecuencia del teclado en reposo// y cuando se toca un PAD la frecuencia cambia por la capacitancia del dedo.// Cuando se pulsa una tecla se enciende un led y se enva la tecla pulsada por// el puerto serie. El sistema se queda a la espera de que se suelte la tecla.//// Es muy sencillo modificar este programa para poder detectar varias teclas// pulsadas de forma simultanea.////****************************************************************************//#include #include#FUSES HS //Cristal de 8 Mhz#FUSES NOWDT //Sin Watch Dog Timer#FUSES NOPROTECT //Cdigo abierto#FUSES PLLEN //Habilita PLL#FUSES NODEBUG //No Debug#FUSES NOMCLR //NO Master Clear pin#FUSES NOBROWNOUT //No brownout reset#FUSES NOPUT //No Power Up Timer//configurar los delays#use delay(clock=8000000)//configuracin del puerto serie#use rs232(baud=19200, xmit=PIN_C6,rcv=PIN_C7)//****************************************************************************////* DEFINICIONES//****************************************************************************//int16 timer1_val[NUMSENSORES];int16 timer1_raw[NUMSENSORES];int16 media_boton[NUMSENSORES];int16 trip_val[NUMSENSORES];char pasadas_estabilizacion;char pasadas_media;char num_sensor;char tecla;//****************************************************************************////* PROTOTIPOS//****************************************************************************//void init(void);void timers_isr(void);void reset_timer1(void);void selecciona_siguiente_sensor(void);//****************************************************************************////* FUNCION DE INICIALIZACION//****************************************************************************//void init(){char x;setup_adc_ports( ALL_ANALOG );OSCCON = 030; //16 MHz with PLLEN// INICIALIZAR LOS TIMERSOPTION = 0xC3;T0IF = 0;T0IE = 1;T1CON = 0xC5;T1GCON = 0xE1;//INICIALIZAR EL MODULO CAPACITIVOCPSCON0 = 0b10001100;CPSCON1 = 0;//INICIALIZAR LAS VARIABLESpasadas_estabilizacion = PASES_ESTABILIZACION;pasadas_media = PASES_MEDIA;for(x = 0; x < NUMSENSORES; x++){trip_val[x] = UMBRAL;media_boton[x] = 0;}// Gate SetupTMR1GIF = 0; // borra el gate interrup flagTMR1GIE = 1; // habilita la gate interrupPEIE = 1; // habilita las peripheral intptsGIE = 1; // habilita las global intpts// APAGA EL LEDoutput_low(LED);}//****************************************************************************//// ISR() RUTINA DE INTERRUPCION//****************************************************************************//#INT_DEFAULT // Interrupcionesvoid timers_isr(){if (T0IF==1) // Timer0{T0IF = 0; // limpia el interrup flag}if(TMR1GIF==1) // Timer1 gate{TMR1GIF = 0; // limpia el interrup flagTMR1ON = 0; // TIMER1 offtimer1_val[num_sensor] = make16(TMR1H,TMR1L);timer1_raw[num_sensor] = timer1_val[num_sensor] * 16;//estabilizar el valor de media_botonif(pasadas_estabilizacion > 000){pasadas_estabilizacion;media_boton[num_sensor] = timer1_raw[num_sensor];if((pasadas_estabilizacion == 0) && (num_sensor < (NUMSENSORES - 1))){pasadas_estabilizacion = PASES_ESTABILIZACION;selecciona_siguiente_sensor();}}else{//buscar botones pulsadosif(timer1_raw[num_sensor] < (media_boton[num_sensor] - trip_val[num_sensor])){tecla=num_sensor+1;}else if(timer1_raw[num_sensor] > (media_boton[num_sensor] - trip_val[num_sensor])+ VALOR_HISTERESIS){tecla=0;if(timer1_raw[num_sensor] > (media_boton[num_sensor])){media_boton[num_sensor] = media_boton[num_sensor] + (timer1_val[num_sensor] - (media_boton[num_sensor] / 16));}//calcular la mediapasadas_media;if(pasadas_media == 0){media_boton[num_sensor] = media_boton[num_sensor] + (timer1_val[num_sensor] - (media_boton[num_sensor] / 16));pasadas_media = PASES_MEDIA;selecciona_siguiente_sensor();}}}reset_timer1();}}//****************************************************************************////* RESET DEL TIMER1//****************************************************************************//void reset_timer1(){TMR1L = 0;TMR1H = 0;TMR1ON = 1;}//****************************************************************************////* SELECCIONAR SIGUIENTE CANAL CPS//****************************************************************************//void selecciona_siguiente_sensor(){num_sensor++;if(num_sensor >= NUMSENSORES){num_sensor = 0;}CPSCON1 = num_sensor; //Selecciona el siguiente pin CPS0..CPS15}//****************************************************************************////* BUCLE PRINCIPAL//****************************************************************************//void main(void){char tecla1;Init();num_sensor = 0; // comenzamos con el primer canalwhile(true){GIE = 0;tecla1=tecla;GIE = 1;if (tecla1>0) //si se localiza una tecla pulsada{output_high(LED); //enciende el ledprintf(T%c,tecla1); //lo envia por el puerto seriedelay_ms(100);}while(tecla1>0) //espera que se suelten todas las teclas{GIE = 0;tecla1=tecla;GIE = 1;delay_ms(50);}output_low(LED); //apagar el led}}//****************************************************************************//// nombre: tecladocap.h// Autor: Flix Sasin// Fecha: enero 2009// Proposito: mostrar el uso del modulo de sensado capacitivo//****************************************************************************////*********************definiciones del registro ************************#byte OSCCON = 090#byte OPTION = 081#byte T1CON = 010#byte T1GCON = 08f#byte CPSCON0 = 0108#byte INTCON = 00b#byte CPSCON1 = 0109#byte PIE1 = 08c#byte PIR1 = 00c#byte TMR1L = 00e#byte TMR1H = 00f// T1CON bits#bit TMR1ON = T1CON.0// INTCON bits#bit GIE = INTCON.7#bit PEIE = INTCON.6#bit T0IE = INTCON.5#bit T0IF = INTCON.2// PIE1 bits#bit TMR1GIE = PIE1.7// PIR1 bits#bit TMR1GIF = PIR1.7//****************************************************************************//// DEFINICIONES//****************************************************************************//#define NUMSENSORES 16#define PASES_MEDIA 3#define PASES_ESTABILIZACION 50#define VALOR_HISTERESIS 30#define UMBRAL 220//****************************************************************************////* DEFINICIONES DE I/O//****************************************************************************//#define LED PIN_C1Espero que sea til