Frustrating Problem with 2 A/D conversion

For C and ASSEMBLY users to post questions and code snippets for programming in C and ASSEMBLY. And for any other C or ASM course related questions.

Moderators: Benj, Mods

Post Reply
David Halliday
Posts: 9
Joined: Tue Jan 10, 2006 4:36 pm
Location: Hampshire
Contact:

Frustrating Problem with 2 A/D conversion

Post by David Halliday »

Hi me again ! :?

I've been learning about how to use the a/d ports on a 16F877A . I have enabled the analog ports and have put two power supply (0-5V) on RA0 and RA1 . The result of the A/D conversion has then been placed upon a 2 Line lcd display. But for some reason when you adjust RA0 it also adjust RA1 and vice versa. They never seems to be two independant readings . I have a 10K resistor to ground on each port and a 1k resistor upon the incoming voltage but can'nt get them to work as two independant channels.


Heres my the code

Code: Select all

#include <system.h>

unsigned char ADCRESL@0x9e;  // control reg for A/D
unsigned char ADCRESH@0x1e;

char display1_value (int value,int position) // value of a/d result and position																	
{																															
																				
 unsigned char hunds, tens, units; 																							
																				
    //  first get the digits  													
																				
		units = value % 100 ;														
		hunds = value / 100 ;					 
       tens =  units / 10 ;															
		units = units % 10 ;													
																				
																				
     // now display them 
    if(portd==00000110b)// if press closed and RF ON 
	{
    lcd_cursor(position,1);// Compacting numbers for more space on screen														//
    lcd_print_ch ( '0' + hunds ) ;												
    lcd_print_ch ( '0' + tens ) ;												
    lcd_print_ch ( '0' + units ) ;
    }
    else
    {
    lcd_cursor(5,1);
    lcd_print (clear) ;												
	}
}				


int read_adc0 (char adcon_0 ) // Main A/D conversion sub

{

   unsigned char h, l =0;
   int result=0;
    
	adcon0 = adcon_0;  /* enable the converter and start    */
	  
	while ( adcon0 & 0x04 );//spin while the conversion runs  
	
	h = ADCRESH;
	l = ADCRESL;
	
	//m movwf _l_read_adc0;
	result = (256 * h) + l; // Add high byte-to-low 
	return result;
}



		
char ad_Channel_0() //Channel_0 of A/D PORT RA0   Set for forward power readback
{

int CH0_adcon0=0x05;
int result=0;
   
result= read_adc0(CH0_adcon0);// Send A/D channel for  conversio and get result 
display1_value(result,5);    // Send a/d result and where to place upon the screen
}
   	
	

char ad_Channel_1 () //Channel_0 of A/D PORT RA1   Set for reflected power readback
{

int CH1_adcon0=0x0d;  
int result=0;   
        	
result= read_adc0(CH1_adcon0);// Send A/D channel for  conversio and get result 
display1_value(result,13); // Send a/d result TO LCD display and position on screen
}			


			
Can any body help because I'm cunfused I've tried adding delay but it seem to make no difference ?

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Post by Benj »

Hi David

Im pretty sure your problem is that you have to wait a small time between reading your first ADC value and starting the next ADC process. There is only one ADC module onboard the PIC devices and this is multiplexed between all of the analogue input pins. The ADC module has a capacitor which takes a certain amount of time to charge up and discharge. This is the reason for your analogue signals affecting each other. All you need to do to fix this problem is to switch the ADC channel to the one you want to sample, Wait a TAD amount of time for the capacitor to charge/discharge (Refer to datasheet) And then start the conversion process.

For egsample your code would now look like this

Code: Select all

int read_adc0 (char adcon_0 ) // Main A/D conversion sub 
{ 

   unsigned char h, l =0; 
   int result=0; 
    
   adcon0 = adcon_0 & 0xFb;  /* Switch ADC channel*/ 
   
   delay(TAD)  //Need to look up TAD on the datasheet or just wait a ms or two

   adcon0 = adcon0 + 0x04;  //start conversion

   while ( adcon0 & 0x04 );//spin while the conversion runs  
    
   h = ADCRESH; 
   l = ADCRESL; 
    
   //m movwf _l_read_adc0; 
   result = (256 * h) + l; // Add high byte-to-low 
   return result; 
} 


void delay (int inst_count)
{
   int i;
   for (i=0;i<inst_count;i++){};
}

David Halliday
Posts: 9
Joined: Tue Jan 10, 2006 4:36 pm
Location: Hampshire
Contact:

Problem resolved

Post by David Halliday »

Hi Ben

Just to let you know Ive added the adjustment to the code and now it works perfectly.

Thankyou Thankyou Dave :D

Post Reply