Det är 2 filer:
adcTouch.c
Kod: Markera allt
#include <xc.h>
#include "adcTouch.h"
#define MIN(x,y) (((x)>(y))?(y):(x))
#define MAX(x,y) (((x)<(y))?(y):(x))
#define X(adcMux, lowCode, outCode, inCode) 0,
static volatile char adcTouchButtonReadings[] = {adcTouchMacro};
#undef X
static volatile char adcTouchButtonState[(sizeof (adcTouchButtonReadings) / sizeof (adcTouchButtonReadings[0]))] = {0};
static void setChannel(unsigned char nr);
static inline void vddSampleCap();
static void groundChannel(unsigned char nr);
static inline unsigned short adcGetResult();
static void inputChannel(unsigned char nr);
void adcTouchInit() {
//Set up touch pads as analog inputs
ANSELB |= 0b00110011;
//Set up DAC as VDD
DACCON0 = 0b01000000;
DACCON1 = 0b00011111;
//Set up ADC
ADCON0 = 0b00000001;
ADCON1 = 0b10110000;
}
void adcTouchRun() {
static unsigned char state = 1;
static unsigned char channelIndex = 0;
if (ADCON0bits.GO)
return;
switch (state) {
case 1:
vddSampleCap();
groundChannel(channelIndex);
inputChannel(channelIndex);
setChannel(channelIndex);
ADCON0bits.GO = 1;
break;
case 2:
if (adcTouchButtonState[channelIndex]) {
if (adcGetResult() > adcTouchThreshold)
adcTouchButtonReadings[channelIndex]++;
else
adcTouchButtonReadings[channelIndex] = 0;
} else {
if (adcGetResult() < adcTouchThreshold)
adcTouchButtonReadings[channelIndex]++;
else
adcTouchButtonReadings[channelIndex] = 0;
}
if (adcTouchButtonReadings[channelIndex] > adcDebounce)
adcTouchButtonState[channelIndex] ^= 1;
if (++channelIndex == (sizeof (adcTouchButtonReadings) / sizeof (adcTouchButtonReadings[0])))
channelIndex = 0;
state = 0;
break;
}
state++;
}
unsigned char adcTouchGetButton(unsigned char channel) {
return adcTouchButtonState[channel];
}
static void setChannel(unsigned char nr) {
unsigned char i = 0;
#define X(adcMuxCode, lowCode, outCode, inCode) if(nr==i++){ adcMuxCode; }
adcTouchMacro
#undef X
}
static void groundChannel(unsigned char nr) {
unsigned char i = 0;
#define X(adcMuxCode, lowCode, outCode, inCode) if(nr==i++){ lowCode; outCode; }
adcTouchMacro
#undef X
}
static void inputChannel(unsigned char nr) {
unsigned char i = 0;
#define X(adcMuxCode, lowCode, outCode, inCode) if(nr==i++){ inCode; }
adcTouchMacro
#undef X
}
static inline void vddSampleCap() {
ADCON0bits.CHS = 0b11110;//Sample DAC
}
static inline unsigned short adcGetResult() {
return (ADRESH << 8) | ADRESL;
}
Kod: Markera allt
#ifndef ADCTOUCH_H
#define ADCTOUCH_H
void adcTouchInit();
void adcTouchRun();
unsigned char adcTouchGetButton(unsigned char channel);
//Set ADC-Mux Channel Code, Drive Pad Low Code, Pad Output Code, Pad Input Code
#define adcTouchMacro \
X(ADCON0bits.CHS=13, LATB5=0, TRISB5=0, TRISB5=1)\
X(ADCON0bits.CHS=11, LATB4=0, TRISB4=0, TRISB4=1)\
X(ADCON0bits.CHS=10, LATB1=0, TRISB1=0, TRISB1=1)\
X(ADCON0bits.CHS=12, LATB0=0, TRISB0=0, TRISB0=1)\
#define adcTouchThreshold 1020
#define adcDebounce 5
#endif
void adcTouchInit();
Kör en gång i början för att initera det hela.
void adcTouchRun();
Kör på fix frekvens, exakt frekvens spelar ingen roll, mellan 10µs och 10ms ungefär, jag kör på 1ms.
unsigned char adcTouchGetButton(unsigned char channel);
Returnerar ett om knapp #channel är nedtryckt och noll annars
Sedan har vi inställningarna, man lägger in knappar i adcTouch.h, i exemplet är 4st inlaggda.
adcTouchThreshold Anger känsligheten, 1023 är max känslighet och kommer inte funka, en yta på ca 10mmx10mm med ett finger på och lödmask imellan koppar och finger ger ca 950 i värde, inget finger ger 1022 eller 1023, jag har känsligheten på 1020, det funkar bra för mig.
adcDebounce Anger hur många på varandra följande mätningar som måste "vara överens" för att en knapp ska bli släppt eller tryckt.
Exempel på användning:
Kod: Markera allt
#include "adcTouch.h"
static void interrupt isr(void) {
if (TMR2IE && TMR2IF) {
TMR2IF = 0;
adcTouchRun();
}
}
void main() {
TRISB = 0;
LATB = 0b1000;
OSCCON = 0b01110000;
OPTION_REG = 0;
adcTouchInit();
//TMR2
T2CON = 0b00000111;
TMR2 = 0;
PR2 = 125;
//interrupt
GIE = 1;
PEIE = 1;
TMR2IE = 1;
while (1) {
if (adcTouchGetButton(0))
LED3 = 0; //Enable LED
else
LED3 = 1;//Disable LED
}
}
http://ww1.microchip.com/downloads/en/A ... 01298A.pdf