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.

Regarding multiple ADC on 16F877

Status
Not open for further replies.

tiwari.sachin

New Member
Hello

I am trying to write a code to sample 2 adc channels continuously. As of now i am displaying the values on the LCD.


when I scan one channel, all seems to work fine. but then when I am scanning two channels, change in channel0 seems to effect the channel1 reading too. Although its only channel0 that I am changing.

I am reading 10 bit value.

Help on this is really appreciated.
 
Hello

I am trying to write a code to sample 2 adc channels continuously. As of now i am displaying the values on the LCD.

when I scan one channel, all seems to work fine. but then when I am scanning two channels, change in channel0 seems to effect the channel1 reading too. Although its only channel0 that I am changing.

I am reading 10 bit value.

Help on this is really appreciated.

hi,
Please post your FULL program listing.:)

Use the 'Manage Attachments' button lower down the REPLY window.
 
Doing this is highly dependent on the source impedance and how fast you switch. Everytime you switch it takes time for the sample and hold capacitor to charge/discharge, so either add a delay before the reading, or decrease the source impedance.

Check my tutorials for details of using the ADC.

Like Eric says, post your code, but also post your circuit.
 
Reading 2 channel on 16F877

hi,
Please post your FULL program listing.:)

Use the 'Manage Attachments' button lower down the REPLY window.

Code is as follows

void main(void)
{
unsigned short adc_value;

unsigned short number_in_thousands_place, number_in_hundreds_place, number_in_tens_place, number_in_unit_place;

unsigned short remaining_three_digit_number, remaining_two_digit_number;


GIE=0; // we don't want interrupts

init_a2d(); // Initialise A/D Module
lcd_init(); // Initialise LCD

lcd_clear(); // Clear LCD

for(;;)
{

adc_value = read_a2d(0);
DelayMs(40);

lcd_goto(0); // Select first line
lcd_puts("VAL1:");

number_in_thousands_place = (adc_value / 1000);
remaining_three_digit_number = (adc_value % 1000);
number_in_hundreds_place = (remaining_three_digit_number / 100);
remaining_two_digit_number = (remaining_three_digit_number % 100);
number_in_tens_place = (remaining_two_digit_number / 10);
number_in_unit_place = (remaining_two_digit_number % 10);

lcd_putch(number_in_thousands_place | 0x30);

lcd_putch(number_in_hundreds_place | 0x30);

lcd_putch(number_in_tens_place | 0x30);

lcd_putch(number_in_unit_place | 0x30);




adc_value = read_a2d(1);
DelayMs(40);

lcd_goto(0x40); // Select Second line
lcd_puts("VAL2:");

number_in_thousands_place = (adc_value / 1000);
remaining_three_digit_number = (adc_value % 1000);
number_in_hundreds_place = (remaining_three_digit_number / 100);
remaining_two_digit_number = (remaining_three_digit_number % 100);
number_in_tens_place = (remaining_two_digit_number / 10);
number_in_unit_place = (remaining_two_digit_number % 10);

lcd_putch(number_in_thousands_place | 0x30);

lcd_putch(number_in_hundreds_place | 0x30);

lcd_putch(number_in_tens_place | 0x30);

lcd_putch(number_in_unit_place | 0x30);

DelayMs(100);

}
}


void init_a2d(void)
{
TRISA = 0x1F; // RA0 - RA4 input , RA5 output - (is used for LCD)
ADCON0=0; // select Fosc/2
ADCON1=0x82; // select Right justify result. A/D port configuration 0
ADON=1; // turn on the A2D conversion module
}



unsigned 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 10 bit result
}



LCD functions work fine. I am separating each decimal value and displaying it on the LCD

I am using 4Mhz Oscillator

Kindly let me know what might be the possible error.
 
hi tiwari,
I dont use 'C' language only asm, however many members are conversant in 'C' and are sure to help.:)

Do you have a circuit diagram to post.?
 
You're getting 'crosstalk' between ADC channels? Nearly everyone goes through this the first time they use a multiple input ADC, don't feel silly!

When moving on the the next ADC channel, you have to allow an "appropriate time" to elapse, before you read it. Otherwise the readings smudge eachother. The minimum time to give, the datasheet tells you how to calculate it. Nigel's tutorials are great resource too. Or at the least, insert a call to a Delay, of about 100 ms or more (which is probably more than long enough).
 
Last edited:
You're getting 'crosstalk' between ADC channels? Nearly everyone goes through this the first time they use a multiple input ADC, don't feel silly!

When moving on the the next ADC channel, you have to allow an "appropriate time" to elapse, before you read it. Otherwise the readings smudge eachother. The minimum time to give, the datasheet tells you how to calculate it. Nigel's tutorials are great resource too. Or at the least, insert a call to a Delay, of about 100 ms or more (which is probably more than long enough).


Hello Marcbaker
Thank you for your reply. I infact had figured it out yesterday. A small delay did make it work. The thing that i was trying seems to be ready now.

Thanks again for your reply
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top