Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register Log in

can any 1 tel me where the wrong in program ADC pic16f882 internal adc

Status
Not open for further replies.

parimi.ravikiran

Newbie level 4
Joined
Dec 4, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Pune
Activity points
1,352
unsigned int low_value, hig_value;
void main()
{
OSCCON=0X60; // INTERNAL CLOCK FREQ 4MHZ
TRISA=1; // ADC INPUT PORTA
TRISB=0; //ADC O/P PORTB FOR LOWER BITS (0-1) USING LEFT JUSTIFIED
TRISC=0; // ADC O/P HIGHER BITS (2-9)
PORTB=0X00; // make o/p ports clear
PORTC=0X00; // make o/p ports clear
while(1)
{
ADCON0=0b01000000; //AN0 SELECT , clk Fosc/8
ANSEL=0x01; // ANALOG HAS BEEN SELECTED
ADCON0=0B01000001; // CLK FOSC/8 , Analog channel AN0,ADC ON
ADCON1=0X00; // Vref use vss , vdd
PIR1=0X00; // clr interrupt flag
delay_ms(30); // wait for 4.67uS ACQUISITION MIN TIME
//ADCON0=0x41; //make adc ON--- (not used now)
//ADCON0=0B01000011; // to make adc start.-- (not used now)
//while(PIR1=0b01000000) // check for IF bit is set or not-- (not used now)
for(;;) {
//ADCON0=0x43; // initiate conversion on the channel 0 , go/done bit=1
ADCON0|=2; //set bit go =1
//while(GO); // Wait conversion done
//while(Go&0x00);
while(ADIF); //checking that go bit is clear or not . is conversion over?
{
portb=ADRESL; // send lower 2 bits 0-1 to portb
//portb=low_value;
portc=ADRESH; //send 2-9 bits higher bits to portc. msb last
//PORTC=hig_value;
PIR1=0X00; // clear IF( Interrupt flag)
}
}
}
}
 

btbass

Advanced Member level 5
Joined
Jul 20, 2001
Messages
1,897
Helped
438
Reputation
880
Reaction score
287
Trophy points
1,363
Location
Oberon
Activity points
12,861
It is a lot easier to understand if you put the A/D conversion into a single separate function.

Divide and conquer!

This also promotes reusable code, once you have a peripheral function debugged and working, next time you need it, it's a cut and paste job.


Code:
/*--- Read A/D conversion ---*/

unsigned int read_ad(unsigned char channel)
  {
  unsigned int result = 0U;
  unsigned char acquisition_time = 3U;

  ADCON1 = 0x80U;   /* 10 bit Right justified result, Vdd as ref */
  ADCON0 = 0x81U;   /* Conversion clock Fosc/32 */

  ADCON0 |= (unsigned char)(channel << 2U);  /* Select channel */ 
        
  while(acquisition_time--){ /* Sample channel */
    ;
    }
    
  GODONE = 1U;    /* Start conversion */
  
  while(GODONE){  /* Wait for conversion end */
    ;
    }
    
  result = ADRESH;
  result <<= 8U;
  result |= ADRESL;
  return result;
  }

/*--- End of Function ---*/
 

parimi.ravikiran

Newbie level 4
Joined
Dec 4, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Pune
Activity points
1,352
Thanks dude ...

small doubt in the main while calling the read_ad(?); the parameters need to give
bcoz
ADCON0 |= (unsigned char)(channel << 2U); /* Select channel */

it takes the channel here.. i am not getting this line
 

btbass

Advanced Member level 5
Joined
Jul 20, 2001
Messages
1,897
Helped
438
Reputation
880
Reaction score
287
Trophy points
1,363
Location
Oberon
Activity points
12,861
The channel is the A/D input you want to read.
So you would define them something like this:

Code:
#define SUPPLY_VOLTAGE  0    /* A/D channel AN0 */
#define MOTOR_CURRENT   1    /* A/D channel AN1 */

/* Call A/D routine */

psu_volts = read_ad(SUPPLY_VOLTAGE);  /* Read A/D channel AN0 */

current  = read_ad(MOTOR_CURRENT);    /* Read A/D channel AN1 */
Or you could just use the channel number

result = read_ad(4); /* Read A/D channel AN4 */


ADCON0 |= (unsigned char)(channel << 2U); /* Select channel */

The channel number is shifted into the correct position and ored with the register.
The U after the 2 tells the compiler that the 2 is an unsigned variable.
 
Last edited:

parimi.ravikiran

Newbie level 4
Joined
Dec 4, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Pune
Activity points
1,352
Thanks a lot man

i got it ..u r explanation is superb..

got the result
 

parimi.ravikiran

Newbie level 4
Joined
Dec 4, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Pune
Activity points
1,352
Just i want to know,while next time receiving the adc o/p with different voltage input from Variable pot the ARSESH and ADRESL are giving the previous result only why so?
 

btbass

Advanced Member level 5
Joined
Jul 20, 2001
Messages
1,897
Helped
438
Reputation
880
Reaction score
287
Trophy points
1,363
Location
Oberon
Activity points
12,861
Don't know?

Show us what code you are using.
 

parimi.ravikiran

Newbie level 4
Joined
Dec 4, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Pune
Activity points
1,352
i am using miKroC compiler pic16f882.
simulation in Proteus is showing some o/p but its not correct
Hard ware shows nothing o/p

my code::

unsigned int result1;
unsigned int read_ad(char);
unsigned char acquisition_time = 3U;
void main()
{
OSCCON=0X71; // INTERNAL CLOCK FREQ 8MHZ,SCS Internal oscillator is used for system clock
TRISA=1; // ADC INPUT PORTA
TRISB=0; //ADC O/P PORTB FOR LOWER BITS (0-7) USING RIGHT JUSTIFIED
TRISC=0; // ADC O/P HIGHER BITS (8-9)
ANSEL=0x10; //ANS4 Analog i/p
PORTB=0X00; // make o/p ports clear
PORTC=0X00; // make o/p ports clear
portb|=2; //my optional
delay_ms(1000); //my optional
out=read_ad(4);

// send the 0-7 bits of adc result to the portb ( LSB 1st) *
PORTB=out; // portb will contain the result of adc (1-8)lsb 1st
//portc=out>>8;
// send the 8-9 bits of adc result to the portb (MSB END)

}

/* calling function*/
unsigned int read_ad(unsigned char channel)
{
unsigned int result = 0U;
unsigned char acquisition_time = 3U;

ADCON1 = 0x80U; /* 10 bit Right justified result, Vdd as ref */
ADCON0 = 0x81U; /* Conversion clock Fosc/32 */

ADCON0 |= (unsigned char)(channel << 2U); /* Select channel */
while(acquisition_time--) /* Sample channel */
{;
}

//GO=0x01; or GO=1; /* Start conversion */ It is not working for me miKroC
//GO=1;
ADCON0|=2; //go=1
portb=0x00; //optional
portc|=2; //my optional
//while((ADIF&0x01)&(GO&0x00))
//while(ADIF==1&GO==0x00)
//while(ADIF&0x01)/* Wait for conversion end */
while(GO&0x00) // while(GO) is not working here
{
;
}
portc=0x00; //my optional
PORTC=ADRESH; //msb bit (10, 9 ) send to portc
result1 = ADRESH;
result1 <<= 8U;
result1 |= ADRESL;
//portb=ADRESL; //bit (8, 1 ) send to portb
return result1;
}
 

dayanpad

Advanced Member level 4
Joined
Mar 23, 2009
Messages
114
Helped
17
Reputation
34
Reaction score
17
Trophy points
1,298
Location
Colombo
Activity points
1,921
read This example code reads analog value from channel 2 and displays it on PORTB and PORTC. this is work perfectly then try to understand your code that it is included necessary codes

unsigned int temp_res;

void main() {
ANSEL = 0x04; // Configure AN2 pin as analog
ANSELH = 0; // Configure other AN pins as digital I/O
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;

TRISA = 0xFF; // PORTA is input
TRISC = 0; // PORTC is output
TRISB = 0; // PORTB is output

do {
temp_res = ADC_Read(2); // Get 10-bit results of AD conversion
PORTB = temp_res; // Send lower 8 bits to PORTB
PORTC = temp_res >> 8; // Send 2 most significant bits to RC1, RC0
} while(1);
}
 

parimi.ravikiran

Newbie level 4
Joined
Dec 4, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Pune
Activity points
1,352
Thanks both of u , finally it is working ..
here is my code any fineness is required just tell me
All i have observed the o/p on led
now i have 2 work on taking this data to the LCD

CODE::pIC16F882 INTERNAL ADC USING MIKROC

unsigned int result1,temp_result;
unsigned int read_ad(char);
unsigned char acquisition_time = 3U;
void main()
{
OSCCON=0X61; // INTERNAL CLOCK FREQ 4MHZ,SCS Internal oscillator is used for system clock
TRISA=0XFF; // ADC INPUT PORTA
TRISB=0; //ADC O/P PORTB FOR LOWER BITS (0-7) USING RIGHT JUSTIFIED
TRISC=0; // ADC O/P HIGHER BITS (8-9)
ANSEL=0x10; //ANS4 Analog i/p
ANSELH=0; //Configure other AN pins as digital I/O
PORTB=0X00; // make o/p ports clear
PORTC=0X00; // make o/p ports clear
C1ON_BIT=0; // disable comparator
C2ON_BIT=0;

do
{
temp_result=read_ad(4); //Read the adc function

// send the 0-7 bits of adc result to the portb ( LSB 1st) *
PORTB=temp_result; // portb will contain the result of adc (1-8)lsb 1st
PORTC=temp_result>>8; // send the 8-9 bits of adc result to the portc(RC0,RC1) (MSB END)
}while(1);
}

/* calling function*/
unsigned int read_ad(unsigned char channel)
{
unsigned int result = 0U;
unsigned char acquisition_time = 3U;

ADCON1 = 0x80U; /* 10 bit Right justified result, Vdd as ref */
ADCON0 = 0x81U; /* Conversion clock Fosc/32 */

ADCON0 |= (unsigned char)(channel << 2U); /* Select channel */
while(acquisition_time--) /* Sample channel */
{;
}

GO_DONE_BIT = 1U;
//while((ADIF&0x01)&(GO_DONE_BIT&0x00))
//while(ADIF&0x01)/* Wait for conversion end */
while(GO_DONE_BIT) // use this for mikroC
{
;
}

result1 = ADRESH;
result1 <<= 8U;
result1 |= ADRESL;
return result1;
}
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top