Re: ADC Issue


Nov 7, 2003

 


----------------------------

#3168 Nov 7, 2003

some deal has been said about ADCs, and its becoming an important

feature in pics now. Hoeever, is it all that difficult to make it

work? Here I list a program I wrote which simply converts an analogue

signal thru a pot to AN0, then outputs the result to portb which is a

bank if LEDs. for some reason, it doesnt work. I've tried going over

the logic disabling the interrupts so that the program doesn nothing

but loop and convert. But its not working...Is it a timing problem,

so something i forgot to configure guys?



; The A/D is configured as follows:

; Vref = 2.5V

; A/D Osc. = Fosc/8

; A/D Channel = AN0 (RA0)



LIST P=16f818

include "P16f818.inc".; File contains addresses for

register and bit names

CBLOCK.0x20

TEMP

ENDC



;************************************************************

; reset and interrupt vectors



org.0x00000.; Reset Vector Address

goto.Start



;.org.0x00008.; Interrupt Vector Address

;.goto.ISR.; goto Interrupt Service Routine.



;************************************************************

; program code starts here





org.0x00020

Start

bcf..STATUS,RP0

bcf..STATUS,RP1



bsf..STATUS,RP0



BSF..OPTION_REG,7..;DISABLE INTERNAL P/U

clrf.PORTB..; clear all bits of PORTB.

clrf.TRISB..; Set PORTB as outputs



BCF..STATUS,RP0

call.InitializeAD .; configure A/D module



call.SetupDelay.; delay for 15 instruction cycles



Main.bsf.ADCON0,GO.; Start first A/D conversion

call.SetupDelay.; Delay for 15 cycles



goto.Main..; do nothing loop



;************************************************************

; Service A/D interrupt

; Get value and display on LEDs



;ISR

; Save context (WREG and STATUS) if required.



;.btfss.PIR1,ADIF.; Did A/D cause interrupt?

;.goto.OtherInt.; No, check other sources



movf.ADRESH,W.; Get A/D value

movwf.PORTB..; Display on LEDs

;bcf.PIR1,ADIF.; Reset A/D int flag



call.SetupDelay.; Delay for 15 cycles



;.bsf.ADCON0,GO.; Start A/D conversion



;.goto.EndISR..; return from ISR



;OtherInt

; This would be replaced by code to check and service other

interrupt sources

;goto.$.; trap here, loops to self



;EndISR

; Restore context if saved.



;retfie..; Return, enables GIE



;************************************************************

; InitializeAD - initializes and sets up the A/D hardware.

; Select AN0 to AN3 as analog inputs, RC clock, and read AN0.



InitializeAD

BSF..STATUS,RP0

movlw.B'10000101'.; Make RA0,RA1,RA4 analog inputs

movwf.ADCON1



BSF..STATUS,RP1

movlw.B'01000001'.; Select Fosc/8, AN0 selected,

movwf.ADCON0..; A/D enabled



bcf..INTCON,PEIE.; Enable peripheral interrupts

bcf..INTCON,GIE.; Enable Global interrupts



BCF..STATUS,RP0



bcf..PIR1,ADIF.; Clear A/D interrupt flag

bcf..PIE1,ADIE.; Enable A/D interrupt







return



;************************************************************

; This is used to allow the A/D time to sample the input

; (acquisition time).

;

; This routine requires 11 cycles to complete.

; The call and return add another 4 cycles.

;

; 15 cycles with Fosc=4MHz means this delay consumes 15us.



SetupDelay

movlw..3..; Load Temp with decimal 3

movwf.TEMP

SD

decfsz.TEMP, F..; Delay loop

goto.SD

return



END



----------------------------

#3170 Nov 7, 2003

the interrupt vector is 0x4, not 0x8

even though commented out in your code).

See page 9 on the 818 data sheet.



Phil

--- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> some deal has been said about ADCs, and its becoming an important

> feature in pics now. Hoeever, is it all that difficult to make it

> work? Here I list a program I wrote which simply converts an

analogue

> signal thru a pot to AN0, then outputs the result to portb which is

a

> bank if LEDs. for some reason, it doesnt work. I've tried going

over

> the logic disabling the interrupts so that the program doesn

nothing

> but loop and convert. But its not working...Is it a timing problem,

> so something i forgot to configure guys?

>

> ; The A/D is configured as follows:

> ; Vref = 2.5V

> ; A/D Osc. = Fosc/8

> ; A/D Channel = AN0 (RA0)

>

> .LIST P=16f818

> .include "P16f818.inc".; File contains addresses for

> register and bit names

> .CBLOCK.0x20

> ..TEMP

> ..ENDC

>

> ;************************************************************

> ; reset and interrupt vectors

>

> .org.0x00000.; Reset Vector Address

> .goto.Start

>

> ;.org.0x00008.; Interrupt Vector Address

> ;.goto.ISR.; goto Interrupt Service Routine.

>

> ;************************************************************

> ; program code starts here

>

> .

> .org.0x00020

> Start

> .bcf..STATUS,RP0

> .bcf..STATUS,RP1

>

> .bsf..STATUS,RP0

>

> .BSF..OPTION_REG,7..;DISABLE INTERNAL P/U

> .clrf.PORTB..; clear all bits of PORTB.

> .clrf.TRISB..; Set PORTB as outputs

>

> .BCF..STATUS,RP0

> .call.InitializeAD .; configure A/D module

> .

> .call.SetupDelay.; delay for 15 instruction cycles

>

> Main.bsf.ADCON0,GO.; Start first A/D conversion

> .call.SetupDelay.; Delay for 15 cycles

>

> .goto.Main..; do nothing loop

>

> ;************************************************************

> ; Service A/D interrupt

> ; Get value and display on LEDs

>

> ;ISR

> .; Save context (WREG and STATUS) if required.

>

> ;.btfss.PIR1,ADIF.; Did A/D cause interrupt?

> ;.goto.OtherInt.; No, check other sources

> .

> .movf.ADRESH,W.; Get A/D value

> .movwf.PORTB..; Display on LEDs

> .;bcf.PIR1,ADIF.; Reset A/D int flag

>

> .call.SetupDelay.; Delay for 15 cycles

>

> ;.bsf.ADCON0,GO.; Start A/D conversion

>

> ;.goto.EndISR..; return from ISR

>

> ;OtherInt

> .; This would be replaced by code to check and service other

> interrupt sources

> .;goto.$.; trap here, loops to self

>

> ;EndISR

> .; Restore context if saved.

>

> .;retfie..; Return, enables GIE

>

> ;************************************************************

> ; InitializeAD - initializes and sets up the A/D hardware.

> ; Select AN0 to AN3 as analog inputs, RC clock, and read AN0.

>

> InitializeAD

> .BSF..STATUS,RP0

> .movlw.B'10000101'.; Make RA0,RA1,RA4 analog inputs

> .movwf.ADCON1

>

> .BSF..STATUS,RP1

> .movlw.B'01000001'.; Select Fosc/8, AN0 selected,

> .movwf.ADCON0..; A/D enabled

>

> .bcf..INTCON,PEIE.; Enable peripheral interrupts

> .bcf..INTCON,GIE.; Enable Global interrupts

>

> .BCF..STATUS,RP0

> .

> .bcf..PIR1,ADIF.; Clear A/D interrupt flag

> .bcf..PIE1,ADIE.; Enable A/D interrupt

> .

>

>

> .return

>

> ;************************************************************

> ; This is used to allow the A/D time to sample the input

> ; (acquisition time).

> ;

> ; This routine requires 11 cycles to complete.

> ; The call and return add another 4 cycles.

> ;

> ; 15 cycles with Fosc=4MHz means this delay consumes 15us.

>

> SetupDelay

> .movlw..3..; Load Temp with decimal 3

> .movwf.TEMP

> SD

> .decfsz.TEMP, F..; Delay loop

> .goto.SD

> .return

>

> .END







----------------------------

#3175 Nov 7, 2003

A quick glance shows that you are disabling all the interrupts, not

enabling. And in the line labeled "Main" you keep setting the ADC

done bit.



Chad

--- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> some deal has been said about ADCs, and its becoming an important

> feature in pics now. Hoeever, is it all that difficult to make it

> work? Here I list a program I wrote which simply converts an analogue

> signal thru a pot to AN0, then outputs the result to portb which is a

> bank if LEDs. for some reason, it doesnt work. I've tried going over

> the logic disabling the interrupts so that the program doesn nothing

> but loop and convert. But its not working...Is it a timing problem,

> so something i forgot to configure guys?

>

> ; The A/D is configured as follows:

> ; Vref = 2.5V

> ; A/D Osc. = Fosc/8

> ; A/D Channel = AN0 (RA0)

>

> .LIST P=16f818

> .include "P16f818.inc".; File contains addresses for

> register and bit names

> .CBLOCK.0x20

> ..TEMP

> ..ENDC

>

> ;************************************************************

> ; reset and interrupt vectors

>

> .org.0x00000.; Reset Vector Address

> .goto.Start

>

> ;.org.0x00008.; Interrupt Vector Address

> ;.goto.ISR.; goto Interrupt Service Routine.

>

> ;************************************************************

> ; program code starts here

>

> .

> .org.0x00020

> Start

> .bcf..STATUS,RP0

> .bcf..STATUS,RP1

>

> .bsf..STATUS,RP0

>

> .BSF..OPTION_REG,7..;DISABLE INTERNAL P/U

> .clrf.PORTB..; clear all bits of PORTB.

> .clrf.TRISB..; Set PORTB as outputs

>

> .BCF..STATUS,RP0

> .call.InitializeAD .; configure A/D module

> .

> .call.SetupDelay.; delay for 15 instruction cycles

>

> Main.bsf.ADCON0,GO.; Start first A/D conversion

> .call.SetupDelay.; Delay for 15 cycles

>

> .goto.Main..; do nothing loop

>

> ;************************************************************

> ; Service A/D interrupt

> ; Get value and display on LEDs

>

> ;ISR

> .; Save context (WREG and STATUS) if required.

>

> ;.btfss.PIR1,ADIF.; Did A/D cause interrupt?

> ;.goto.OtherInt.; No, check other sources

> .

> .movf.ADRESH,W.; Get A/D value

> .movwf.PORTB..; Display on LEDs

> .;bcf.PIR1,ADIF.; Reset A/D int flag

>

> .call.SetupDelay.; Delay for 15 cycles

>

> ;.bsf.ADCON0,GO.; Start A/D conversion

>

> ;.goto.EndISR..; return from ISR

>

> ;OtherInt

> .; This would be replaced by code to check and service other

> interrupt sources

> .;goto.$.; trap here, loops to self

>

> ;EndISR

> .; Restore context if saved.

>

> .;retfie..; Return, enables GIE

>

> ;************************************************************

> ; InitializeAD - initializes and sets up the A/D hardware.

> ; Select AN0 to AN3 as analog inputs, RC clock, and read AN0.

>

> InitializeAD

> .BSF..STATUS,RP0

> .movlw.B'10000101'.; Make RA0,RA1,RA4 analog inputs

> .movwf.ADCON1

>

> .BSF..STATUS,RP1

> .movlw.B'01000001'.; Select Fosc/8, AN0 selected,

> .movwf.ADCON0..; A/D enabled

>

> .bcf..INTCON,PEIE.; Enable peripheral interrupts

> .bcf..INTCON,GIE.; Enable Global interrupts

>

> .BCF..STATUS,RP0

> .

> .bcf..PIR1,ADIF.; Clear A/D interrupt flag

> .bcf..PIE1,ADIE.; Enable A/D interrupt

> .

>

>

> .return

>

> ;************************************************************

> ; This is used to allow the A/D time to sample the input

> ; (acquisition time).

> ;

> ; This routine requires 11 cycles to complete.

> ; The call and return add another 4 cycles.

> ;

> ; 15 cycles with Fosc=4MHz means this delay consumes 15us.

>

> SetupDelay

> .movlw..3..; Load Temp with decimal 3

> .movwf.TEMP

> SD

> .decfsz.TEMP, F..; Delay loop

> .goto.SD

> .return

>

> .END



----------------------------

#3176 Nov 7, 2003

yup, i tried taking out the interrupts and let the ADC loop itself,

giving some delay for the cap to charge up. I am using the internal

ocs. Could there be some other register I did not switch properly,

or some bank switching not done right...



BG --- In piclist@yahoogroups.com, "Phil" phil1960us@y...> wrote:

> the interrupt vector is 0x4, not 0x8

> even though commented out in your code).

> See page 9 on the 818 data sheet.

>

> Phil

>

> --- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> > some deal has been said about ADCs, and its becoming an important

> > feature in pics now. Hoeever, is it all that difficult to make it

> > work? Here I list a program I wrote which simply converts an

> analogue

> > signal thru a pot to AN0, then outputs the result to portb which

is

> a

> > bank if LEDs. for some reason, it doesnt work. I've tried going

> over

> > the logic disabling the interrupts so that the program doesn

> nothing

> > but loop and convert. But its not working...Is it a timing

problem,

> > so something i forgot to configure guys?

> >

> > ; The A/D is configured as follows:

> > ; Vref = 2.5V

> > ; A/D Osc. = Fosc/8

> > ; A/D Channel = AN0 (RA0)

> >

> > .LIST P=16f818

> > .include "P16f818.inc".; File contains addresses for

> > register and bit names

> > .CBLOCK.0x20

> > ..TEMP

> > ..ENDC

> >

> > ;************************************************************

> > ; reset and interrupt vectors

> >

> > .org.0x00000.; Reset Vector Address

> > .goto.Start

> >

> > ;.org.0x00008.; Interrupt Vector Address

> > ;.goto.ISR.; goto Interrupt Service Routine.

> >

> > ;************************************************************

> > ; program code starts here

> >

> > .

> > .org.0x00020

> > Start

> > .bcf..STATUS,RP0

> > .bcf..STATUS,RP1

> >

> > .bsf..STATUS,RP0

> >

> > .BSF..OPTION_REG,7..;DISABLE INTERNAL P/U

> > .clrf.PORTB..; clear all bits of PORTB.

> > .clrf.TRISB..; Set PORTB as outputs

> >

> > .BCF..STATUS,RP0

> > .call.InitializeAD .; configure A/D module

> > .

> > .call.SetupDelay.; delay for 15 instruction cycles

> >

> > Main.bsf.ADCON0,GO.; Start first A/D conversion

> > .call.SetupDelay.; Delay for 15 cycles

> >

> > .goto.Main..; do nothing loop

> >

> > ;************************************************************

> > ; Service A/D interrupt

> > ; Get value and display on LEDs

> >

> > ;ISR

> > .; Save context (WREG and STATUS) if required.

> >

> > ;.btfss.PIR1,ADIF.; Did A/D cause interrupt?

> > ;.goto.OtherInt.; No, check other sources

> > .

> > .movf.ADRESH,W.; Get A/D value

> > .movwf.PORTB..; Display on LEDs

> > .;bcf.PIR1,ADIF.; Reset A/D int flag

> >

> > .call.SetupDelay.; Delay for 15 cycles

> >

> > ;.bsf.ADCON0,GO.; Start A/D conversion

> >

> > ;.goto.EndISR..; return from ISR

> >

> > ;OtherInt

> > .; This would be replaced by code to check and service other

> > interrupt sources

> > .;goto.$.; trap here, loops to self

> >

> > ;EndISR

> > .; Restore context if saved.

> >

> > .;retfie..; Return, enables GIE

> >

> > ;************************************************************

> > ; InitializeAD - initializes and sets up the A/D hardware.

> > ; Select AN0 to AN3 as analog inputs, RC clock, and read AN0.

> >

> > InitializeAD

> > .BSF..STATUS,RP0

> > .movlw.B'10000101'.; Make RA0,RA1,RA4 analog inputs

> > .movwf.ADCON1

> >

> > .BSF..STATUS,RP1

> > .movlw.B'01000001'.; Select Fosc/8, AN0 selected,

> > .movwf.ADCON0..; A/D enabled

> >

> > .bcf..INTCON,PEIE.; Enable peripheral interrupts

> > .bcf..INTCON,GIE.; Enable Global interrupts

> >

> > .BCF..STATUS,RP0

> > .

> > .bcf..PIR1,ADIF.; Clear A/D interrupt flag

> > .bcf..PIE1,ADIE.; Enable A/D interrupt

> > .

> >

> >

> > .return

> >

> > ;************************************************************

> > ; This is used to allow the A/D time to sample the input

> > ; (acquisition time).

> > ;

> > ; This routine requires 11 cycles to complete.

> > ; The call and return add another 4 cycles.

> > ;

> > ; 15 cycles with Fosc=4MHz means this delay consumes 15us.

> >

> > SetupDelay

> > .movlw..3..; Load Temp with decimal 3

> > .movwf.TEMP

> > SD

> > .decfsz.TEMP, F..; Delay loop

> > .goto.SD

> > .return

> >

> > .END







----------------------------

#3178 Nov 7, 2003

Maybe I am missing something but it looks like at 'Main' all you are

doing is starting the conversion and then looping to start it over

again. The port is never read and certainly nothing is being sent

to PORTB.



As a suggestion, I would try to make it work without the ISR. All

you do is start the conversion and loop while waiting for the GO bit

to drop to 0. Something like:

bsf ADCON0,GO ; start A/D conversion

; may need to delay 15 uS

test:



btfsc ADCON0,NOT_DONE

goto test ; wait for it to complete



movf ADRESH,w ; get A/D value





Microchip app note AN546 may be a help.

--- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> yup, i tried taking out the interrupts and let the ADC loop

itself,

> giving some delay for the cap to charge up. I am using the

internal

> ocs. Could there be some other register I did not switch

properly,

> or some bank switching not done right...

>

> BG

> --- In piclist@yahoogroups.com, "Phil" phil1960us@y...> wrote:

> > the interrupt vector is 0x4, not 0x8

> > even though commented out in your code).

> > See page 9 on the 818 data sheet.

> >

> > Phil

> >

> > --- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> > > some deal has been said about ADCs, and its becoming an

important

> > > feature in pics now. Hoeever, is it all that difficult to make

it

> > > work? Here I list a program I wrote which simply converts an

> > analogue

> > > signal thru a pot to AN0, then outputs the result to portb

which

> is

> > a

> > > bank if LEDs. for some reason, it doesnt work. I've tried

going

> > over

> > > the logic disabling the interrupts so that the program doesn

> > nothing

> > > but loop and convert. But its not working...Is it a timing

> problem,

> > > so something i forgot to configure guys?

> > >

> > > ; The A/D is configured as follows:

> > > ; Vref = 2.5V

> > > ; A/D Osc. = Fosc/8

> > > ; A/D Channel = AN0 (RA0)

> > >

> > > .LIST P=16f818

> > > .include "P16f818.inc".; File contains addresses for

> > > register and bit names

> > > .CBLOCK.0x20

> > > ..TEMP

> > > ..ENDC

> > >

> > > ;************************************************************

> > > ; reset and interrupt vectors

> > >

> > > .org.0x00000.; Reset Vector Address

> > > .goto.Start

> > >

> > > ;.org.0x00008.; Interrupt Vector Address

> > > ;.goto.ISR.; goto Interrupt Service Routine.

> > >

> > > ;************************************************************

> > > ; program code starts here

> > >

> > > .

> > > .org.0x00020

> > > Start

> > > .bcf..STATUS,RP0

> > > .bcf..STATUS,RP1

> > >

> > > .bsf..STATUS,RP0

> > >

> > > .BSF..OPTION_REG,7..;DISABLE INTERNAL

P/U

> > > .clrf.PORTB..; clear all bits of PORTB.

> > > .clrf.TRISB..; Set PORTB as outputs

> > >

> > > .BCF..STATUS,RP0

> > > .call.InitializeAD .; configure A/D module

> > > .

> > > .call.SetupDelay.; delay for 15 instruction cycles

> > >

> > > Main.bsf.ADCON0,GO.; Start first A/D conversion

> > > .call.SetupDelay.; Delay for 15 cycles

> > >

> > > .goto.Main..; do nothing loop

> > >

> > > ;************************************************************

> > > ; Service A/D interrupt

> > > ; Get value and display on LEDs

> > >

> > > ;ISR

> > > .; Save context (WREG and STATUS) if required.

> > >

> > > ;.btfss.PIR1,ADIF.; Did A/D cause interrupt?

> > > ;.goto.OtherInt.; No, check other sources

> > > .

> > > .movf.ADRESH,W.; Get A/D value

> > > .movwf.PORTB..; Display on LEDs

> > > .;bcf.PIR1,ADIF.; Reset A/D int flag

> > >

> > > .call.SetupDelay.; Delay for 15 cycles

> > >

> > > ;.bsf.ADCON0,GO.; Start A/D conversion

> > >

> > > ;.goto.EndISR..; return from ISR

> > >

> > > ;OtherInt

> > > .; This would be replaced by code to check and service other

> > > interrupt sources

> > > .;goto.$.; trap here, loops to self

> > >

> > > ;EndISR

> > > .; Restore context if saved.

> > >

> > > .;retfie..; Return, enables GIE

> > >

> > > ;************************************************************

> > > ; InitializeAD - initializes and sets up the A/D hardware.

> > > ; Select AN0 to AN3 as analog inputs, RC clock, and read AN0.

> > >

> > > InitializeAD

> > > .BSF..STATUS,RP0

> > > .movlw.B'10000101'.; Make RA0,RA1,RA4 analog inputs

> > > .movwf.ADCON1

> > >

> > > .BSF..STATUS,RP1

> > > .movlw.B'01000001'.; Select Fosc/8, AN0 selected,

> > > .movwf.ADCON0..; A/D enabled

> > >

> > > .bcf..INTCON,PEIE.; Enable peripheral

interrupts

> > > .bcf..INTCON,GIE.; Enable Global interrupts

> > >

> > > .BCF..STATUS,RP0

> > > .

> > > .bcf..PIR1,ADIF.; Clear A/D interrupt flag

> > > .bcf..PIE1,ADIE.; Enable A/D interrupt

> > > .

> > >

> > >

> > > .return

> > >

> > > ;************************************************************

> > > ; This is used to allow the A/D time to sample the input

> > > ; (acquisition time).

> > > ;

> > > ; This routine requires 11 cycles to complete.

> > > ; The call and return add another 4 cycles.

> > > ;

> > > ; 15 cycles with Fosc=4MHz means this delay consumes 15us.

> > >

> > > SetupDelay

> > > .movlw..3..; Load Temp with decimal 3

> > > .movwf.TEMP

> > > SD

> > > .decfsz.TEMP, F..; Delay loop

> > > .goto.SD

> > > .return

> > >

> > > .END







----------------------------

#3179 Nov 7, 2003

Yup, I just realized that and modified the main loop to set the AD

bit, then keep polling the ADC interrupt bit. When set, the contents

of ARESHL is written into port b. Thus turning the trim pot should

show the LED bank lighting up like a bargraph display..but running

this code, as i turn the pot up and down (vary the anlg voltage into

AN0), the light blinks to show some on/off state. Thus only portB,0

is outputting although TRISB is all set to Ox00...

BG



Main.nop

bcf.PIR1,ADIF

bsf.ADCON0,GO.; Start first A/D conversion

ADC..btfss.PIR1,ADIF.; Did A/D cause interrupt?

goto ADC





movfw.ADRESL

movwf.PORTB

call.SetupDelay.; Delay for 15 cycles



goto.Main..; do nothing loop



--- In piclist@yahoogroups.com, "rtstofer" rstofer@p...> wrote:

>

> Maybe I am missing something but it looks like at 'Main' all you

are

> doing is starting the conversion and then looping to start it over

> again. The port is never read and certainly nothing is being sent

> to PORTB.

>

> As a suggestion, I would try to make it work without the ISR. All

> you do is start the conversion and loop while waiting for the GO

bit

> to drop to 0. Something like:

> bsf ADCON0,GO ; start A/D conversion

> ; may need to delay 15 uS

> test:

>

> btfsc ADCON0,NOT_DONE

> goto test ; wait for it to complete

>

> movf ADRESH,w ; get A/D value

>

>

> Microchip app note AN546 may be a help.

>

> --- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> > yup, i tried taking out the interrupts and let the ADC loop

> itself,

> > giving some delay for the cap to charge up. I am using the

> internal

> > ocs. Could there be some other register I did not switch

> properly,

> > or some bank switching not done right...

> >

> > BG

> > --- In piclist@yahoogroups.com, "Phil" phil1960us@y...> wrote:

> > > the interrupt vector is 0x4, not 0x8

> > > even though commented out in your code).

> > > See page 9 on the 818 data sheet.

> > >

> > > Phil

> > >

> > > --- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> > > > some deal has been said about ADCs, and its becoming an

> important

> > > > feature in pics now. Hoeever, is it all that difficult to

make

> it

> > > > work? Here I list a program I wrote which simply converts an

> > > analogue

> > > > signal thru a pot to AN0, then outputs the result to portb

> which

> > is

> > > a

> > > > bank if LEDs. for some reason, it doesnt work. I've tried

> going

> > > over

> > > > the logic disabling the interrupts so that the program doesn

> > > nothing

> > > > but loop and convert. But its not working...Is it a timing

> > problem,

> > > > so something i forgot to configure guys?

> > > >

> > > > ; The A/D is configured as follows:

> > > > ; Vref = 2.5V

> > > > ; A/D Osc. = Fosc/8

> > > > ; A/D Channel = AN0 (RA0)

> > > >

> > > > .LIST P=16f818

> > > > .include "P16f818.inc".; File contains addresses for

> > > > register and bit names

> > > > .CBLOCK.0x20

> > > > ..TEMP

> > > > ..ENDC

> > > >

> > > > ;************************************************************

> > > > ; reset and interrupt vectors

> > > >

> > > > .org.0x00000.; Reset Vector Address

> > > > .goto.Start

> > > >

> > > > ;.org.0x00008.; Interrupt Vector Address

> > > > ;.goto.ISR.; goto Interrupt Service Routine



> > > >

> > > > ;************************************************************

> > > > ; program code starts here

> > > >

> > > > .

> > > > .org.0x00020

> > > > Start

> > > > .bcf..STATUS,RP0

> > > > .bcf..STATUS,RP1

> > > >

> > > > .bsf..STATUS,RP0

> > > >

> > > > .BSF..OPTION_REG,7..;DISABLE

INTERNAL

> P/U

> > > > .clrf.PORTB..; clear all bits of PORTB



> > > > .clrf.TRISB..; Set PORTB as outputs

> > > >

> > > > .BCF..STATUS,RP0

> > > > .call.InitializeAD .; configure A/D module

> > > > .

> > > > .call.SetupDelay.; delay for 15 instruction

cycles

> > > >

> > > > Main.bsf.ADCON0,GO.; Start first A/D conversion

> > > > .call.SetupDelay.; Delay for 15 cycles

> > > >

> > > > .goto.Main..; do nothing loop

> > > >

> > > > ;************************************************************

> > > > ; Service A/D interrupt

> > > > ; Get value and display on LEDs

> > > >

> > > > ;ISR

> > > > .; Save context (WREG and STATUS) if required.

> > > >

> > > > ;.btfss.PIR1,ADIF.; Did A/D cause interrupt?

> > > > ;.goto.OtherInt.; No, check other sources

> > > > .

> > > > .movf.ADRESH,W.; Get A/D value

> > > > .movwf.PORTB..; Display on LEDs

> > > > .;bcf.PIR1,ADIF.; Reset A/D int flag

> > > >

> > > > .call.SetupDelay.; Delay for 15 cycles

> > > >

> > > > ;.bsf.ADCON0,GO.; Start A/D conversion

> > > >

> > > > ;.goto.EndISR..; return from ISR

> > > >

> > > > ;OtherInt

> > > > .; This would be replaced by code to check and service

other

> > > > interrupt sources

> > > > .;goto.$.; trap here, loops to self

> > > >

> > > > ;EndISR

> > > > .; Restore context if saved.

> > > >

> > > > .;retfie..; Return, enables GIE

> > > >

> > > > ;************************************************************

> > > > ; InitializeAD - initializes and sets up the A/D hardware.

> > > > ; Select AN0 to AN3 as analog inputs, RC clock, and read AN0.

> > > >

> > > > InitializeAD

> > > > .BSF..STATUS,RP0

> > > > .movlw.B'10000101'.; Make RA0,RA1,RA4 analog

inputs

> > > > .movwf.ADCON1

> > > >

> > > > .BSF..STATUS,RP1

> > > > .movlw.B'01000001'.; Select Fosc/8, AN0 selected,

> > > > .movwf.ADCON0..; A/D enabled

> > > >

> > > > .bcf..INTCON,PEIE.; Enable peripheral

> interrupts

> > > > .bcf..INTCON,GIE.; Enable Global

interrupts

> > > >

> > > > .BCF..STATUS,RP0

> > > > .

> > > > .bcf..PIR1,ADIF.; Clear A/D interrupt

flag

> > > > .bcf..PIE1,ADIE.; Enable A/D interrupt

> > > > .

> > > >

> > > >

> > > > .return

> > > >

> > > > ;************************************************************

> > > > ; This is used to allow the A/D time to sample the input

> > > > ; (acquisition time).

> > > > ;

> > > > ; This routine requires 11 cycles to complete.

> > > > ; The call and return add another 4 cycles.

> > > > ;

> > > > ; 15 cycles with Fosc=4MHz means this delay consumes 15us.

> > > >

> > > > SetupDelay

> > > > .movlw..3..; Load Temp with decimal 3

> > > > .movwf.TEMP

> > > > SD

> > > > .decfsz.TEMP, F..; Delay loop

> > > > .goto.SD

> > > > .return

> > > >

> > > > .END







----------------------------

#3180 Nov 7, 2003

ok I tried inserting your code and completely disabling the

interrupts but its still yielding the same result...



--- In piclist@yahoogroups.com, "rtstofer" rstofer@p...> wrote:

>

> Maybe I am missing something but it looks like at 'Main' all you

are

> doing is starting the conversion and then looping to start it over

> again. The port is never read and certainly nothing is being sent

> to PORTB.

>

> As a suggestion, I would try to make it work without the ISR. All

> you do is start the conversion and loop while waiting for the GO

bit

> to drop to 0. Something like:

> bsf ADCON0,GO ; start A/D conversion

> ; may need to delay 15 uS

> test:

>

> btfsc ADCON0,NOT_DONE

> goto test ; wait for it to complete

>

> movf ADRESH,w ; get A/D value

>

>

> Microchip app note AN546 may be a help.

>

> --- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> > yup, i tried taking out the interrupts and let the ADC loop

> itself,

> > giving some delay for the cap to charge up. I am using the

> internal

> > ocs. Could there be some other register I did not switch

> properly,

> > or some bank switching not done right...

> >

> > BG

> > --- In piclist@yahoogroups.com, "Phil" phil1960us@y...> wrote:

> > > the interrupt vector is 0x4, not 0x8

> > > even though commented out in your code).

> > > See page 9 on the 818 data sheet.

> > >

> > > Phil

> > >

> > > --- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> > > > some deal has been said about ADCs, and its becoming an

> important

> > > > feature in pics now. Hoeever, is it all that difficult to

make

> it

> > > > work? Here I list a program I wrote which simply converts an

> > > analogue

> > > > signal thru a pot to AN0, then outputs the result to portb

> which

> > is

> > > a

> > > > bank if LEDs. for some reason, it doesnt work. I've tried

> going

> > > over

> > > > the logic disabling the interrupts so that the program doesn

> > > nothing

> > > > but loop and convert. But its not working...Is it a timing

> > problem,

> > > > so something i forgot to configure guys?

> > > >

> > > > ; The A/D is configured as follows:

> > > > ; Vref = 2.5V

> > > > ; A/D Osc. = Fosc/8

> > > > ; A/D Channel = AN0 (RA0)

> > > >

> > > > .LIST P=16f818

> > > > .include "P16f818.inc".; File contains addresses for

> > > > register and bit names

> > > > .CBLOCK.0x20

> > > > ..TEMP

> > > > ..ENDC

> > > >

> > > > ;************************************************************

> > > > ; reset and interrupt vectors

> > > >

> > > > .org.0x00000.; Reset Vector Address

> > > > .goto.Start

> > > >

> > > > ;.org.0x00008.; Interrupt Vector Address

> > > > ;.goto.ISR.; goto Interrupt Service Routine



> > > >

> > > > ;************************************************************

> > > > ; program code starts here

> > > >

> > > > .

> > > > .org.0x00020

> > > > Start

> > > > .bcf..STATUS,RP0

> > > > .bcf..STATUS,RP1

> > > >

> > > > .bsf..STATUS,RP0

> > > >

> > > > .BSF..OPTION_REG,7..;DISABLE

INTERNAL

> P/U

> > > > .clrf.PORTB..; clear all bits of PORTB



> > > > .clrf.TRISB..; Set PORTB as outputs

> > > >

> > > > .BCF..STATUS,RP0

> > > > .call.InitializeAD .; configure A/D module

> > > > .

> > > > .call.SetupDelay.; delay for 15 instruction

cycles

> > > >

> > > > Main.bsf.ADCON0,GO.; Start first A/D conversion

> > > > .call.SetupDelay.; Delay for 15 cycles

> > > >

> > > > .goto.Main..; do nothing loop

> > > >

> > > > ;************************************************************

> > > > ; Service A/D interrupt

> > > > ; Get value and display on LEDs

> > > >

> > > > ;ISR

> > > > .; Save context (WREG and STATUS) if required.

> > > >

> > > > ;.btfss.PIR1,ADIF.; Did A/D cause interrupt?

> > > > ;.goto.OtherInt.; No, check other sources

> > > > .

> > > > .movf.ADRESH,W.; Get A/D value

> > > > .movwf.PORTB..; Display on LEDs

> > > > .;bcf.PIR1,ADIF.; Reset A/D int flag

> > > >

> > > > .call.SetupDelay.; Delay for 15 cycles

> > > >

> > > > ;.bsf.ADCON0,GO.; Start A/D conversion

> > > >

> > > > ;.goto.EndISR..; return from ISR

> > > >

> > > > ;OtherInt

> > > > .; This would be replaced by code to check and service

other

> > > > interrupt sources

> > > > .;goto.$.; trap here, loops to self

> > > >

> > > > ;EndISR

> > > > .; Restore context if saved.

> > > >

> > > > .;retfie..; Return, enables GIE

> > > >

> > > > ;************************************************************

> > > > ; InitializeAD - initializes and sets up the A/D hardware.

> > > > ; Select AN0 to AN3 as analog inputs, RC clock, and read AN0.

> > > >

> > > > InitializeAD

> > > > .BSF..STATUS,RP0

> > > > .movlw.B'10000101'.; Make RA0,RA1,RA4 analog

inputs

> > > > .movwf.ADCON1

> > > >

> > > > .BSF..STATUS,RP1

> > > > .movlw.B'01000001'.; Select Fosc/8, AN0 selected,

> > > > .movwf.ADCON0..; A/D enabled

> > > >

> > > > .bcf..INTCON,PEIE.; Enable peripheral

> interrupts

> > > > .bcf..INTCON,GIE.; Enable Global

interrupts

> > > >

> > > > .BCF..STATUS,RP0

> > > > .

> > > > .bcf..PIR1,ADIF.; Clear A/D interrupt

flag

> > > > .bcf..PIE1,ADIE.; Enable A/D interrupt

> > > > .

> > > >

> > > >

> > > > .return

> > > >

> > > > ;************************************************************

> > > > ; This is used to allow the A/D time to sample the input

> > > > ; (acquisition time).

> > > > ;

> > > > ; This routine requires 11 cycles to complete.

> > > > ; The call and return add another 4 cycles.

> > > > ;

> > > > ; 15 cycles with Fosc=4MHz means this delay consumes 15us.

> > > >

> > > > SetupDelay

> > > > .movlw..3..; Load Temp with decimal 3

> > > > .movwf.TEMP

> > > > SD

> > > > .decfsz.TEMP, F..; Delay loop

> > > > .goto.SD

> > > > .return

> > > >

> > > > .END







----------------------------

#3181 Nov 8, 2003

You have the output format set right justified so only the very high

bits will change in ADRESH. You have also selected a configuration

that requires Vref - how are you handling that?



--- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> ok I tried inserting your code and completely disabling the

> interrupts but its still yielding the same result...

>

>

> --- In piclist@yahoogroups.com, "rtstofer" rstofer@p...> wrote:

> >

> > Maybe I am missing something but it looks like at 'Main' all you

> are

> > doing is starting the conversion and then looping to start it

over

> > again. The port is never read and certainly nothing is being

sent

> > to PORTB.

> >

> > As a suggestion, I would try to make it work without the ISR.

All

> > you do is start the conversion and loop while waiting for the GO

> bit

> > to drop to 0. Something like:

> > bsf ADCON0,GO ; start A/D conversion

> > ; may need to delay 15 uS

> > test:

> >

> > btfsc ADCON0,NOT_DONE

> > goto test ; wait for it to complete

> >

> > movf ADRESH,w ; get A/D value

> >

> >

> > Microchip app note AN546 may be a help.

> >

> > --- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> > > yup, i tried taking out the interrupts and let the ADC loop

> > itself,

> > > giving some delay for the cap to charge up. I am using the

> > internal

> > > ocs. Could there be some other register I did not switch

> > properly,

> > > or some bank switching not done right...

> > >

> > > BG

> > > --- In piclist@yahoogroups.com, "Phil" phil1960us@y...> wrote:

> > > > the interrupt vector is 0x4, not 0x8

> > > > even though commented out in your code).

> > > > See page 9 on the 818 data sheet.

> > > >

> > > > Phil

> > > >

> > > > --- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> > > > > some deal has been said about ADCs, and its becoming an

> > important

> > > > > feature in pics now. Hoeever, is it all that difficult to

> make

> > it

> > > > > work? Here I list a program I wrote which simply converts

an

> > > > analogue

> > > > > signal thru a pot to AN0, then outputs the result to portb

> > which

> > > is

> > > > a

> > > > > bank if LEDs. for some reason, it doesnt work. I've tried

> > going

> > > > over

> > > > > the logic disabling the interrupts so that the program

doesn

> > > > nothing

> > > > > but loop and convert. But its not working...Is it a timing

> > > problem,

> > > > > so something i forgot to configure guys?

> > > > >

> > > > > ; The A/D is configured as follows:

> > > > > ; Vref = 2.5V

> > > > > ; A/D Osc. = Fosc/8

> > > > > ; A/D Channel = AN0 (RA0)

> > > > >

> > > > > .LIST P=16f818

> > > > > .include "P16f818.inc".; File contains addresses

for

> > > > > register and bit names

> > > > > .CBLOCK.0x20

> > > > > ..TEMP

> > > > > ..ENDC

> > > > >

> > > >

> ;************************************************************

> > > > > ; reset and interrupt vectors

> > > > >

> > > > > .org.0x00000.; Reset Vector Address

> > > > > .goto.Start

> > > > >

> > > > > ;.org.0x00008.; Interrupt Vector Address

> > > > > ;.goto.ISR.; goto Interrupt Service Routine

> .

> > > > >

> > > >

> ;************************************************************

> > > > > ; program code starts here

> > > > >

> > > > > .

> > > > > .org.0x00020

> > > > > Start

> > > > > .bcf..STATUS,RP0

> > > > > .bcf..STATUS,RP1

> > > > >

> > > > > .bsf..STATUS,RP0

> > > > >

> > > > > .BSF..OPTION_REG,7..;DISABLE

> INTERNAL

> > P/U

> > > > > .clrf.PORTB..; clear all bits of PORTB

> .

> > > > > .clrf.TRISB..; Set PORTB as outputs

> > > > >

> > > > > .BCF..STATUS,RP0

> > > > > .call.InitializeAD .; configure A/D module

> > > > > .

> > > > > .call.SetupDelay.; delay for 15 instruction

> cycles

> > > > >

> > > > > Main.bsf.ADCON0,GO.; Start first A/D conversion

> > > > > .call.SetupDelay.; Delay for 15 cycles

> > > > >

> > > > > .goto.Main..; do nothing loop

> > > > >

> > > >

> ;************************************************************

> > > > > ; Service A/D interrupt

> > > > > ; Get value and display on LEDs

> > > > >

> > > > > ;ISR

> > > > > .; Save context (WREG and STATUS) if required.

> > > > >

> > > > > ;.btfss.PIR1,ADIF.; Did A/D cause interrupt?

> > > > > ;.goto.OtherInt.; No, check other sources

> > > > > .

> > > > > .movf.ADRESH,W.; Get A/D value

> > > > > .movwf.PORTB..; Display on LEDs

> > > > > .;bcf.PIR1,ADIF.; Reset A/D int flag

> > > > >

> > > > > .call.SetupDelay.; Delay for 15 cycles

> > > > >

> > > > > ;.bsf.ADCON0,GO.; Start A/D conversion

> > > > >

> > > > > ;.goto.EndISR..; return from ISR

> > > > >

> > > > > ;OtherInt

> > > > > .; This would be replaced by code to check and

service

> other

> > > > > interrupt sources

> > > > > .;goto.$.; trap here, loops to self

> > > > >

> > > > > ;EndISR

> > > > > .; Restore context if saved.

> > > > >

> > > > > .;retfie..; Return, enables GIE

> > > > >

> > > >

> ;************************************************************

> > > > > ; InitializeAD - initializes and sets up the A/D hardware.

> > > > > ; Select AN0 to AN3 as analog inputs, RC clock, and read

AN0.

> > > > >

> > > > > InitializeAD

> > > > > .BSF..STATUS,RP0

> > > > > .movlw.B'10000101'.; Make RA0,RA1,RA4 analog

> inputs

> > > > > .movwf.ADCON1

> > > > >

> > > > > .BSF..STATUS,RP1

> > > > > .movlw.B'01000001'.; Select Fosc/8, AN0

selected,

> > > > > .movwf.ADCON0..; A/D enabled

> > > > >

> > > > > .bcf..INTCON,PEIE.; Enable peripheral

> > interrupts

> > > > > .bcf..INTCON,GIE.; Enable Global

> interrupts

> > > > >

> > > > > .BCF..STATUS,RP0

> > > > > .

> > > > > .bcf..PIR1,ADIF.; Clear A/D

interrupt

> flag

> > > > > .bcf..PIE1,ADIE.; Enable A/D

interrupt

> > > > > .

> > > > >

> > > > >

> > > > > .return

> > > > >

> > > >

> ;************************************************************

> > > > > ; This is used to allow the A/D time to sample the input

> > > > > ; (acquisition time).

> > > > > ;

> > > > > ; This routine requires 11 cycles to complete.

> > > > > ; The call and return add another 4 cycles.

> > > > > ;

> > > > > ; 15 cycles with Fosc=4MHz means this delay consumes 15us.

> > > > >

> > > > > SetupDelay

> > > > > .movlw..3..; Load Temp with decimal 3

> > > > > .movwf.TEMP

> > > > > SD

> > > > > .decfsz.TEMP, F..; Delay loop

> > > > > .goto.SD

> > > > > .return

> > > > >

> > > > > .END







----------------------------

#3184 Nov 8, 2003

My Vref comes from a TL431 configured as a 2.5 V voltage reference,

while my analogue is from a 5 V fed thru a trimpot to AN0. I will

try using left justification to see if it helps.

--- In piclist@yahoogroups.com, "rtstofer" rstofer@p...> wrote:

>

> You have the output format set right justified so only the very

high

> bits will change in ADRESH. You have also selected a configuration

> that requires Vref - how are you handling that?

>



----------------------------

#3217 Nov 9, 2003

I think that the analogue voltage going in should not exceed Vref and

in this case I put 2.5 V as a reference but fed a 0-5Vdc signal which

kept overshooting the limit. I"ll fool around more to check out more

on this. Also i think I'll try on the interrupts and multiple

conversions. --- In piclist@yahoogroups.com, "bg3009" bg3009@y...> wrote:

> My Vref comes from a TL431 configured as a 2.5 V voltage reference,

> while my analogue is from a 5 V fed thru a trimpot to AN0. I will

> try using left justification to see if it helps.

>

> --- In piclist@yahoogroups.com, "rtstofer" rstofer@p...> wrote:

> >

> > You have the output format set right justified so only the very

> high

> > bits will change in ADRESH. You have also selected a

configuration

> > that requires Vref - how are you handling that?

> >


S
e
n
i
o
r
T
u
b
e
.
o
r
g