Do you know some good tutorial about ADC with 16f88 ? I have to interface it with a Analog temperature sensor (-40 , +125 =B0C : 10mV/=B0C)
ADC with PIC16F88
Sep 27, 2005
5 Replies
C
The data sheet for the PIC16F88 tells you just about everything you=20 need to know about the A/D, except that it is very sensitive to=20 voltages outside the power supply range.
Do you need to know how to interface the temperature sensor to the=20 A/D? Since the sensor has an absolute voltage for a given=20 temperature, you may need to reference the A/D to an absolute voltage,=20 instead of using the power supply as the full scale reference. Then=20 you need to amplify the temperature signal (with an op amp, perhaps)=20 to move and expand the signal to use most of the A/D input voltage=20 range, so that you can take advantage of the 1024 levels of the A/D=20 for something like .16 degree resolution, on average (higher=20 resolution if you don't need the whole temperature range).
"John Popelish" wrote
°CSounds like the OP is using an LM34 or LM35 temp sensor. I have played with these and using a 1.024V Vref (outside the datasheet specs for min Vref I know, but it worked fine for me using a 16F88). This allowed me to have .1F resolution, but also limited the max temperature to 102.3F. I know that the proper way would have been to use a higher Vref and an op-amp to boost (double) the output of the temp sensor, but hey it was purely for grins to see if it would work.
To the OP, I have some code that will initialize the 16F88 and take a sample. I can post it if you'd like.
Thanks, if you can post your code ...
My idea is to keep the circuit very simple, so without Amplifier: i think i have a signal of about 1.7 Volt (from -40 =B0C to 125 =B0C) so with 1700mV i can detect 0.1=B0C... but how can i adjust with the 1024 levels ?
If you don't care too much about resolution you can just connect it directly to the input. With Vref=Vcc=5V you'll get about 0.5°C resolution. If you use a TL431 for the reference (the minimum datasheet value of 2.5V for full temp range operation) then that will be halved to more like 0.25°C (or +/- 0.13°C in marketingspeak).
You can easily do a bit of integer math to calculate the temperature with an arbitrary reference, it's not like it's going to change very fast.
Best regards, Spehro Pefhany
"it\'s the network..." "The Journey is the reward"
speff@interlog.com Info for manufacturers: http://www.trexon.com
Embedded software/hardware/analog Info for designers: http://www.speff.com
"merco" wrote
Here is my __CONFIG stuff:
;Program Configuration Register 1 __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB3 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_IO
;Program Configuration Register 2 __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
This is how I set up my 16F88 that does ADC as well as I2C and RS232 serial communications. You will want to check the pin directions for RA1 and RA0. I also apply an external Vref on RA3. I think that RA5 is stuck as a 1 when you use _MCLR_OFF, but I set it anyway.
bsf STATUS, RP0 ;Switch to Bank 1
movlw b'00111011' ;Define I/O on Port A (RA5 mclr input, RA4 ADC input, RA3 Vref+ input, RA1 SDA, RA0 SCL, all others outputs) movwf TRISA & 0x7F movlw b'00000101' ;Define I/O on Port B (mostly output, RB2-RX input, RB0 input) movwf TRISB & 0x7F
movlw 0x00 ;All pins digital i/o for now movwf ANSEL & 0x7F
movlw b'01110000' ;Set internal osc to 8Mhz movwf OSCCON & 0x7F
; movlw 0x07 ;Turn off the comparators (unnecessary on 16F88) ; movwf CMCON
bcf STATUS, RP0 ;Back to Bank 0
call ADC_Init
Here is code to do an analog to digital conversion.
bsf ADCON0, ADON ; Turn the ADC back on
call Wait_100mS ;Let things stabilize for a real long time
bsf ADCON0, GO_DONE ;Start a conversion _ck_conversion btfsc ADCON0, GO_DONE ;Is it done yet? goto _ck_conversion ; nope, check again
movfw ADRESH movwf CurrentTempH ; save all 10 bits as temp (precision to .1 degrees w/1.024V Vref) bsf STATUS, RP0 ;Bank 1 for lower bits movfw ADRESL & 0x7F bcf STATUS, RP0 ;Bank 0 movwf CurrentTempL
Here is the ADC_Init subroutine.
ADC_Init
bsf STATUS, RP0 ; Select BANK 1
movlw b'00011000' ; ANSEL ; |||||||+-------------- ANS0 (RA0) ; ||||||+--------------- ANS1 (RA1) ; |||||+---------------- ANS2 (RA2) ; ||||+----------------- ANS3 (RA3) Vref+ ; |||+------------------ ANS4 (RA4) AN4 ; ||+------------------- ANS5 (RB6) ; |+-------------------- ANS6 (RB7) ; +--------------------- Unused movwf ANSEL & 0x7F
movlw b'11100000' ; ADCON1 ; |||||||+-------------- Unused ; ||||||+--------------- Unused ; |||||+---------------- Unused ; ||||+----------------- Unused ; |||+------------------ VCFG0 (Vref-) ; ||+------------------- VCFG1 (Vref+) ; |+-------------------- ADCS2 ; +--------------------- ADFM (0=left, 1=right justification) movwf ADCON1 & 0x7F
bsf TRISA & 0x7F, 4 ; Make RA4 input (Temp Sensor) bsf TRISA & 0x7F, 3 ; Make RA3 input (Vref+)
bcf STATUS, RP0 ; Select BANK 0
movlw b'01100001' ; ADCON0 ; |||||||+-------------- ADON ; ||||||+--------------- Unused ; |||||+---------------- GO/DONE ; ||||+----------------- CHS0 ; |||+------------------ CHS1 ; ||+------------------- CHS2 ; |+-------------------- ADCS0 ; +--------------------- ADCS1 movwf ADCON0
return
I cut and pasted it all, so hopefully everything you need is present except for my generic time delay/waste routines.
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required