#include <pic.h>
#include "serial.h"
#include "globals.h"
#undef ADCDEBUG
void adc_init() {
ADCON0 = 0b01000000; // Fosc/8, channel 0, A/D off
ADCON1 = 0x80; // right justified, all analog, vref+ = vdd, vref- = vss
ADIE = 0; // no A/D interrupt since A/D is usually fast enough anyway.
}
unsigned int get_ad_immediate(unsigned char channel) {
unsigned int adresult;
unsigned int timewaster;
ADIE = 0; // no A/D interrupts for now.
ADIF = 0;
ADRESH = 0x00;
ADRESL = 0x00;
ADCON0 = ADCON0 & 0b11000000; // clear channel selection
switch(channel) {
case 0: RA0 = 1;
break;
case 1: ADCON0 = ADCON0 | 0b00001000;
RA1 = 1;
break;
case 2: ADCON0 = ADCON0 | 0b00010000;
RA2 = 1;
break;
case 3: ADCON0 = ADCON0 | 0b00011000;
RA3 = 1;
break;
case 4: ADCON0 = ADCON0 | 0b00100000;
RA5 = 1;
break;
case 5: ADCON0 = ADCON0 | 0b00101000;
RE0 = 1;
break;
case 6: ADCON0 = ADCON0 | 0b00110000;
RE1 = 1;
break;
case 7: ADCON0 = ADCON0 | 0b00111000;
RE2 = 1;
}
ADON = 1;
for (timewaster = 0; timewaster < 50; timewaster++); // waste 50 us for charging cap
ADGO = 1;
for(;;) {
#ifdef ADCDEBUG
putch('a');
#endif
if (ADIF) {
adresult = ADRESH;
adresult = adresult << 8;
adresult += ADRESL;
ADIF = 0;
break;
}
}
ADON = 0;
#ifdef ADCDEBUG
putdec(adresult, 'h');
#endif
return adresult;
}
#ifdef ADCDEBUG
main() {
serial_init();
setup_interrupts();
ad_init();
putdec(get_ad_immediate(0), 'h');
putdec(get_ad_immediate(1), 'h');
putdec(get_ad_immediate(2), 'h');
}
#endif