| « Time | S vs C » |
It is often very useful to create a digital representation of an analog signal. The primary way we do this is through a analog to digital conversion. This is done by comparing Vin with a reference voltage (Vref) and converting their ratios to a binary number.
Fortunately for us the PIC microcontroller has analog to digital converters built into the hardware. Doing an analog to digital conversion does take time however, but it is an extremely valuable resource. We often use analog to digital conversions for sensor applications, or anything where voltage varies with conditions.
Doing an A2D conversion
As with everything in the PIC, the first thing we have to do is enable the hardware and then set up the port to do an A2D conversion.
The registers:
ADCON0: (bank 0) Stores the config information for the A2D module
ADCON1: (bank 1) Sets the clock for the A2D conversion
ANSEL: (bank 2) Determines whether a port is digital or analog, for A2D we obviously want whatever port were using to be analog
ADRESH: (bank 0 ) Results of conversion are here.
The Code:
#include
__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
org 0 ; Beginning of code
DISPLAY equ 0x22 ; DISPLAY var stored at General purpose register 0x22
PORTS:
bsf STATUS,RP0 ; select BANK 1
movlw 0x00 ; Move the hex value of 0 to multipurpose register W
movwf TRISC ; make IO PortC all output
movlw 0xff ; Move the hex value of FF(255) to multipurpose register W
movwf TRISA ; Make PortA all inputs
movlw 0x10
movwf ADCON1 ;set A2d Clock to FOSC/32
bcf STATUS,RP0 ;Exit bank 1
bsf STATUS,RP1 ; BANK 2
movlw 0xff
movwf ANSEL ; Set PortA for all analog
bcf STATUS,RP1 ; Exit bank 2, Enter bank 0
movlw 0x01
movwf ADCON0 ; Configure ADCON and turn it on {Left just, VDD=VREF, RA0,A2D ON}
clrf DISPLAY ; Clear Display Var
MAIN:
call A2D ; Call subroutine
movf DISPLAY,w ; Move Display to w
movwf PORTC ; Move W to portC
goto MAIN ; Return to main
A2D:
nop
nop
nop
nop
nop ; wait 5 uS
bsf ADCON0,GO ; Start the conversion
btfss ADCON0,GO ; Bit will stay high until conversion is complete
goto $-1 ; Until then keep going back
movf ADRESH,w ; Move result to w
movwf DISPLAY ;Then w to Display
return
end
The Breakdown:
Most of the code is fairly straight forward, we set up the A2D module in the ports routine and then we do a conversion on RA0 and display the results on PORTC.
movlw 0x10 movwf ADCON1 ;set A2d Clock to FOSC/32
These lines move a literal into ADCON1, ADCON1 is the register for the clock of the conversion module, this one sets the time to the oscillator by 32, which is fairly slow. The higher the impedance of your input, the longer you should let the conversion take. The longer the clock, the more data you acquire and the more accurate your results are. However set this to what best fits your application
movlw 0xff movwf ANSEL ; Set PortA for all analog
This merely tells the PIC to set porta up for analog signals, if you’re doing a purely digital circuit it’s wise to set these low
movlw 0x01
movwf ADCON0 ; Configure ADCON and turn it on {Left just, VDD=VREF, RA0,A2D ON}
ADCON0 is the configuration register of the A2D module, here you set the VREF source, how the data is outputted, and what port to run the conversion on and weather to start or stop the conversion. The datasheet explains what each bit does. This setup, we have our data left justified (A2D is a 10 bit operation, bit we only want 8, so we have the data start with the first 8 bits rather than the first 2), Our VREF is VDD, channel 000 is set (ra0) and we turned the module on.
A2D:
nop
nop
nop
nop
nop ; wait 5 uS
bsf ADCON0,GO ; Start the conversion
btfss ADCON0,GO ; Bit will stay high until conversion is complete
goto $-1 ; Until then keep going back
movf ADRESH,w ; Move result to w
movwf DISPLAY ;Then w to Display
This is the main A2D subroutine. The module works by charging an internal capacitor; this takes time to charge so it’s always good practice to kill some time before the conversion starts. Once you set the ADCON0 GO bit high the conversion starts. After the conversion finishes the bit will go low, so we continue to poll that bit until it does so, and then we move the contents of ADRESH to wherever we want. In this case we move it to DISPLAY.
There we have it, a basic Analog to digital conversion. It is worth your time to check out the chapter on A2D conversion in the PIC hand guide. Good luck on your future code, the source and compiled hex are located below