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.

newbie in using PIC16F877

Status
Not open for further replies.

cyb3rfreak

New Member
hi to all!

i would like to ask some help from the experts in using ADC of 877. i already read the datasheet with regards on using adc but i have difficulty in understanding the details. im using PICSimulator IDE as my compiler (that uses C environment) and Proteus by simulating the program. i also search the net and forum for example but unfortunately i didn't find any that can help me. if it's not too much to ask, can somebody provide an example program that will require analog signal (e.g 0V to 5V) and will display 3-bit digital output (i.e. 3 LED). i only know how to set the pins as input but i dont know how to obtain or where to get the output from the adc.

any reply is very appreciated! thnx:)
 
Here is how I do it in BoostC,

Code:
int ReadADC(unsigned char Channel){
    adcon1=0x80;
    adcon0=0b10000001+(Channel<<CHS0);
    DelayuS(20);
    adcon0.GO=1;
    while(adcon0.GO);
    return(adresh*256+adresl);
}

Mike.
 
thnx for the reply

what ports are input and output from your program? can you explain what is the use of adresh and adresl?
 
thnx for the reply

what ports are input and output from your program? can you explain what is the use of adresh and adresl?

hi,
The ADRESH and ADRESL are the ADC output registers.

ADRESH-igh is the high byte [msb] and ADRESL-ow id the low byte [lsb]

The ADC value when set for its maximum of 10bits, loads the ADRESH with 6 leading zero's and then 2 bits of data,
the lower 8 bits are loaded into ADRESL.
That is if the ADC output has been RIGHT justified.

If LEFT justified then ADRESH holds the 8 upper bits and ADRESL has 2 data bits followed by 6 trailing zero's.

Do you follow.?
 
Last edited:
thnx for the reply ericgibbs. btw, nigel i read some adc tutorials in some site but most of them uses assembly language that is very difficult for me to comprehend.

anyway, is it necessary for the ADC to use all the 10-bit result? is it possible to only use specified number of bits (e.g 3 bits) and how to configure it..? and lastly since it is a 10bit therefore 2^10 - 1 = 1023 which gives 4.88mV of resolution of the ADC. does the 877 has the capability of changing the resolution depending on the users preference?
 
thnx for the reply ericgibbs. btw, nigel i read some adc tutorials in some site but most of them uses assembly language that is very difficult for me to comprehend.

anyway, is it necessary for the ADC to use all the 10-bit result? is it possible to only use specified number of bits (e.g 3 bits) and how to configure it..? and lastly since it is a 10bit therefore 2^10 - 1 = 1023 which gives 4.88mV of resolution of the ADC. does the 877 has the capability of changing the resolution depending on the users preference?

hi,
If you left justify the ADC and use only the ADRESH, that will be 8 bits, 0 thru 255.
Thats nice and easy.:)
 
hi,

can u help me coz im lost, i tried using adresh but im not getting the output i wanted. this is my table:
0 0 0 = 0.5V
0 0 1 = 1V
0 1 0 = 1.5V
0 1 1 = 2V
1 0 0 = 2.5V
1 0 1 = 3V
1 1 0 = 3.5V
1 1 1 = 4V

and this is my experimental code :(

TRISA = 0xff
TRISC = 0x00

ADCON1 = 0x00
ADCON0 = 0x41

Dim output As Byte

main:

ADCON0.2 = 1
output = ADRESH
WaitUs 100
PORTC = output

Goto main

my input is in RA0 that varies from 0V to 5V. i connect all the port in portC with LED and observe the output but even i only want to use 3bits, all of the ports are conducting when i vary the input.

i know there something wrong about my code and i dont know how to debug it... :(:confused:
 
hi,
I dont use 'C' programming.

Are you testing bit ADCON0 GO/DONE..?
 
Last edited:
i already visited that site and it somehow help my problem. btw, i already solved my problem with regards to my first post.. thnx for the help guys...
 
i already visited that site and it somehow help my problem. btw, i already solved my problem with regards to my first post.. thnx for the help guys...

It would help others who are following this thread, if you explained how you solved your problem.:)
 
i solve my problem by observing the output of portC and portD (RD0 and RD1) where i connect a LED in all the pins and taking note of the output it produces with this program:
-----------------------
TRISA = 0xff
TRISC = 0x00
TRISD = 0X00

ADCON1 = 0x80 'Right Justified; All Ports are Analog Input or %10000000

ADCON0 = 0x41 'set Fosc/8; channel 0; ADON = 1 or %01000001

Dim output1 As Byte
Dim output2 As Byte

main:
ADCON0.2 = 1 'start A/D conversion
output1 = ADRESL
output2 = ADRESH

WaitMs 100
PORTC = output1
PORTD = output2

Goto main
-------------------------

after obtaining the output for every varied voltage level (e.g 0V = 00000000, 0.5V = 01100110... and etc) i then edit my program and insert some lines: (this is just part but it goes for 1.5V, 2V, 2.5V, 3V, and so on.)

main:
PORTC = 0x00 'setting all the led into logic 0
ADCON0.2 = 1 'start A/D conversion
output1 = ADRESL 'store the A/D result to output
output2 = ADRESH

'0.5V
If output1 = %01100110 And output2 = %00000000 Then (i use adresh output coz 0.5V and 3V has the same digital output in adresL)
PORTC = 0x01 'to get my desired output which is 001
Endif

If output1 = %11001101 Then '1V
PORTC = 0x02 ' 010
Endif

If output1 = %00110011 Then '1.5V
PORTC = 0x03
Endif

goto main

since i dont know how to set the resolution of the 877 i simple use this approach to attain my desired output.

btw, any comment from the expert about my codes.. i know it uses more lines but this is all i can do.. :(
 
After setting the GO bit you have to wait until it goes low again or you will get an invalid result. To reduce it to 3 bits you just divide by 32.

Mike.
 
After setting the GO bit you have to wait until it goes low again or you will get an invalid result. To reduce it to 3 bits you just divide by 32.

Mike.

wtf! :eek: ok i'll try it. btw, how did you know that the result must be divided by 32 to obtain 3bits output?
 
i see, i tried dividing it and got the bits i want to use but i have a problem in testing the go/done bit and where to actually put the delay before displaying the output. i edited and added this code to test the go/done bit

check:
if adcon0.2 = 0 then
output1 = adresl / 32
goto main
else
waitus 500
goto check
endif

but the output is same as usual.. :(
 
It depends on your version of basic but normally you would do something like,
Code:
main:
    ADCON0.2 = 1	'start A/D conversion
    while(ADCON0.2=1)	'wait for it to complete
    wend
    output1 = adresl / 32
    WaitMs 100
    Goto main

You might also want to use while wend instead of the goto structure,
Code:
    while(1)
        ADCON0.2 = 1 'start A/D conversion
        while(ADCON0.2=1)
        wend
        output1 = adresl / 32
        WaitMs 100
    wend

BTW, in your first post you stated you were using C but you appear to be using Basic.

Mike.
 
i forgot to edit my first, im using picsimulator IDE with BASIC compiler. i've added and tried the program that you post..

main:
ADCON0.2 = 1 'start A/D conversion
while(ADCON0.2=1) 'wait for it to complete
wend
output1 = adresl / 32
WaitMs 100
portb = output1 <--- is this correct? coz when i didnt get the result i wanted

Goto main

btw, what does timer0/1/2 module do in 877? is this a timer that you can set in the piC? i read the datasheet but cant understand what it means :(
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top