I was playing around with the ADC on a PIC12F683 - although the compiler I use has a built-in adc_read library function I wanted to have a bit more control over the actual settings (e.g. which sample clock to use). After writing the code I could not resist and ported it over to the Picaxe 08M (which incidentally is based on the 12F683...). With some small changes the same code should also run on other Picaxes up to the 28X1 and 40X1 (the X2 series has a different SFR setup and so would need a bit more work).
Anyway, here is the sample program. It basically replaces the readadc10 function. One application could be to use pin1 as the reference input (instead of the supply voltage as the built-in Picaxe readadc function does) by setting VCFG to 1 - could come handy when you input voltage range is smaller than 0V to VCC because it can give you better resolution over a smaller range.
To replace readadc instead of readadc10, change the format to left justified (ADFM=0) and only read back a single byte (adc_res_hi).
Wolfgang
Anyway, here is the sample program. It basically replaces the readadc10 function. One application could be to use pin1 as the reference input (instead of the supply voltage as the built-in Picaxe readadc function does) by setting VCFG to 1 - could come handy when you input voltage range is smaller than 0V to VCC because it can give you better resolution over a smaller range.
To replace readadc instead of readadc10, change the format to left justified (ADFM=0) and only read back a single byte (adc_res_hi).
Wolfgang
Code:
symbol ANSEL = 0x9f
symbol ADCON0 = 0x1f
symbol ADON = bit0
symbol GO_DONE = bit1
symbol CHS0 = bit2
symbol CHS1 = bit3
symbol VCFG = bit6
symbol ADFM = bit7
symbol ADRESH = 0x1e
symbol ADRESL = 0x9e
symbol SFR_reg = b0
symbol counter = b1
symbol adc_res = w1
symbol adc_res_lo = b2
symbol adc_res_hi = b3
setfreq m4
dirs = %00000000 ' all inputs (especially pin1)
peek ANSEL, SFR_reg
SFR_reg = %01110010; // Use RC oscillator as sample clock; configure pin1 as analog (ADC) pin
poke ANSEL, SFR_reg
peek ADCON0, SFR_reg
VCFG = 0; // use Vdd as voltage reference
ADFM = 1; // result is right Justified
ADON = 1; // enable A/D converter
poke ADCON0, SFR_reg
adc_loop:
'readadc10 1, adc_res ' built-in ADC routine
gosub adc_read
sertxd (#counter, ": ", #adc_res, cr, lf)
inc counter
pause 500
goto adc_loop
' acquires ADC
' result is in adc_res
adc_read:
peek ADCON0, SFR_reg
' select channel to measure (0 to 3)
'CHS1 = 0 : CHS0 = 0 ' channel 0
CHS1 = 0 : CHS0 = 1 ' channel 1
'CHS1 = 1 : CHS0 = 0 ' channel 2
'CHS1 = 1 : CHS0 = 1 ' channel 3
poke ADCON0, SFR_reg
GO_DONE = 1; // to start conversion
poke ADCON0, SFR_reg ' conversion starts now
' wait for conversion to finish
do
peek ADCON0, SFR_reg
loop while GO_DONE > 0
' read result into adc_res
peek ADRESL, adc_res_lo
peek ADRESH, adc_res_hi
return
Last edited: