PIC 16F876a read from 2 analog ports

Thread Starter

oronning

Joined Aug 1, 2013
5
I'm trying to program codes to read two analog signals, but becomes rubbish when I read in from more than one port.

only ned 8bit so I read from ADRESH only.

the analog signal is volt signal form 2 potmeters. 0-3.8volt

do I have to gnd on the not in use ports on PORTA?
read for one of the inputs is ok.

Rich (BB code):
	list		p=16f876A	; list directive to define processor
	#include	<p16f876A.inc>	; processor specific variable definitions
	
	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF


ADCon0 EQU H'001F'
ADCon1 EQU H'009F'


AA		equ	0x2B
BB		equ	0x2C
BIN		equ	0x2D


#define	CARRY	STATUS,C	
#define	ZERO	STATUS,Z	
#define	NEG FLAGS,0
#define	ENABLE	PORTC,0
#define	RIGHT	PORTC,1
#define	LEFT	PORTC,2


;******************************************
HP:
	; Start at the reset vector
org 0x000
 goto Start
org 0x004
Interrupt
         retfie
Start:

	
         bsf    	STATUS,RP0   ;bank 1
         bcf    	STATUS,RP1
         movlw  	B'00011000'
         movwf   	TRISC              ;portc [3-0 6-8] outputs
         movlw   	H'00'
         movwf   	TRISB               ;portb [7-0] outputs

         clrf    	 ADCon1       ;left justified, all inputs a/d

         bcf     	STATUS,RP0   ;bank 0

         movlw  	B'11000001'  ;Fosc/8 [7-6], A/D ch0 [5-3], a/d on [0]
         movwf   	ADCon0
		clrf		PORTB
		clrf		PORTC
;******************************************		
HPLOOP:
	
	call	ad_porta0
	call	ad_porta1


	goto	HPLOOP

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


ad_porta0:

		 movlw    B'11000001'  ;Fosc/8 [7-6], A/D ch0 [5-3], a/d on [0]
         movwf    ADCon0
         bsf      ADCon0,GO    ;Start A/D conversion
Wait
         btfsc    ADCon0,GO    ;Wait for conversion to complete
         goto     Wait
 
         movf     ADRESH,W     ;write A/D result to PORTB

         movwf    AA        	;register


         return

ad_porta1:

         movlw     B'11011001'  ;Fosc/8 [7-6], A/D ch0 [5-3], a/d on [0]
         movwf    ADCon0
         bsf         ADCon0,GO    ;Start A/D conversion
Wait1
         btfsc     ADCon0,GO    ;Wait for conversion to complete
         goto      Wait1
 
         movf      ADRESH,W     ;write A/D result to PORTB
         movwf    BB        ;Register
         movwf    PORTB        ;LEDs

         return
 
Last edited by a moderator:

tshuck

Joined Oct 18, 2012
3,534
Your comments don't follow what you are doing.

You've set the ADC to use the RC oscillator, not Fosc/8. Also, your first subroutine gets channel 0, but your next one gets channel 3 (may, or may not, be intentional, but your comments don't show what you want to do)...
 

Thread Starter

oronning

Joined Aug 1, 2013
5
Your comments don't follow what you are doing.

You've set the ADC to use the RC oscillator, not Fosc/8. Also, your first subroutine gets channel 0, but your next one gets channel 3 (may, or may not, be intentional, but your comments don't show what you want to do)...
I have borrowed code form other programs so all comment is not right, I now. is it right now? 10 insted of 11
movlw B'10000001' ;Fosc/16 [7-6], A/D ch0 [5-3], a/d on [0]
movwf ADCon0


jes I use channel 0 and channel 3. channel is not the same as ports?:confused:

endstate. I need the pic to read in two analog inputs. (0-5v) from two potmeters. and these to values is read into two registers (AA and BB)
 
Last edited:

tshuck

Joined Oct 18, 2012
3,534
Given your level of confusion, I'd suggest you go through the link mitko89 gave, it will help you understand what you are doing, instead of relying on Frankencode...

No, your value is wrong, putting 0b10000001 into ADCON0 will give you Fosc/32. You want 0b01000001 to set it to Fosc/8 and AN0, and 0b01011001 to read from AN3.

An analog channel is not a port. A port on the PIC is a bi--directional register (or two) that, depending on its configuration, may be multiplexed to access the external pins, but you probably aren't ready to hear that yet...
 

Thread Starter

oronning

Joined Aug 1, 2013
5
I have a 20MHz frequency on my board, so I did not see the Difference
between 10 or 11 which is 20MHz crystal or frequency, that said I have borrowed program lines and dishes in the order that they will fit my circuit, as I did not want Fosc / 8 but Fosc/32, but that said, commentaries, I have not any corrected.

I have read through this link before,

but is it the frekensen settings that makes me unable reading in the from two channels (ports AN0 AN1 example) at the same time.
I plugged into one potentiometer and no problem. It reads from ADRESH and laid over into the registry. but when I run the subroutine to read from two channels, both potmeters affect the same register.

********* movf ADRESH, W; write A / D result two PORTB
********* movwf BB; Register
********* movwf ;PORTB LEDs
this is from one subroutine and both potentiometers affect this register.
but it only results from one of the subroutine that writes to PORTB

so a port is a digital in/out and the pins om PORTA it not called a port when it programed to be used to ADC then its called a channel. for me it sounded like it was not the same physical space on my board.
 

tshuck

Joined Oct 18, 2012
3,534
Page 131 in the datasheet explains the use of the internal RC oscillator for the ADC and that it should not be used for any Fosc over 1MHz...

Table 11-1 suggests you are exceeding the Tad requirements. It looks like using a 20MHz clock restricts you to using either Fosc/32 or Fosc/64 for the ADC clock.

You are only writing to port B as your output for the result on AN3. Subroutine ad_porta0 only saves the result from converting AN0 to a register.

Perhaps, regarding the port vs. channel) what I said is a bit misleading. As far as the ADC is concerned, you are reading the channel, which is part of the port (in the sense that the collection of pins is PortA)
 

Thread Starter

oronning

Joined Aug 1, 2013
5
You are only writing to port B as your output for the result on AN3. Subroutine ad_porta0 only saves the result from converting AN0 to a register.
this is a small part of the program I use, registers AA and BB are being used on calculation. that part of my program is working, it is the ADC party that does not work. writing to PORTB is only to see that things are being read correctly,

Operation ADCS2:ADCS1:ADCS0
64 TOSC 110 20 MHz

ADCS2 is not in ADCON0 how can I get 64 TOSC then?
 

tshuck

Joined Oct 18, 2012
3,534
The table you are getting that from specifically states that ADCS2 is located in ADCON1. It is bit 6.

How have you narrowed your problems down to be the ADC?
 
Last edited:

absf

Joined Dec 29, 2010
1,968
Oops! I was reading the old datasheet DS30292C. I just downloaded the new datasheet DS39582B and see the differences now...

Thanks.

Allen
 

Thread Starter

oronning

Joined Aug 1, 2013
5
ad_porta0

movlw B'01000001' ;Fosc/16 [7-6], A/D ch0 [5-3], a/d on [0]
movwf ADCon0
call delay ;delay ca 6,6us
bsf ADCon0,GO ;Start A/D conversion

btfsc ADCon0,GO ;Wait for conversion to complete
goto $ -1

movf ADRESH,W ;write A/D result to register
movwf AA ;register
movwf PORTB ;LEDs

return
I put in a 6.6us delay after setting the port. now it works fine.
 
Top