16F877 A/D IO Sample Programs

...the ground pin next to the port A pins is used internally in a way that is much closer to the A/D converter, and is thus meant to be the analog ground.

JB says:

After trying unsucessfully to get Microchip's example code (among others) to work, I hacked out this modification which seems to do the job, at least for me. If anyone else is having as a much difficulty as I did, this may help get things going. FWIW, the remaining least-significant bits are in ADRESL but this example makes use of the most-significant 8 bits left justified into ADRESH.
;16f877 a/d test routine
;
;TEST CIRCUIT:
;pin 11 & 32 = 5VDC
;pin 12 & 31 = 0VDC
;pin 1 = 5VDC
;pin 2 = 0 - 5 VDC analog input (center tap on 20k variable resistor)
;pin 13 & 14 = 4MHz crystal with 18pF capacitors to 0VDC
;pin 15,16,17,18,23,24,25,26 PORTC outputs each to 330 ohm resistor
;       in series with LED to 0VDC
;**********************************************************

        __config _LVP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF & _BODEN_OFF
& _DEBUG_OFF
        list p=16f877

        include "p16f877.inc"

        ; Start at the reset vector
        org     0x000
        goto    Start
        org     0x004
Interrupt
        retfie
Start
        bsf     STATUS,RP0      ;bank 1
        bcf     STATUS,RP1
        movlw   H'00'
        movwf   TRISC           ;portc [7-0] outputs
        clrf    ADCON1          ;left justified, all inputs a/d
        bcf     STATUS,RP0      ;bank 0
        movlw   B'01000001'     ;Fosc/8 [7-6], A/D ch0 [5-3], a/d on [0]
        movwf   ADCON0
Main
        call    ad_portc
        goto    Main


ad_portc
                                ;wait for acquision time (20uS)
                                ;(non-critical for this test)

        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 PORTC
        movwf   PORTC           ;LEDs
        return

        end

Mark Willcox modified Tony Nixons program

;pwm.asm to learn CCP/PWM of 16f873. Last edited 5/23/2000
;Originated by Tony Nixon and modified by Mark Willcox.
;Grahm
;   This code will light a LED on portC pin RC2/CCP1 and 
;display the 8 bit hex value on portB LEDs or bargraph. The CCP1 LED
;will glow from bright to dim as the pot varies the pulse width. 
;Connect an O-scope to CCP1 and watch the PW vary. This code can be 
;used on other PICs but you will have to change the code to fit it's 
;instruction set. One wire on pot goes to +Vdd and the other end 
;of the pot goes to -Vss/ground. The wiper goes to RA0 input pin.
;You can use any input signal source as long as you don't exceed the 
;chips max specs. For example, a slow sine or ramp wave(1-5Hz) will 
;flash the CCP1 LED. Make sure you use a common ground for the 
;signal generator and PIC board.


        #include <p16F873.inc>
        LIST p=16F873
	errorlevel 1,-302	;to disable MPLAB bank warnings.
        __config _XT_OSC & _PWRTE_ON & _WDT_OFF & _LVE_OFF
		;Some versions of MPLAB use _LVP_OFF
		;This sets all portB pins to output.
;/*---------Declare Registers
STATUS	EQU	03
ADCON	EQU	08
PORTB	EQU	06
F       EQU     1
W       EQU     0
;/*---------Set up chip parameters
	CLRF	CCP1CON	;CCP MODULE IS OFF
	CLRF	TMR2	;CLEAR TIMER2
	MOVLW	0X7F	;
	MOVWF	PR2
	CALL	A2D
	CLRF	INTCON		;DISABLE INTRPTS ANDCLEAR T0IF
	BSF	STATUS,RP0
	BCF	TRISC,2		;MAKE PIN 2 PWM OUTPUT
	CLRF	PIE1		;DISABLE PERIPHERAL INTS
	BCF	STATUS,RP0
	CLRF	PIR1		;CLR PER INT FLAGS
	MOVLW	0X2C		;PWM  MODE, 2LSBs OF DUTY CYCLE=10
	MOVWF	CCP1CON
	BSF	T2CON,TMR2ON	;TIME2 STRTS TO INCREMENT
	;
	 ;CCP1 INT IS DISABLED
	 ;DO POLLING ON THE TMR2 INT FLAG BIT
	;
PWM_PERIOD_MATCH
	BTFSS	PIR1,TMR2IF
	GOTO	PWM_PERIOD_MATCH
	;
	 ;UPDATE THIS PWM PERIOD AND THE FOLLOWING PWM DUTY CYCLE
	;
	BCF	PIR1,TMR2IF
A2D     bsf     STATUS,RP0
        MOVLW   B'00000001'
        MOVWF   TRISA           ;All outputs except RA0.
        CLRF    TRISB		;RA0 is wiper of 50k pot/Vin
        CLRF    TRISC		;PortB is 8 LED output to show 
        MOVLW   B'00001110'     ;Hex value of Vin from pot.
        MOVWF   ADCON1		;left justified, RA0 = input
;/*-----Set up A2D parameters
        MOVLW   B'11010111'     ;prescaler 1:256 tmr0, internal clock
        MOVWF   OPTION_REG
        BCF     STATUS,RP0
        MOVLW   B'01000001'     ;a2d = on, ch0, fosc/8
        MOVWF   ADCON0
;/*-----Delay loop to settle A2D, similar to de-bounce???
mnloop  btfss   INTCON,T0IF     ;50us loop delay @ 4Mhz
        goto    mnloop
;/*-----Stop timer0 interrupt
        BCF     INTCON,T0IF
        BSF     ADCON0,GO_DONE  ;start a2d conversion
WAITA2D NOP                     ;wait 4 finish
        BTFSC   ADCON0,GO_DONE
        GOTO    WAITA2D
;/*-----Put A2D/PWM value in W and send to ports.
        MOVF    ADRESH,W        ;upper 8 bits-ignor lower 3
        MOVWF	CCPR1L		;PWM is output on pin 13 of 16F873
        MOVWF   PORTB		;output Hex value to LEDs
        RETURN			;DUTY CYCLE IS 25% OF PWM PERIOD
        
   END     	


See:

Questions:

Interested:

Comments: