|
|
View previous topic :: View next topic |
Author |
Message |
CSharpdeveloper
Joined: 12 Jan 2014 Posts: 4
|
Read voltage using 16f877 with 12bit External Adc (ltc1297) |
Posted: Sun Jan 12, 2014 3:57 pm |
|
|
Hi,
i tried the following codes for using 12bit external adc.
i have a problem about 12bit external adc. i am using ltc1297 12bit adc and pic16f877. The obtained voltage value is not true. The proteus scheme and CCS C codes are as follows.
the proteus file and ccs codes are present in the following links.
Link: http://www.dosyasitesi.com/download.php?file=819e28c743d6d74c632d4802f44d87e6
For example:
While the pot value is 0V, the obtained voltage value is 0.009V.
While the pot value is 1V, the obtained voltage value is 3.003V.
While the pot value is 2.5V, the obtained voltage value is 0.000V.
While the pot value is 4V, the obtained voltage value is 1.996V.
While the pot value is 5V, the obtained voltage value is 5.000V.
Code: |
#include <16f877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <ltc1297.c>
void display_data( long int data ) {
char volt_string[6];
convert_to_volts( data, volt_string );
printf(volt_string);
printf(" (%4lX)",data);
}
void main()
{
long int value;
adc_init();
printf("Sampling:\r\n");
do {
delay_ms(1000);
value = read_analog(0);
printf("\n\rCh0: ");
display_data( value );
} while (TRUE);
}
|
Code: |
#ifndef ADC_CS
#define ADC_CLK PIN_B0
#define ADC_DOUT PIN_B1
#define ADC_DIN PIN_B2
#define ADC_CS PIN_B3
#endif
void adc_init() {
output_high(ADC_CS);
}
void write_adc_byte(BYTE data_byte, BYTE number_of_bits) {
BYTE i;
delay_us(2);
for(i=0; i<number_of_bits; ++i) {
if((data_byte & 1)==0)
output_low(ADC_DIN);
else
output_high(ADC_DIN);
data_byte=data_byte>>1;
output_high(ADC_CLK);
delay_us(50);
output_low(ADC_CLK);
delay_us(50);
}
}
BYTE read_adc_byte(BYTE number_of_bits) {
BYTE i,data;
data=0;
for(i=0;i<number_of_bits;++i) {
output_high(ADC_CLK);
delay_us(50);
shift_left(&data,1,input(ADC_DOUT));
output_low(ADC_CLK);
delay_us(50);
}
return(data);
}
long int read_analog( BYTE channel ) {
int l;
long int h;
delay_us(200);
output_low(ADC_CLK);
output_high(ADC_DIN);
output_low(ADC_CS);
if(channel==0)
channel=0x1b;
write_adc_byte( channel, 5);
h=read_adc_byte(8);
l=read_adc_byte(4)<<4;
output_high(ADC_CS);
return((h<<8)|l);
}
void convert_to_volts( long int data, char volts[6]) {
BYTE i;
long int temp,div;
div=0x3330;
for(i=0;i<=4;i++) {
temp=data/div;
volts[i]=(BYTE)temp+'0';
if(i==0) {
volts[1]='.';
i++;
}
temp=div*(BYTE)temp;
data=data-temp;
div=div/10;
}
volts[i]='\0';
}
|
proteus scheme:
link1: http://s16.postimg.org/71akbx8xh/image1.png
link2:
jpg upload |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Sun Jan 12, 2014 7:52 pm |
|
|
BUILD the project with real hardware.
you don't even have a safe circuit design for the LTC converter.
check its data sheet.
then see if it works.
NOBODY here trusts or will respond to proteus questions. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Sun Jan 12, 2014 9:11 pm |
|
|
Please read PIC101 and you'll see why real PICsters use real PICs in the real world. Your Proteus schematic has over 11 errors and can not work in the real world. There's probably a coding issue as well but that could easily be an internal Proteus problem as it's full of 'bugs'.
I strongly urge you to wire up the 877 and run the CCS example code for the internal ADC peripheral. First in 8 bit mode, then 10 bit. Once you've gotten it to work 100% then wire up the external ADC.
Getting a 12 bit ADC to work reliably requires the use of an accurate and stable Vref, great ground planes and careful board layout. The best I've achieved is +-3 bits using those same components.
Also the '877 is, well, obsolete and you should use a newer PIC. There are several pin-for-pin compatible ones now, not only cheaper but with more features.
hth
jay |
|
|
dorinm
Joined: 07 Jan 2006 Posts: 38
|
|
Posted: Tue Jan 14, 2014 3:49 am |
|
|
Code: | #ifndef ADC_CS
#define ADC_CLK PIN_B0
#define ADC_DOUT PIN_B1
#define ADC_DIN PIN_B2
#define ADC_CS PIN_B3
#endif
void adc_init() {
output_high(ADC_CS);
}
unsigned int16 read_ltc1297(void) {
unsigned int8 i;
unsigned int16 data;
data=0;
output_low(ADC_CS);
delay_us(50);
//first clock
output_low(ADC_CLK);
delay_us(50);
output_high(ADC_CLK);
delay_us(50);
//null_bit
output_low(ADC_CLK);
delay_us(50);
output_high(ADC_CLK);
delay_us(50);
for(i=0;i<11;++i) {
output_low(ADC_CLK);
delay_us(50);
output_high(ADC_CLK);
delay_us(50);
}
// now read the data
for(i=0;i<12;++i) {
output_low(ADC_CLK);
delay_us(50);
output_high(ADC_CLK);
shift_right(&data,2,input(ADC_DOUT));
delay_us(50);
}
output_low(ADC_CLK);
delay_us(50);
output_high(ADC_CS);
delay_us(50);
data>>=4;
data&=0X0FFF;
return(data);
}
|
...and volts=data*vref/0x0FFF |
|
|
CSharpdeveloper
Joined: 12 Jan 2014 Posts: 4
|
Thanks to dorinm |
Posted: Wed Jan 15, 2014 6:19 pm |
|
|
Thank you very much for all advice (Especially to dorinm). I tried the code and see that the code is working correctly. My problem is solved by dorinm.
Best regards. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|