Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Using the ADC on the PIC16F871

Status
Not open for further replies.

zach_blader

New Member
I'm looking to use the PIC16F871 to work as an ADC as it already has a sample and hold circuit contained within it. I think I have the basics in place for my programme well the idea of how to use the ADC I am just a bit unsure about the acquisition time and how I can control the sampling frequency etc.
I need to have a sampling frequency of 40Khz, so I can sample audio. I need to be able to output the 10 bit ADC conversion to the rest of my circuit also.
So far I haven't written any code but my ideas are;

In ADCON1 Register, Set the bits 0-3 as 1110, (To give 7 digital I/O and 1 Analog Input)
In ADCON0 Register, Set the bits 3-5 as 000, (To select RA0/AN0 as the analog input)
I then need to select the A/D Conversion clock which I am unsure about.
In ADCON0 Register, Set bit 0 to 1, (To turn on the module)
Then I could use the A/D interrupt feature but I don't understand this.
Wait the required Acquisition Time given as 19.72us in the data-sheet
In ADCON0 Register, Set bit 2 to logic 1, (Start the conversion)
In ADCON0 Register, Test bit 2 for a logic 0, (Conversion complete)
Read A/D Result register pair (ADRESH:ADRESL)
Return To the beginning
Wait at least 2TAD (2 x Time to convert 1 bit)

This could be horrifically wrong, I am new to PIC programming and tried to follow the data-sheet but there were a few things I couldn't get my head around.
As if I have to wait 19.72us for the acquisition time, It doesn't leave a lot of time for the conversion and everything before the next sample. Because at 40Khz each sample is at 25us. So how do i set the sampling clock and the conversion clock in the PIC?? Thanks if anyone can shed any light onto my situation.
Many Thanks
P.s sorry if I am being stupid and have missed something completely obvious
 
You need to run your PIC at > 4 MHz in order for it to have time to do all it has to do.

You're jumping in the deep end with this project if you don't have much PIC experience.

Have you looked at Nigel's tutorials?

I don't recall how to set the sampling & conversion clocks.

So I'll have a look at one of my programmes after I post this and re-post if I find how to do it.

Note that it is essential to select the correct bank for each register.
 
Last edited:
This is part of my Garage Door Opener programme using a 16F88.

I expect the 16F871 is similar. I hope it helps you.

This is the initialise sub routine.

Initialise
BANKSEL CMCON ;selects BANK 1

movlw 0x07 ;see spec of the 16F88 p.121
movwf CMCON ;turn comparators off

movlw 0x03 ;see spec p.113
movwf ANSEL ;set AN0:1 as analogue inputs

bsf OSCCON,6 ;
bsf OSCCON,5 ;
bcf OSCCON,4 ;OSCCON <6:4> = 110 => 4 MHz

movlw b'11111111' ;AN1:0 Pot1, Pot2, RA3:2 up, down
movwf TRISA ;RA7:4 DL, UL, stp, opto
movlw b'00000000' ;RB7:4 Ux, Dx, led_5, enUD
movwf TRISB ;RB3:0 light, pwr, led_1, laser

movlw 0xA8 ;external TMR0, 1:1 (bit 0 = prescale WDT)
movwf OPTION_REG ;bit 7 = 1 disables PORTB pullup resistors

movlw 0x00 ;ADCON1 - bank 1: set RIGHT justification,
movwf ADCON1 ; -ref = 0V & +ref = 5V. see 16f88 spec p. 115

BANKSEL portb ;selects BANK 0

clrf portb
movlw 0x20 ;see spec page 72
movwf T1CON ;TMR1 - 1:4 prescale, internal clock

movlw 0x7E ;see spec page 80
movwf T2CON ;TMR2 on, set for 1:16 prescale & postscale

movlw 0x41 ;Fosc/8 & A/D on
movwf ADCON0 ;see spec page 114

clrf INTCON ;no interrupts
return

This is the sub routine that reads the AN inputs.

meas_pots
bcf tmr1_on ;stop TMR1

btfsc Ux ;is the door going up?
bsf ADCON0, 3 ;Yes, select AN1
btfsc Dx ;is the door going down?
bcf ADCON0, 3 ;Yes, select AN0

call delay_30u ;30 us delay
bsf ADCON0,2 ;start the A/D conversion

btfsc ADCON0,2
goto $-1 ;wait until finished

movfw ADRESH ;high byte of force Pot voltage
movwf force_H ;store high byte of force Pot voltage

BANKSEL ADRESL ;select bank 1
movfw ADRESL ;low byte of force Pot voltage
BANKSEL force_L ;select bank 0
movwf force_L ;store low byte of force Pot voltage

bcf c_bit
rrf force_H ;divide pot value by 8
rrf force_L ;the LSB bits of force_L are 0
rrf force_H
rrf force_L
rrf force_H
rrf force_L

movlw 0x63 ;0x630 = 1584 = minimum "pot value"
addwf force_H ; 101 ms pot at min, 134 ms pot at max
return
 
Hi,
The choice was just due to the fact I found it on Rapid in all honesty. Thanks very much for the help. I think I'll need to improve my PIC understanding more before I take this on I've had to change my project because the ADC and DAC conversion just wouldn't work and I don't have the time to get my head around it all. But many thanks indeed :)
 
Hi,
The choice was just due to the fact I found it on Rapid in all honesty. Thanks very much for the help. I think I'll need to improve my PIC understanding more before I take this on I've had to change my project because the ADC and DAC conversion just wouldn't work and I don't have the time to get my head around it all. But many thanks indeed :)

You're welcome.

Yes, it takes some time to understand PICs.

Nigel's tutorials are a good starting point.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top