Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

pic16f676 ADC problem

Status
Not open for further replies.

Noman Yousaf

Full Member level 4
Joined
Nov 19, 2003
Messages
208
Helped
3
Reputation
6
Reaction score
2
Trophy points
1,298
Location
Lahore Pakistan
Activity points
1,763
i m using 16F676 for ADC output on porta.
the problems are:
1: result is not stable even selected input is on 0V (ground). it gives 1's and 0's on porta.

system is:
i m using internal MCLR, and oscillator. Vref is VDD. and i m geting only lsb byte on the PORTA.
the program is as follows.




Code ASM - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;THIS IS THE SOFTWARE OF adc 
 
#include "P16F676.INC"
 
 
                        BSF                     STATUS,RP0
                        CLRF                   TRISA
                        MOVLW           3FH
                        MOVWF           TRISC
                        BCF                     STATUS,RP0
                        MOVLW           B'10011001'
                        MOVWF           ADCON0
 
                        BSF                     STATUS,RP0
                        MOVLW           B'00110000'
                        MOVWF           ADCON1
                        
                        MOVLW           B'01000000'
                        MOVWF           ANSEL
                        BCF                     STATUS,RP0
 
                        
                                
MAIN    
                        CALL    DELAY
                        CALL    READ_ADC
                        GOTO    MAIN
                        
DELAY
                        BCF                     STATUS,RP0
                        MOVLW           0FFH
                        MOVWF           20H
DL2                     
                        MOVLW           0FFH
                        MOVWF           21H
DL1
                        DECFSZ          21H
 
                        GOTO            DL1
                        
                        DECFSZ          20H
                        GOTO            DL2
                        BSF                     STATUS,RP0
                        RETURN
                        
READ_ADC
                        BCF                     STATUS,RP0
                        BSF                     ADCON0,1
R_AD                    
                        BTFSC           ADCON0,GO
                        GOTO            R_AD
 
                        BSF                     STATUS,RP0
                        MOVFW           ADRESL
                        
                        BCF                     STATUS,RP0
                        MOVWF           PORTA
                        
 
                        RETURN          
 
 
                        END
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


plz check is there any mistake in it or not
 
Last edited by a moderator:

i m using 16F676 for ADC output on porta.
the problems are:
1: result is not stable even selected input is on 0V (ground). it gives 1's and 0's on porta.

system is:
i m using internal MCLR, and oscillator. Vref is VDD. and i m geting only lsb byte on the PORTA.
the program is as follows.



plz check is there any mistake in it or not


Hi,

Were did you get that code from - its a very poor example, no Configurations code shown, no comments, using direct addressing - horrible !

First have to ask are you using any configuration bits in your code ?

Are you simulating it or running it on hardware ?

What Pin are you using for the ADC input ? its coded for RC2

What oscillator frequency are you wanting to use ?

Apart from 0v what is the signal /voltage you are wanting to read in ?

Only the ADRESL is displayed because that all it programmed to do, to display the ADRESH 2 bits you need to tell it to display it.

Give us some answers and possibly a diagram or link to the original code.

---------- Post added at 17:04 ---------- Previous post was at 16:08 ----------

Hi ,

Here is some 'proper' adc code which was for a pic16f88 which I have modified for the pic16F676 and ran ok in simulation.
You can see it is full of comments about what is happening and how it certain values are calculated

Note that it only displays the low 6 bits of the adc results on port C, you will have to change things to see the other 4 bits of the result on either PortC again or at the same time on PortA



Code:
;*************************************
; Author  : Mike Baird
; Program : ADC Example, Takes ADC result from AN0 and display LSB on PORTB
; Date    : September 7th, 2009
;*************************************
 
 
	List	P=16F676
	#include	"P16F676.INC"

	__CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT

;*** Cblock ***
 
	CBLOCK	0x20		 
	d1
	d2
	ADCLOW
	ADCHIGH
	ENDC
 
;*** START OF RAM ***
	ORG	0x000							; Start of program vector
	GOTO	Start						;
	ORG	0x004							; Interrupt vector
 
;*** ISR ***
	RETFIE
 
;*** Configuration ***
 
Start
	CLRF	PORTA						; PortA all low
	CLRF	PORTC						; PortB all low
 
	BSF		STATUS,RP0					; Bank 1

;	MOVLW	b'01100000'					; Make clock 4Mhz  ;  FIXED ON 16F6767
;	IORWF	OSCCON	

	MOVLW	b'00100001'					; Bit 5 input, Bit 0 for ADC
	MOVWF	TRISA						; PortA all output except MCLR
	CLRF	TRISC						; PortB all output
 
	MOVLW	b'00000001'					; Set RA0 as analog input
	MOVWF	ANSEL						;
 
	MOVLW	b'00110000'					; FOR 16F676 ONLY
	MOVWF	ADCON1						;
 
	BCF		STATUS,RP0					; Bank 0
 
	MOVLW	b'10000001'					; FOR 16F676 ONLY
	MOVWF	ADCON0						; 
 
;***
 
Main:
	CALL 	Delay1ms					; Wait MUCH longer then required aquasition time, see below for time
	BSF		ADCON0,GO
 
	BTFSC	ADCON0,GO					; Wait for conversion to be complete
	GOTO	$-1							;
	BCF		PIR1,ADIF
 
	CALL	ADCMOVE
 
	MOVF 	ADCLOW,W					;
	MOVWF	PORTC						;
 
	CALL 	Delay
 
	GOTO 	Main						;	
 
 
ADCMOVE:
	MOVF	ADRESH,W					;
	MOVWF	ADCHIGH						; 
	BSF		STATUS,RP0					; Bank 1
	MOVF	ADRESL,W					;
	BCF		STATUS,RP0					; Bank 0
	MOVWF	ADCLOW						;
 
	RETURN
 
;*** Delay ***
Delay1ms	
	MOVLW	d'6'    ; 1 Ms Delay  (924 uS)
	MOVWF d2
Delay	
	DECFSZ	d1,F
	GOTO	Delay
	DECFSZ	d2,F
	GOTO	Delay
	RETURN
 
;********************
 
	END
 
; That's all folks!
 
 ; IMPORTANT  - THE COMMENTS BELOW REFER TO THE 16F88 CHIP, THE CODE ABOVE IS MODIFIED FOR THE 
; 16F676 AND SOME PARAMETERS ARE LOCATED IN DIFFERENT REGISTERS - ADCON1 AND ANCON0
 
;*************************************************************************************
;
; Note: On a Power-on Reset, the pins PORTA<4:0> are configured as analog
; inputs and read as ‘0’.
;
;
;	ANSEL: ANALOG SELECT REGISTER(ADDRESS 9Bh) PIC16F88 DEVICES ONLY
;
;	Bit7 =  Unimplemented: Read as ‘0’
;	Bit 6:0 = ANS<6:0> Analog Input Select bits
;	
;		Bits select input function on corresponding AN<6:0> pins.
;		1 = Analog I/O(1,2)
;		0 = Digital I/O
;
;	Note 1: Setting a pin to an analog input disables the digital input buffer. The corresponding
;	TRIS bit should be set to input mode when using pins as analog inputs. Only AN2 is
;	an analog I/O, all other ANx pins are analog inputs.
;	2: See the block diagrams for the analog I/O pins to see how ANSEL interacts with the
;	CHS bits of the ADCON0 register.
;
;
;	ADCON0: A/D CONTROL REGISTER (ADDRESS 1Fh)   b'00000001'
;
;	bit 7-6 ADCS<1:0>: A/D Conversion Clock Select bits
;
;		If ADCS2 = 0:
;		00 = FOSC/2
;		01 = FOSC/8
;		10 = FOSC/32
;		11 = FRC (clock derived from the internal A/D module RC oscillator)
;		If ADCS2 = 1:
;		00 = FOSC/4
;		01 = FOSC/16
;		10 = FOSC/64
;		11 = FRC (clock derived from the internal A/D module RC oscillator)
;
;	bit 5-3 CHS<2:0>: Analog Channel Select bits
;
;		000 = Channel 0 (RA0/AN0)
;		001 = Channel 1 (RA1/AN1)
;		010 = Channel 2 (RA2/AN2)
;		011 = Channel 3 (RA3/AN3)
;		100 = Channel 4 (RA4/AN4)
;		101 = Channel 5 (RB6/AN5)
;		110 = Channel 6 (RB7/AN6)
;
;	bit 2 GO/DONE: A/D Conversion Status bit
;		
;		If ADON = 1:
;		1 = A/D conversion in progress (setting this bit starts the A/D conversion)
;		0 = A/D conversion not in progress (this bit is automatically cleared by hardware when the A/D
;		conversion is complete)
;	
;	bit 1 Unimplemented: Read as ‘0’
;	bit 0 ADON: A/D On bit
;
;		1 = A/D converter module is operating
;		0 = A/D converter module is shut off and consumes no operating current
;
;
;	ADCON1: A/D CONTROL REGISTER 1 (ADDRESS 9Fh)PIC16F88 DEVICES ONLY
;
; 
;	bit 7 ADFM: A/D Result Format Select bit
;
;		1 = Right justified. Six Most Significant bits of ADRESH are read as ‘0’.
;		0 = Left justified. Six Least Significant bits of ADRESL are read as ‘0’.
;
;	bit 6 ADCS2: A/D Clock Divide by 2 Select bit
;
;		1 = A/D clock source is divided by 2 when system clock is used
;		0 = Disabled
;
;	bit 5-4 VCFG<1:0>: A/D Voltage Reference Configuration bits
;
;		Logic State VREF+ VREF-
;		00 AVDD AVSS
;		01 AVDD VREF-
;		10 VREF+ AVSS
;		11 VREF+ VREF
;		Note: The ANSEL bits for AN3 and AN2 inputs must be configured as analog inputs for the
;		VREF+ and VREF- external pins to be used.
;
;	bit 3-0 Unimplemented: Read as ‘0’
;
;
;	These steps should be followed for doing an A/D conversion:
;	
;	1. Configure the A/D module:
;		• Configure analog/digital I/O (ANSEL)
;		• Configure voltage reference (ADCON1)
;		• Select A/D input channel (ADCON0)
;		• Select A/D conversion clock (ADCON0)
;		• Turn on A/D module (ADCON0)
;	
;	2. Configure A/D interrupt (if desired):
;		• Clear ADIF bit
;		• Set ADIE bit
;		• SET PEIE bit
;		• Set GIE bit
;
;	3. Wait the required acquisition time.
;
;	4. Start conversion:
;		• Set GO/DONE bit (ADCON0)
;
;	5. Wait for A/D conversion to complete, by either:
;		• Polling for the GO/DONE bit to be cleared
;		(with interrupts disabled); OR
;		• Waiting for the A/D interrupt
;
;	6. Read A/D Result register pair (ADRESH:ADRESL), clear bit ADIF if required.
;
;	7. For next conversion, go to step 1 or step 2 as required. The A/D conversion time per bit is
;	defined as TAD. A minimum wait of 2 TAD is required before the next acquisition starts.
;
;
;	EQUATION 12-1: ACQUISITION TIME
;
;	TACQ = Amplifier Settling Time + Hold Capacitor Charging Time + Temperature Coefficient
;        = TAMP + TC + TCOFF
;	     = 2 µs + TC + [(Temperature -25°C)(0.05 µs/°C)]
;	TC   = CHOLD (RIC + RSS + RS) ln(1/2047)
;	     = -120 pF (1 kO + 7 kO + 10 kO) In(0.0004885)
;	     = 16.47 µs
;   	 = 2 µs + 16.47 µs + [(50°C – 25°C)(0.05 µs/°C)
;	TACQ = 19.72 µs
;
 

wp100
thanks a lot. but even your sent code, there is a problem. output is not stable even i give 0V on input. it must be on 0 every output bit when it is supplied 0 on input but this is not doing that.

---------- Post added at 17:57 ---------- Previous post was at 17:33 ----------

yes i got that. actually your and mine both codes are ok. output is not stable because of input was not completely "0".
when i made it 0, it got stable.
 

wp100
thanks a lot. but even your sent code, there is a problem. output is not stable even i give 0V on input. it must be on 0 every output bit when it is supplied 0 on input but this is not doing that.

---------- Post added at 17:57 ---------- Previous post was at 17:33 ----------

yes i got that. actually your and mine both codes are ok. output is not stable because of input was not completely "0".
when i made it 0, it got stable.


Hi,

If you get a steady result with the input connected to 0v thats a start.

The next thing to do is test it with the adc input connected to +5v, perhaps though a 1K resistor to avoid and chance of a short.

That should give an adc result of 0x3F, though you may find the last few bits 0-2 of the result may 'jitter' a little from one reading to the next, thats normal.
Also while testing do a delay of at least 250ms so you can 'see' the leds changing more clearly

If thats ok, then connect a 10k pot or trimmer to the adc input with the pots connections to +5v and 0v and the slider to the ADC.
As you turn the pot slowly you should see the result change on your leds.

If things are still very unstable, then post a diagram of your hardware incase the problem is there..
 

I m beginner in pic. In 16f676 i tried to set the porta by the following code but only porta,4 and porta,5 go to 1 not porta,0,1,2. Please correct the code. Or tel the reason. I m working on mplab



Code ASM - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
bsf                     status,rp0            ;bank1
                        clrf                    trisa
                        
                        bcf                     status,rp0                ;bank0
                        clrf            porta
                        clrf            portc
 
                        
                        bsf                     porta,0                        ;make porta,0, hi
                        bsf                     porta,1
                        bsf                     porta,2
        
                        bsf                     porta,4
                        bsf                     porta,5
                        
 
 
main
                        
                        goto            main



---------- Post added at 18:07 ---------- Previous post was at 18:00 ----------

HAY WP100
CAN U CHAT ME PLZ. IF U R ON FB, PLZ ADD ME, THEN WE CAN CHAT EASILY. MY ID IS alirehan40@gmail.com
 
Last edited by a moderator:

HAY WP100
CAN U CHAT ME PLZ. IF U R ON FB, PLZ ADD ME, THEN WE CAN CHAT EASILY. MY ID IS alirehan40@gmail.com

Sorry, nothing personal , but I can only reply though the EDA forum.


Re your code example, if you see the 676 datasheet, section I/O Ports it shows how to intialise them.
Many of the pins are multifunction, so you have to set them up for what you need.

Most of the port pins power up in Analogue Input mode, so you must change the ones you need to Digital with the ANSEL instruction.
Also the comparators need to be turned off the CMCON.
RA3 can only be used as Mlcre or Digital Input


You did not say if you got any further with that ADC code I sent, nor have you sent a circuit diagram ?

I am sure it is much better if you start with doing your own code then you will soon progress to more interesting things.

These two turorials should help you do a ' flashing led'

http://www.winpicprog.co.uk/pic_tutorial.htm
**broken link removed**


Just to get you going here is a bit of code that uses PORTA for INPUT and PORTC for outputs.
Its important you use all the code show, otherwise not everything will work.
(Have only been able to get some of PortA to act as Outputs, must be missing something, so just use PortC)

Code:
	List	P=16F676
	#include	"P16F676.INC"

	__CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT


;*** Cblock ***      SPECIFY YOUR 'USER REGISTERS HERE
 
	CBLOCK	0x20		 
	d1
	d2
	ENDC
 

	ORG	0x000							; Start of program vector
	GOTO	Start						;

 

 
Start

										; SET UP PORTS
	banksel PORTA

	CLRF	PORTA						; PortA all low
	CLRF	PORTC						; PortB all low
	
	MOVLW	0x05
	MOVWF	CMCON

	banksel ANSEL						; Bank 1

	MOVLW	b'00000000'					; Set ALL PORTS TO DIGITAL
	MOVWF	ANSEL

	CLRF VRCON

	MOVLW	b'11111111'					; make PortA OUTPUTS exect RA3 as input
	MOVWF	TRISA						; PortA all output 
	CLRF	TRISC						; PortB all output
 
 	Banksel 0							; Bank 0

	
;  your program code goes here



	BSF	PORTC,0
	BSF	PORTC,1
	BSF	PORTC,2
	BSF   PORTC,3
	BSF	PORTC,4
	BSF	PORTC,5

loop goto loop
 
	END
 

Hi,

Hope you are still following the forum/ thread.

Regarding the code I posted last night, have now found out why PortA would not work properly as Outputs.

The datasheet has an Error , to turn off the Comparator function its states you need to load CMCON with 0x05, it should be 0x07.

Have attached the code that uses this and it now uses all the Ports as Outputs apart from RA3 with can only be an Input.


You can build the code in MPLAB and use the Debugger, SIM and step though the code and Watch it turn on each bit of PortA and C



Code:
	List	P=16F676
	#include	"P16F676.INC"

	__CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT


;*** Cblock ***      SPECIFY YOUR 'USER REGISTERS HERE
 
	CBLOCK	0x20		 
	d1
	d2
	ENDC
 

	ORG		0x000						; Start of program vector
	GOTO	Start						;

 
Start									; SET UP PORTS
									
	banksel PORTA

	CLRF	PORTA						; PortA all low
	CLRF	PORTC						; PortC all low
	
	MOVLW	0x07						; Turn off Comparators USING 0x07  - NOT 0x05 AS SHOWN IN THE DATASHEET
	MOVWF	CMCON

	banksel ANSEL						; Bank 1

	MOVLW	b'00000000'					; Set ALL PORTS TO DIGITAL
	MOVWF	ANSEL

	MOVLW	b'00001000'					; make PortA OUTPUTS exect RA3 as input only
	MOVWF	TRISA						; PortA all output 
	CLRF	TRISC						; PortC all output
 
 	Banksel 0							; Bank 0

	
;  your program code goes here


	BSF	PORTA,0							; turn on portA, except RA3 - Input only
	BSF	PORTA,1
	BSF	PORTA,2
	BSF	PORTA,4
	BSF	PORTA,5

	BSF	PORTC,0
	BSF	PORTC,1
	BSF	PORTC,2
	BSF portC,3
	BSF	PORTC,4
	BSF	PORTC,5

loop goto loop
 
	END
 

Attachments

  • ScreenShot001.jpg
    ScreenShot001.jpg
    75.3 KB · Views: 79

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top