Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics 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.

ADC 16f877 from 8 to 10 bit

Status
Not open for further replies.

maria258

Member level 2
Joined
Feb 10, 2011
Messages
42
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,288
Activity points
1,577
I have already done an 8 bit mode adc but would like to change it to 10 bit. How can this code be altered to make it a 10 bit?

thanks
maria

Code:
#include<htc.h>

__CONFIG (0x3F72); //configured fuses
//define ports for easier reading
#define LEDS PORTB

void delay(unsigned char itime);

void main(void)
{
//8bit data-type variables
unsigned char x;	//ADC low byte
unsigned char y;	//ADC high byte
unsigned int z;	//final result

TRISB=0x00; //output
TRISA=0xFF;	//inputs
LEDS=0xFF;	//clear/switch off LEDS

while(1)
{
//ADFM=1, all i/ps analog, +VREF enabled
//Configure the functions of the Port bits
ADCON1=0b10000001;
//clock/channel select & enable bits
//controls the operation of the A/D module
ADCON0=0b11000001;


delay(1);
//Start a2d conversion
//Set GO bit (ADCON0=ADCON0|1;)
GODONE=1;
//wait end-of-conversion (conversion complete)
while(GODONE==1);
x=ADRESL; //store low byte
x=x>>1;	//shift 1 bit to the right
y=ADRESH;	//store high byte
y=y<<7;	//shift left 7 bit position
z=x|y; //combine together
LEDS=~z; //output on leds
}
}

void delay(unsigned char itime)
{
unsigned char i,j;
for(i=0;i<itime;i++)
for(j=0;j<1;j++);
}
 

Code:
/*--- Initialise A/D convertor ---*/

void init_ad(void)
  {
  ADCON1 = 0x20U;   /* Conversion clock Fosc/32 */
  ADCON0 = 0x80U;   /* 10 bit Right justified result, Vdd as ref */    
  }
 
/*--- Read A/D conversion ---*/

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

  ADCON0 = 0x01U;             /* Turn on A/D */
  ADCON0 |= (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;
  }
 

but the problem is since it is 10 bit and they are shown on leds, there will be another 2 leds that need to be shown on another port and dont know how to do that.
thanks
 

Code:
#define LEDS_8 LATB
#define LEDS_2 LATC

/*--- Read A/D conversion ---*/

void read_ad(unsigned char channel)
  {
  unsigned char acquisition_time = 3U;

  ADCON0 = 0x01U;             /* Turn on A/D */
  ADCON0 |= (channel << 2U);  /* Select channel */ 
        
  while(acquisition_time--){ /* Sample channel */
    ;
    }
    
  GODONE = 1U;    /* Start conversion */
  
  while(GODONE){  /* Wait for conversion end */
    ;
    }
    

  LEDS_8 = ADRESL;

  LEDS_2 &= 0xfc;
  LEDS_2 |= ADRESH;
  }
 
Last edited:

Hi Sir btbass,
I am new in pic and I use 16F877A ,MPLAB and Hi-tech C compiler,
I read about ADC for one month plus & try those who master in this code but does not work for me. Especially ADGO or GODONE always give me compiler error.
---
undefined identifier "ADGO"--
Any advice form you Sir, Thanks a lot.

---------- Post added at 04:01 ---------- Previous post was at 03:52 ----------

Sorry still not finish,

I am using sharp sensor GP2d120 and I connect to RA1 pin as analog input.
Physically I can measure the voltage when I play around with object distance.
But soft code I still having problem how to get the ADC results.my flow is..

if object < 10cm, Red LED blink ( connect at RC5)
else if ( 10cm < object < 20cm) , Green LED blink (connect at RC6 )
else if Blue LED blink ( connect at RC7)

Look like very simple for outputs but how can I get the input from RA1??
Please kindly help to explain how can I write the code.Thanks.

---------- Post added at 04:07 ---------- Previous post was at 04:01 ----------

I did try with below code but does not work in hardware.my code start here-

#include <pic.h>

__CONFIG ( 0x3F32 );

#define PORTBIT(adr,bit) ((unsigned)(&adr)*8+(bit)) //no modify this line

static bit led @ PORTBIT(PORTC,5);


void timer1init(void)
{
/* initialisation of timer1; */

T1CKPS1=1; T1CKPS0=1; /* select prescaler by 8 */
T1OSCEN=0; /* secondary oscillator disabled */
T1SYNC=0;
TMR1CS=0; /* clock source - internal clock */
TMR1ON=1; /* enable timer 1 */
}

void delayus(unsigned char us)
{
for (;us--;);
}

void adcinit(void)
{
/* initialisation of AD converter */
TRISA = 0xFF; /* all pin of portA are inputs */
ADCON1 = 0x00; /* pin RA1 is analog input */
ADCON0 = 0x49; /* config the converter */
delayus(100);
}

void settimer1(unsigned int val)
{
TMR1ON=0;
TMR1IF=0;
TMR1L=val&0xFF;
TMR1H=val>>8;
TMR1ON=1;
}

unsigned int adcsample(void)
{

for (ADCON0|=0x04; ADCON0&0x04; ); /* start and wait for done */

return ADRESL|(ADRESH<<8);
}


void main(void)
{
unsigned int speed;

TRISC=0x00;
timer1init();
adcinit();

for(;;) {
speed=adcsample();
settimer1(speed);
for(;!TMR1IF;); /* wait for timer1 overflow */
led=!led;
}
}

//code end here
 

I can not see any problems with your code other than

ADCON1 = 0x00;

You need to set bit 7 to right justify the result otherwise the 6 Least Significant bits of ADRESL will always are read as 0.

ADCON1 = 0x80;
 
  • Like
Reactions: mncp

    mncp

    Points: 2
    Helpful Answer Positive Rating
Hi Sir btbass,

I will change and tried.But my Blue , Red and Green LED all OFF.
Is there any things wrong with my value? I just want to measure the distance.
Please advice. Thanks.


/*============================================================================

INCLUDE

============================================================================*/
#include <pic.h>


/*============================================================================

Configuration Bits

============================================================================*/
__CONFIG ( 0x3F32 );


/*============================================================================

User definition

============================================================================*/
#define PORTBIT(adr,bit) ((unsigned)(&adr)*8+(bit)) //no modify this line

static bit ledR @ PORTBIT(PORTC,5);
static bit ledG @ PORTBIT(PORTC,6);
static bit ledB @ PORTBIT(PORTC,7);


/*============================================================================

Program

============================================================================*/

void timer1init(void)
{
/* initialisation of timer1; */

T1CKPS1=1; T1CKPS0=1; /* select prescaler by 8 */
T1OSCEN=0; /* secondary oscillator disabled */
T1SYNC=0;
TMR1CS=0; /* clock source - internal clock */
TMR1ON=1; /* enable timer 1 */
}

void delayus(unsigned char us)
{
for (;us--;);
}

void adcinit(void)
{
/* initialisation of AD converter */
TRISA = 0xE3; /* all pin of portA are inputs */
TRISC = 0X00;
ADCON1 = 0x08; /* pin RA1 is analog input */
ADCON0 = 0x49; /* config the converter */
ADON =1;
delayus(100);
}

void settimer1(unsigned int val)
{
TMR1ON=0;
TMR1IF=0;
TMR1L=val&0xFF;
TMR1H=val>>8;
TMR1ON=1;
}

unsigned int adcsample(void)
{

for (ADCON0|=0x04; ADCON0&0x04; ); /* start and wait for done */

return ADRESL|(ADRESH<<8);
}


void main(void)
{
unsigned int value;

TRISA=0xE3;
timer1init();
adcinit();

for(;;) {
value=adcsample();
settimer1(value);
for(;!TMR1IF;); /* wait for timer1 overflow */
if (value == 1)
{
ledG=1;
ledR=1;
ledB=1;

// delayus(100);
}
else {
ledR=0;
ledG=0;
ledB=0;
}
}
}


Clovis
 

if (value == 1)

It is very unlikely that the result will be exactly 1?

Try something like

if (value > 20)
 

Dear btbass,

Thanks for your advice. I tried all possible value 10 to 500 with different sign ( < or > ) but keep blinking Red LED. I do not know what wrongs. I will try to study how to convert analog Voltage to mm/cm (may be there got maths formula) and will let you know and discuss again. Anyway thanks sir.
"""""""
if (value>20)
{
ledR=!ledR;
ledG=0;
ledB=0;
}
//else if ( value < 30)
// {
// ledG=!ledG;
// ledR=0;
// ledB=0;
// }
else
{
// ledB=!ledB;
ledR=0;
// ledG=0;
}
""""""""

Clovis
 

Hi btbass,

I just try with this code , but LED blink alternatively instead of on one only9in terms of distance) although I did not place any object in fornt of sensor.Any advice Sir?
Thanks.
Clovis

---------- Post added at 07:30 ---------- Previous post was at 07:29 ----------

void main(void)
{
unsigned int value;

TRISC=0x00;
timer1init();
adcinit();

for(;;) {
value=adcsample();
settimer1(value);
for(;!TMR1IF;); /* wait for timer1 overflow */
if(value>=200){
ledR=!ledR;
}
else if(value>=400){
ledG=!ledG;
}
else if(value>=600){
ledB=!ledB;
}

}
}
 

This code won't work, it will never get to the last two else if's .

Code:
if(value>=200){
  ledR=!ledR;
  }
else if(value>=400){
  ledG=!ledG;
  }
else if(value>=600){
  ledB=!ledB;
  }

You could try

Code:
if((value >= 200) && (value < 400)){
  ledR=!ledR;
  }
else if((value >= 400) && (value < 600)){
  ledG=!ledG;
  }
else if(value >= 600){
  ledB=!ledB;
  }
 

Thanks Sir,I will try it. BTW, i read from this Linearizing Sharp Ranger Data about sharp sensor calculation. R = (2914 / (V + 5)) - 1
But another formula is R = (2194 / (V + 5)) - 1
I do not know which cal data is right. Anyway , I did calculation for 3 V, 2 V and 1V. 3V=313 .., 2v=365 and 1v=438.(base on 2194) and
3V=363 .., 2v=415 and 1v=485.(base on 2914). I try all range.Will get back to you. Thanks.
Clovis

---------- Post added at 02:51 ---------- Previous post was at 01:11 ----------

Hi btbass,

I have tried a lot of code(change here and there for the value),it does not work for me. My programming skill ???? But I did try with blinking LED speed with one LED. It works very good.

I attached the code below. Any idea about how can I change to 3 different LED to output signal depending on distance(voltage)?
Please kindly advice. Thanks in advanced..

#include <pic.h>


/*============================================================================

Configuration Bits

============================================================================*/

__CONFIG ( 0x3F32 );

/*============================================================================

User definition

============================================================================*/
#define PORTBIT(adr,bit) ((unsigned)(&adr)*8+(bit)) //no modify this line

//static bit led @ PORTBIT(PORTC,5);

static bit ledR @ PORTBIT(PORTC,5);
static bit ledG @ PORTBIT(PORTC,6);
static bit ledB @ PORTBIT(PORTC,7);

/*============================================================================

Program

============================================================================*/

void timer1init(void)
{
/* initialisation of timer1; */

T1CKPS1=1; T1CKPS0=1; /* select prescaler by 8 */
T1OSCEN=0; /* secondary oscillator disabled */
T1SYNC=0;
TMR1CS=0; /* clock source - internal clock */
TMR1ON=1; /* enable timer 1 */
}

void delayus(unsigned char us)
{
for (;us--;);
}

void adcinit(void)
{
/* initialisation of AD converter */
TRISA = 0xFF; /* all pin of portA are inputs */
ADCON1 = 0x00; /* pin RA1 is analog input */
ADCON0 = 0x49; /* config the converter */
delayus(100);
}

void settimer1(unsigned int val)
{
TMR1ON=0;
TMR1IF=0;
TMR1L=val&0xFF;
TMR1H=val>>8;
TMR1ON=1;
}

unsigned int adcsample(void)
{

for (ADCON0|=0x04; ADCON0&0x04; ); /* start and wait for done */

return ADRESL|(ADRESH<<8);
}


void main(void)
{
unsigned int blink_speed;

TRISC=0x00;
timer1init();
adcinit();

for(;;) {
blink_speed=adcsample();
settimer1(blink_speed);
for(;!TMR1IF;); /* wait for timer1 overflow */
ledG=!ledG; //nearer blinking speed faster
}
}
//********** Build successful! **********


Clovis.
 

attached my circuit diagram
 

Attachments

  • My_Circuit.zip
    29.9 KB · Views: 103

Hi sir ,
I attached my circuit n the code below. Any idea about how can I change to 3 different LED to output signal depending on distance(voltage)?
Please kindly advice. Thanks in advanced..
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top