Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Tools
Old 27th June 2009, 04:11 AM   #1
Question Some ideals on adc

What would be the best way to say catch four adc values like low to high
I have this started it works good just don't no how to save four values
Code:
	list		p=16f684		; list directive to define processor
	#include	<P16F684.inc>		; processor specific variable definitions
	errorlevel -302 ; Turn off banking message
                            ; known tested (good) code

	__CONFIG    _CP_OFF & _CPD_OFF & _BOD_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _FCMEN_OFF & _IESO_OFF
	


	CBLOCK 		0x020
	saveadc
	endc


	ORG			0x000		; processor reset vector
  	goto		Start		; go to beginning of program


	ORG			0x004	    ; interrupt vector location

Start:
     bsf       STATUS,RP0     ; select Register Page 1
     movlw     0xFF
     movwf     TRISA          ; Make PortA all input
     clrf      TRISC          ; Make PortC all output
     movlw     0x10           ; A2D Clock Fosc/8
     movwf     ADCON1
     bcf       STATUS,RP0     ; back to Register Page 0

     bcf       STATUS,RP0     ; address Register Page 2
     bsf       STATUS,RP1     
     movlw     0xFF           ; we want all Port A pins Analog
     movwf     ANSEL
     bcf       STATUS,RP0     ; address Register Page 0
     bcf       STATUS,RP1
     
     movlw     0x01
     movwf     ADCON0         ; configure A2D for Channel 0 
MainLoop:
     call	adcdelay		  ;delay to charge cap
     bsf       ADCON0,GO      ; start conversion
     btfss     ADCON0,GO      ; this bit will change to zero when the conversion is complete
     goto      $-1

     movf     ADRESH,w       ; Copy the display to the LEDs
     movwf     saveadc		  ;save value adc
     movf	 saveadc
     movwf	 PORTC
     goto      MainLoop
adcdelay:
	 nop					  ;1 cycle

	 return					  ;4 cycles (including call)
	
     end

Last edited by be80be; 27th June 2009 at 04:14 AM.
be80be is offline  
Old 27th June 2009, 04:15 AM   #2
Default

Are you trying to save 4 ADC readings from 4 different channels/pins or 4 ADC readings from a single channel/pin?
__________________
Inside every little problem, is a big problem trying to get out.

Last edited by kchriste; 27th June 2009 at 04:16 AM. Reason: pin
kchriste is offline  
Old 27th June 2009, 04:34 AM   #3
Default

From a single pin I was using the 16f684 for testing when I get it all working and get some 12f675 in I'm going to use them on GPIO,0 for the adc
be80be is offline  
Old 27th June 2009, 04:55 AM   #4
Default

Simply allocate 4 sequential variables in memory and load the FSR with the address of the first one. The IRP bit of the STATUS register should contain the 9th bit of the address.
Then you simply use the INDF register to manipulate the data which the FSR points to. You increment the FSR register, in your MainLoop, to make INDF point to the next variable in memory and after 4 intterations, reset the FSR to the address of the first variable and then do it all over again.

From the datasheet:
Code:
A simple program to clear RAM locations 20h-2Fh
using indirect addressing is shown in Example 2-1.

movlw 0x20 ;initialize pointer
movwf FSR ;to RAM
NEXT
clrf INDF ;clear INDF register and thus what FSR points to.
incf  FSR,F ;inc pointer
btfss FSR,4 ;all done?
goto NEXT ;no clear next
CONTINUE
: ;yes continue
__________________
Inside every little problem, is a big problem trying to get out.

Last edited by kchriste; 27th June 2009 at 05:03 AM.
kchriste is offline  
Old 27th June 2009, 05:41 AM   #5
Default

I no this is not right but I'm lost with what i need to do How do I add to not clear
Code:
	CBLOCK 		0x020
	ad1
	ad2	
	ad3
	ad4
	endc


	ORG			0x000		; processor reset vector
  	goto		Start		; go to beginning of program


	ORG			0x004	    ; interrupt vector location

Start:
     bsf       STATUS,RP0     ; select Register Page 1
     movlw     0xFF
     movwf     TRISA          ; Make PortA all input
     clrf      TRISC          ; Make PortC all output
     movlw     0x10           ; A2D Clock Fosc/8
     movwf     ADCON1
     bcf       STATUS,RP0     ; back to Register Page 0

     bcf       STATUS,RP0     ; address Register Page 2
     bsf       STATUS,RP1     
     movlw     0xFF           ; we want all Port A pins Analog
     movwf     ANSEL
     bcf       STATUS,RP0     ; address Register Page 0
     bcf       STATUS,RP1
     
     movlw     0x01
     movwf     ADCON0         ; configure A2D for Channel 0 
MainLoop:
     call	   adcdelay		  ;delay to charge cap
     bsf       ADCON0,GO      ; start conversion
     btfss     ADCON0,GO      ; this bit will change to zero when the conversion is complete
     goto      $-1

     movf       ADRESH,w       ; Copy the display to the LEDs
     movlw 	 ad1 		  ;initialize pointer
     movwf     FSR            ;to RAM
NEXT
     clrf      INDF 		  ;clear INDF register and thus what FSR points to.
     incf      FSR,F          ;inc pointer
     btfss     FSR,4          ;all done?
     goto      NEXT           ;no clear next
CONTINUE                      ;yes continue  
     goto      MainLoop
adcdelay:
	 nop					  ;1 cycle

	 return					  ;4 cycles (including call)
	
     end

Last edited by be80be; 27th June 2009 at 05:42 AM.
be80be is offline  
Old 27th June 2009, 06:21 AM   #6
Default

That example was just to demonstrate how to use indirect addressing. The following code will put 4 consecutive 8bit ADC readings into ad1-ad4 and then repeat endlessly:
Code:
    list        p=16f684        ; list directive to define processor
    #include    <P16F684.inc>        ; processor specific variable definitions
    errorlevel -302 ; Turn off banking message
                            ; known tested (good) code

    __CONFIG    _CP_OFF & _CPD_OFF & _BOD_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _FCMEN_OFF & _IESO_OFF
    



    CBLOCK         0x020
    ad1
    ad2    
    ad3
    ad4
    endc


    ORG            0x000        ; processor reset vector
      goto        Start        ; go to beginning of program


    ORG            0x004        ; interrupt vector location

Start:
     bsf       STATUS,RP0     ; select Register Page 1
     movlw     0xFF
     movwf     TRISA          ; Make PortA all input
     clrf      TRISC          ; Make PortC all output
     movlw     0x10           ; A2D Clock Fosc/8
     movwf     ADCON1
     bcf       STATUS,RP0     ; back to Register Page 0

     bcf       STATUS,RP0     ; address Register Page 2
     bsf       STATUS,RP1     
     movlw     0xFF           ; we want all Port A pins Analog
     movwf     ANSEL
     bcf       STATUS,RP0     ; address Register Page 0
     bcf       STATUS,RP1
     
     movlw     0x01
     movwf     ADCON0         ; configure A2D for Channel 0 
MainLoop:
     movlw      0x20           ;initialize pointer
     movwf     FSR            ;to ad1 @ 0x20
NEXT
     call       adcdelay          ;delay to charge cap
     bsf       ADCON0,GO      ; start conversion
     btfss     ADCON0,GO      ; this bit will change to zero when the conversion is complete
     goto      $-1
     movf      ADRESH,w       ; Copy the display to the LEDs
     movwf       PORTC
     movwf     INDF           ;Copy the display to what FSR points to (ad1,2,3,or 4).
     incf      FSR,F          ;inc pointer
     btfss     FSR,2          ;Are we done 4 bytes yet?
     goto      NEXT           ;no so goto next
     goto      MainLoop
adcdelay:
     nop                      ;1 cycle

     return                      ;4 cycles (including call)
    
     end
__________________
Inside every little problem, is a big problem trying to get out.

Last edited by kchriste; 27th June 2009 at 06:31 AM.
kchriste is offline  
Old 27th June 2009, 07:04 AM   #7
Default

Thanks Kchriste This is kind of cool I set it to show two of the values with a delay between. I found some good reading for indirect addressing. going to read up
them
Code:
 list        p=16f684        ; list directive to define processor
    #include    <P16F684.inc>        ; processor specific variable definitions
    errorlevel -302 ; Turn off banking message
                            ; known tested (good) code

    __CONFIG    _CP_OFF & _CPD_OFF & _BOD_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _FCMEN_OFF & _IESO_OFF
    



    CBLOCK         0x020
    ad1
    ad2    
    ad3
    ad4
	d1
	d2
	d3
	endc


    ORG            0x000        ; processor reset vector
      goto        Start        ; go to beginning of program


    ORG            0x004        ; interrupt vector location

Start:
     bsf       STATUS,RP0     ; select Register Page 1
     movlw     0xFF
     movwf     TRISA          ; Make PortA all input
     clrf      TRISC          ; Make PortC all output
     movlw     0x10           ; A2D Clock Fosc/8
     movwf     ADCON1
     bcf       STATUS,RP0     ; back to Register Page 0

     bcf       STATUS,RP0     ; address Register Page 2
     bsf       STATUS,RP1     
     movlw     0xFF           ; we want all Port A pins Analog
     movwf     ANSEL
     bcf       STATUS,RP0     ; address Register Page 0
     bcf       STATUS,RP1
     
     movlw     0x01
     movwf     ADCON0         ; configure A2D for Channel 0 
MainLoop:
     movlw      0x20           ;initialize pointer
     movwf     FSR            ;to ad1 @ 0x20
NEXT
     call       adcdelay          ;delay to charge cap
     bsf       ADCON0,GO      ; start conversion
     btfss     ADCON0,GO      ; this bit will change to zero when the conversion is complete
     goto      $-1
     movf      ADRESH,w       ; Copy the display to the LEDs
     ;movwf       PORTC
     movwf     INDF           ;Copy the display to what FSR points to (ad1,2,3,or 4).
     incf      FSR,F          ;inc pointer
     btfss     FSR,2          ;Are we done 4 bytes yet?
     goto      NEXT           ;no so goto next
     movf	   ad2
     movwf	   PORTC
     call	   Delay
     movf	   ad4
     movwf	   PORTC
     call	   Delay
     goto      MainLoop
adcdelay:
     nop                      ;1 cycle

     return                      ;4 cycles (including call)
Delay
			;499994 cycles
	movlw	0x03
	movwf	d1
	movlw	0x18
	movwf	d2
	movlw	0x02
	movwf	d3
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0

			;2 cycles
	goto	$+1

			;4 cycles (including call)
	return
    
     end

Last edited by be80be; 27th June 2009 at 07:05 AM.
be80be is offline  
Old 28th June 2009, 03:23 AM   #8
Default

If I was getting a bit conversion and I wanted to check for
I would do some thing like 256/5 = 51.2
1. 0 to 1 volt 208 to 256
2. 1 to 2 volt 156 to 207
3. 2 to 3 volt 104 to 155
4. 3 to 4 volt 52 to 103
5. 4 to 5 volt 0 to 51
I rounded it off a little but is this some what the ideal or am I backward. In thinking. ?
be80be is offline  
Old 28th June 2009, 03:57 AM   #9
Default

I don't understand what you are asking. Do mean that you want to scale the 8-bit ADRESH ADC result of 0-255 to some other range such as 1-5?
__________________
Inside every little problem, is a big problem trying to get out.
kchriste is offline  
Old 28th June 2009, 04:52 AM   #10
Default

When the Adc gets a conversion In 8 bit mode the 8-bit converter has 256 states so is Internal Reference say set to 5 volts it will be = 256 2.5volts would be = 128
and 0 would be = 0 or is this wrong.
be80be is offline  
Old 28th June 2009, 04:59 AM   #11
Default

That is correct.
What I don't understand is what you want to do with the 0-255 data. Do you want to display the voltage as 0.00 to 5.00 on an LCD or LED display?
__________________
Inside every little problem, is a big problem trying to get out.
kchriste is offline  
Old 28th June 2009, 05:37 AM   #12
Default

Say I read 0 to 1 volt my program will do (A)
If I read 1 to 2 volts my program will do (b)
and so on to 5 volts
be80be is offline  
Old 28th June 2009, 06:22 AM   #13
Default

OK, I see what you want to do now. Well, you don't need to do any scaling with the PIC at all then. Just do a bunch of comparisons and gotos. Something like this maybe:

Code:
#define _1VOLT 0x33
#define _2VOLT 0x66
#define _2_5VOLT 0x7F
#define _3VOLT 0x99
#define _4VOLT 0xCC
#define _5VOLT 0xFF



Start:
    movlw _1VOLT
    subwf ADRESH, w
    BNC LessThan1V                ; Branch if less than 1V
    movlw _2VOLT
    subwf ADRESH, w
    BNC LessThan2V                ; Branch if Between 1V and 2V
    movlw _2_5VOLT
    subwf ADRESH, w
    BNC LessThan2_5V             ; Branch if Between 2V and 2.5V
    movlw _3VOLT
    subwf ADRESH, w
    BNC LessThan3V                ; Branch if Between 2.5V and  3V
    movlw _4VOLT
    subwf ADRESH, w
    BNC LessThan4V                ; Branch if Between 3V and 4V
    ;Hmmm..  must be 4V or more here.
__________________
Inside every little problem, is a big problem trying to get out.

Last edited by kchriste; 28th June 2009 at 06:33 AM.
kchriste is offline  
Old 28th June 2009, 07:43 AM   #14
Default

Just taking a wild guess here "BNC" means 'bit not clear'? as in the C flag?
__________________
Mike
My website: www.ElectroBird.net
birdman0_o is online now  
Old 28th June 2009, 07:57 AM   #15
Default

BNC = branch not carry. It is a pseudo op that compiles to,

Code:
    btfss STATUS,C
    goto  label
Mike.
Pommie is offline  
Reply

Tags
adc, ideals

Thread Tools
Display Modes




All times are GMT. The time now is 11:06 PM.


Electronic Circuits  |  Learning Electronics
eXTReMe Tracker