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.

PIC16F877 ADC Problem All values the same

Status
Not open for further replies.

Theodoros

New Member
Hello
I am trying to read two analogue values and I’m getting the same values for both. One channel is connected to a differential input instrumentation amplifier and the other directly to a humidity sensor. Independently the channels work. If I connect only one of the two the readings are fine. The program works fine when simulated with proteus. What might be the problem? Are there any special precautions that need to be made, what should happen to the unconnected channels?

I appreciate any help.
 
It could depend on how you have your channels initialized. There are settings to make some digital, some analog, and some as references. Perhaps you have accidentally assigned one of your pins as a reference, so the other pin that is not being used is mirroring the signal on this reference. Copy and paste your initialization code so we can see it, and be sure to use the Code tag button in the reply controls so it is formatted properly and easy to read.
 
Thank fo your reply, but I don't think it's a problem with the voltage reference. ADCON1=0x80 so everything is analogue and right justified. The code is the a2demo sample with some modifications.

Here is the code. I can disassemble it but it would be a mess ( i presume).

Code:
#include <stdio.h>
#include <pic.h>
#include "usart.h"

void init_a2d(void){
	ADCON1=0x80;	// select right justify result.
	ADCON0=0;	// select Fosc/2
	ADON=1;		// turn on the A2D conversion module
}

short read_a2d(unsigned char channel){
	channel&=0x07;	// truncate channel to 3 bits
	ADCON0&=0xC5;	// clear current channel select
	ADCON0|=(channel<<3);	// apply the new channel select
	ADGO=1;	// initiate conversion on the selected channel
	while(ADGO)continue;
	return((ADRESH<<8)+(ADRESL));	// return the result
}

void main(void){
    unsigned char input;
	int a,b,c;
    float an;

	init_a2d();	// initialise the A2D module
	init_comms();	// set up the USART - settings defined in usart.h
	
	for(;;){
       	for(a=0;a<300;a++){
		for(c=0;c<500;c++){}}
		for(b=0;b<8;b++){
       		for(a=0;a<300;a++){
			for(c=0;c<500;c++){}}
			an=read_a2d(b);
		    an=5*an/1023;
			printf("%1.2f   %d  ",an,b);}

			printf("\r \n");
	}
}
 
I should have specified it is written in HI-TECH PICC.
Is the problem most probably due to software or hardware?

Thanks
 
There should be a short delay inserted from the time a channel is selected to the time A/D conversion is started (ADGO=1). This is the acquisition time.

You're using a 1.25 mhz crystal (Fosc/2)?
 
Hi Theodoros

forgive me if I'm not very familiar with C. In your code you set the GO/DONE bit immediately after applying the new channel select, take a look at the Microchip datasheet, PIC16F87X page 114, there is an acquisition time requirement, so that I think you're reading the previous value left on the integrating capacitor.

Best of Luck

Ed
 
Thanks motion and EdwardM indeed I just had to include a small delay for the acquisition time requirement. Now i get the correct values. Thanks all of you for the time you spend and for promptly answering my question.

Thanks again. This forum rocks.
 
Couldnt you store your previous acquisition , instead of just having the processor do nothing but loop in a delay..??
 
williB said:
Couldnt you store your previous acquisition , instead of just having the processor do nothing but loop in a delay..??

By properly sequencing the tasks performed by the PIC, you can minimize wasted time in delay loops. For example, shortly after initiating A/D conversion, the next channel can be selected. This is because the analog multiplexer is automatically disconnected from the sample and hold capacitor during A/D conversion.

While A/D conversion is taking place, digital processing of the previously converted data can be done. Since the A/D conversion time is equal to about 1.6usec X 12 = 19.2usec and the acquisition time is another 19.7usec, the total time allowed for other tasks is about 40usec without slowing down the A/D conversion rate. Using a 20Mhz clock, that is 200 single instruction steps, plenty of code IMHO.
 
As a bit more info about this, it's due to the fact that you're swirching channels!. The A2D in the PIC has a sample and hold, which charges a capacitor - this takes time to charge to the new value when you switch channels.

In order to make it as fast as possible, you should have a low source impedance feeding the input. The MicroChip spec gives a MAXIMUM of about 2Kohm - basically the higher the source impedance, the longer you have to delay.

You need to make sure that you're waiting long enough, or your readings will be inaccurate, as the capacitor hasn't charged to the full input voltage.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top