15bits ADC optimization
Hi,
I was wondering if the following ADC code could be further optimized, especially
the first part (the ADC pins are selected dynamically).
device· SX48
DEVICE· OSCHS1 ;SX48/52
IRC_CAL IRC_SLOW
FREQ·· ·20_000_000
······· org·$0E
_IsrTemp····· ds·1 ;temporary storage
_IsrBank····· ds·1 ;to select adc rambank
······· org·$10
vpAdc_portIn· ds·1 ;adc input port (RA=5)
vpAdc_pinIn·· ds·1 ;OR pinmask (only one bit set to 1)
vpAdc_portOut·ds·1 ;adc output port (RA=5)
vpAdc_pinOut· ds·1 ;OR pinmask (only one bit set to 1)
vpAdc_bits··· ds·2 ;counter resetvalue, $1000 for 12bits, $0100 for 8bits (eg. 1<<resolution)
vpAdc_count·· ds·2 ;counter
vpAdc_accum·· ds·2 ;accumulator
vpAdc_value·· ds·2 ;resulting adc value, max resolution 15 bits
······· org·$0
vpAdc15_isr
;
dynamic adc in pin read and adc out pin update
······· MOV·· W,_IsrBank·;select adc rambank
······· MOV·· FSR,W
······· MOV·· W,#15··;select adc in port
······· AND·· W,vpAdc_portIn
······· MOV·· FSR,W
······· MOV·· W,/INDF··;get inverted port value
······· MOV·· _IsrTemp,W
······· MOV·· W,_IsrBank·;select adc rambank
······· MOV·· FSR,W
······· MOV·· W,vpAdc_pinIn·;extract inverted adc in bit
······· AND·· _IsrTemp,W
······· SETB· C···;Carry is inverted adc in bit
······· SNB·· Z
······· CLRB· C
······· MOV·· W,/vpAdc_pinOut·;AND mask
······· MOV·· _IsrTemp,W
······· MOV·· W,#15··;select adc out port
······· AND·· W,vpAdc_portOut
······· MOV·· FSR,W
······· MOV·· W,INDF··;get current adc out
······· AND·· W,_IsrTemp·;clear adc out bit
······· NOT·· _IsrTemp··;OR mask
······· SNB·· C
······· OR··· W,_IsrTemp·;set adc out bit to inverted adc in bit
······· MOV·· INDF,W
;
adc value calculation
······· MOV·· W,_IsrBank·;select adc rambank
······· MOV·· FSR,W
······· SNB·· C···;adc in triggered?
······· JMP·· m026··;no
······· INC·· vpAdc_accum·;yes, inc accumulator
······· SNB·· Z
······· INC·· vpAdc_accum+1
m026
······· DEC·· vpAdc_count·;dec count
······· MOV·· W,++vpAdc_count
······· SNB·· Z
······· DEC·· vpAdc_count+1
······· MOV·· W,vpAdc_count·;count == 0?
······· OR··· W,vpAdc_count+1
······· SB··· Z
······· JMP·· m028··;no
······· MOV·· W,vpAdc_accum·;yes, done
······· MOV·· vpAdc_value,W·;value = accumulator
······· MOV·· W,vpAdc_accum+1
······· MOV·· vpAdc_value+1,W
······· CLR·· vpAdc_accum·;clear accumulator
······· CLR·· vpAdc_accum+1
······· MOV·· W,vpAdc_bits·;reset counter (count = bits)
······· MOV·· vpAdc_count,W
······· MOV·· W,vpAdc_bits+1
······· MOV·· vpAdc_count+1,W
m028
······· RET
end
regards peter
I was wondering if the following ADC code could be further optimized, especially
the first part (the ADC pins are selected dynamically).
device· SX48
DEVICE· OSCHS1 ;SX48/52
IRC_CAL IRC_SLOW
FREQ·· ·20_000_000
······· org·$0E
_IsrTemp····· ds·1 ;temporary storage
_IsrBank····· ds·1 ;to select adc rambank
······· org·$10
vpAdc_portIn· ds·1 ;adc input port (RA=5)
vpAdc_pinIn·· ds·1 ;OR pinmask (only one bit set to 1)
vpAdc_portOut·ds·1 ;adc output port (RA=5)
vpAdc_pinOut· ds·1 ;OR pinmask (only one bit set to 1)
vpAdc_bits··· ds·2 ;counter resetvalue, $1000 for 12bits, $0100 for 8bits (eg. 1<<resolution)
vpAdc_count·· ds·2 ;counter
vpAdc_accum·· ds·2 ;accumulator
vpAdc_value·· ds·2 ;resulting adc value, max resolution 15 bits
······· org·$0
vpAdc15_isr
;
dynamic adc in pin read and adc out pin update
······· MOV·· W,_IsrBank·;select adc rambank
······· MOV·· FSR,W
······· MOV·· W,#15··;select adc in port
······· AND·· W,vpAdc_portIn
······· MOV·· FSR,W
······· MOV·· W,/INDF··;get inverted port value
······· MOV·· _IsrTemp,W
······· MOV·· W,_IsrBank·;select adc rambank
······· MOV·· FSR,W
······· MOV·· W,vpAdc_pinIn·;extract inverted adc in bit
······· AND·· _IsrTemp,W
······· SETB· C···;Carry is inverted adc in bit
······· SNB·· Z
······· CLRB· C
······· MOV·· W,/vpAdc_pinOut·;AND mask
······· MOV·· _IsrTemp,W
······· MOV·· W,#15··;select adc out port
······· AND·· W,vpAdc_portOut
······· MOV·· FSR,W
······· MOV·· W,INDF··;get current adc out
······· AND·· W,_IsrTemp·;clear adc out bit
······· NOT·· _IsrTemp··;OR mask
······· SNB·· C
······· OR··· W,_IsrTemp·;set adc out bit to inverted adc in bit
······· MOV·· INDF,W
;
adc value calculation
······· MOV·· W,_IsrBank·;select adc rambank
······· MOV·· FSR,W
······· SNB·· C···;adc in triggered?
······· JMP·· m026··;no
······· INC·· vpAdc_accum·;yes, inc accumulator
······· SNB·· Z
······· INC·· vpAdc_accum+1
m026
······· DEC·· vpAdc_count·;dec count
······· MOV·· W,++vpAdc_count
······· SNB·· Z
······· DEC·· vpAdc_count+1
······· MOV·· W,vpAdc_count·;count == 0?
······· OR··· W,vpAdc_count+1
······· SB··· Z
······· JMP·· m028··;no
······· MOV·· W,vpAdc_accum·;yes, done
······· MOV·· vpAdc_value,W·;value = accumulator
······· MOV·· W,vpAdc_accum+1
······· MOV·· vpAdc_value+1,W
······· CLR·· vpAdc_accum·;clear accumulator
······· CLR·· vpAdc_accum+1
······· MOV·· W,vpAdc_bits·;reset counter (count = bits)
······· MOV·· vpAdc_count,W
······· MOV·· W,vpAdc_bits+1
······· MOV·· vpAdc_count+1,W
m028
······· RET
end
regards peter