10 bit ADC in 16f676 to 8 bit

Status
Not open for further replies.

djc

Advanced Member level 1
Joined
Jan 27, 2013
Messages
402
Helped
3
Reputation
6
Reaction score
2
Trophy points
1,298
Location
India
Visit site
Activity points
4,554
Can we configure 10 bit ADC in 16f676 as 8 bit? If yes then how to do it?
 

I'm not sure if this is what you're looking for, but loosing the two lower bits will do just that.

pityu
 
Can we configure 10 bit ADC in 16f676 as 8 bit? If yes then how to do it?

As pityu described, simply dropping the two Least Significant Bits (LSBs) reduces a 10-bit result into an 8-bit result.

One quick way of accomplishing this task, left justify the result into the two byte register and simply acquire the high byte, without utilizing the two LSBs in low register.


BigDog
 

yes it called as under sampling and oversampling means convert 10-bit ADC to 12-bit or 8-bit to 10-bit ADC.if any one knows regarding this in detail plz provide details.
 

For example if you use CCS C for PIC, you may use
#device adc = 10 or
#device adc = 8
to "switch" between 10 or 8 bit ADC,
 

Basically my requirement is i want result in 8 bits i.e. 0 to 255 so that i can put this count directly in TIMER 0 count so that timer will run according to ADC count and PWM will generate according to ADC value. ADC is reading battery voltage. So that for 13 volt PWM width will be minimum and 9 volt PWM width will be maximum i.e 255. Now how can i ignore last two bits of 10 bit ADC?
 

Try like this.

Read adv value it will be around 1023 for full scale (5V input). Convert this value to 255 range using

myadcval = 1023 / 4.011764705882353;

myadcval will be in the range 0 to 255. Use this myadvval variable to set your Timer which will set duty cycle of PWM.
 

Convert this value to 255 range using

myadcval = 1023 / 4.011764705882353;

myadcval will be in the range 0 to 255..

I don't see the point of doing a floating point division to do something as simple as a 10bit to 8bit conversion, it wastes a lot of cycles for no reason not to mention that the division with 4.011764705882353 will actually give wrong results (for value 4 you will get 0 instead of 1, for value 8 you will get 1 instead of 2...)

why can't you just use shift right two times or even better left align the result and just read the high byte as BigDog suggested?
 
just neglect the 2 bits of LSB and shift the data for 2 times... But the accuracy 'll be reduced because of neglecting 2 bits... But no much effect on O/P...
 

Thanx jayant n alexan. I divided 1024 by 4 and used those values to compare with 8 bit timer0 value. So for 13v battery supply voltage acros load is 8.98v and for 9v battery supply voltage across load is 8.02. But main requirement is intensity of load which is a led should remain constant which is not happening. What must be the reason? Any solution for that?

- - - Updated - - -

One more thing i wud like to know. i am using mikroc pro for PIC and 16f676. But when i declare array of 20 its giving an error 'Not enough RAM?FLOC_Main'. What to do if I want to use larger array?
 

Hello there,

One more thing i wud like to know. i am using mikroc pro for PIC and 16f676. But when i declare array of 20 its giving an error 'Not enough RAM?FLOC_Main'. What to do if I want to use larger array?

This is because 16F877A doesn't have enough RAM. You might want to recheck your code, or use a device with larger RAM, like PIC18F458, which has 1.5kByte RAM vs 368Byte of PIC16F877A.

you can declare them as static. You can do this by selecting appropriate option in properties menu,this will store your codes in ROM and free up your RAM space.it will greatly reduces the RAM space

Best regards,
 

One more thing i wud like to know. i am using mikroc pro for PIC and 16f676. But when i declare array of 20 its giving an error 'Not enough RAM?FLOC_Main'. What to do if I want to use larger array?
put const keyword

const int array[20];
 

    V

    Points: 2
    Helpful Answer Positive Rating
Thanx paul, but i cant change controller now and where r the options present can u plz tell me.
 

Once try these,

const int array[20];
or
static int array[20];
or
volatile int array[20];

Best regards,
 

Hey thanx Venky & paul, it solved the RAM issue. But now voltage acros load is varying largely.
 

hello,

Show us your hardware schematic.

How do you scale battery voltage for ADC input ...
13V to 5 volts , by resistor divider ?

What do you want to control : Voltage or intensity ?


with PWM control, with a range 0 to 255 you control from 0V to Maximum Volt 13V. (step 50mV)
so 9V to 13V correspond to a PWM setting value from 176 to 255

if you want to control from 9V to 13V , You need an ampli OP to adapt the ADC input 9-13V to 0-5V wich will give 0 -1024 points
even you are using only 8 bits .. MSB of result with LEFT JUSTIFY MODE , as recommended in Post #3 and Poste #9

to do a loop control, you should use PID control, not direct loop without time constant or proportional adjustements.
to avoid oscillations.
 

Code:
//#fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT

#define ON 0
#define OFF 1
#define timer_val 0
#define BATTERY_CHARGE PORTC.B5
#define LOAD PORTC.B4

unsigned int Panel_Value, Battery_Value,FLAG_1,FLAG_2=0,FLAG_3,FLAG_4,FLAG_5,FLAG_6,FLAG_7,FLAG_8;

//int OnPulse = 217;
//int OffPulse = 38;
//char TOG = 0;
unsigned int i = 305,j=1, factor = 0,divide_val=0,k=14,l=3;

void convert(int m,int n){
 divide_val = ((Battery_Value/4) + k);
 if(divide_val>=200){
 divide_val = divide_val + l;
 l=l+3;
 if(l==42){
 l = 3;
 }
 }
 if(TMR0 >= divide_val){
 LOAD = OFF;
 //k++;
 //FLAG_1=0;
 }
 if(k>=134){
 k=14;
 FLAG_1 = 0;
 }

}


void interrupt(){
     if(INTCON.T0IF){
     T0IF_bit = 0;
     TMR0 = timer_val;
     }
     if(FLAG_1 == 1){
     LOAD = ON;
     //FLAG_2 = 1;
     }

}

void main() {

     TRISA = 0xff;      //port A as input
     TRISC = 0x00;      //port C as output
     PORTC = 0X00;      //INITIAL VALUE ON PORTC

     ADCON0 = 0b00000000;         //Left Justified
     ADCON1 = 0b00110000;         //Clock derived from internal RC oscilator
     ANSEL  = 0b00000011;         //channel AN0 and AN1 as analog input

     INTCON = 0b10100000;
     INTCON.T0IF = 0;
     //CMCON0 = 0x07;               //Disable the comparators
     T0CS_bit = 0;
     PSA_bit = 0;  //Prescaler is assigned to Timer0 module
     PS0_bit = 0;  //TMR0 rate 1:1
     PS1_bit = 0;
     PS2_bit = 0;

     //TMR0 = timer_val;

                      while(1){
                                   Panel_Value = ADC_Read(0);
                                  Battery_Value = ADC_Read(1);

                                  if(Panel_value>=122){       //AD Value for 3 volt
                                  ///FLAG_1 = 1;
                                  BATTERY_CHARGE = ON;
                                          if(Battery_Value>=430){  //AD Value for 12v
                                          //FLAG_2 = 1;
                                          BATTERY_CHARGE = OFF;
                                          }
                                  }

                                  if(Battery_Value > 430){
                                  BATTERY_CHARGE = OFF;
                                  }

                                  if(Panel_Value <= 30 ){   //Panel AD value for 1v <=40
                                  //FLAG_3=1;
                                  BATTERY_CHARGE = OFF;
                                  LOAD = ON;
                                              //if(Panel_Value >=40 && Battery_Value <= 321){  //Panel voltage 3v and battery voltage 9v
                                              //FLAG_4=1;
                                              //BATTERY_CHARGE = ON;
                                              //LOAD = OFF;
                                              //}
                                  }

                                  if(Panel_Value > 321){    //Panel Voltage 9 v
                                  //FLAG_6=1;
                                  LOAD = OFF;
                                  }

                                  /*if(Battery_Value <=425 && Battery_Value > 321){              //Battery voltage between 12v & 9v
                                  FLAG_1=1;
                                  FLAG_2=1;
                                           factor = Battery_Value - i;
                                           if(factor >= 200){
                                                     factor = factor + j;
                                                     j++;
                                                     if(j == 25){
                                                          j = 1;
                                                          }
                                                     }
                                           if(TMR0>=factor){
                                               LOAD = OFF;
                                               //i=0;
                                               //TMR0=0;
                                               //FLAG_1 = 0;
                                               i = i-2;
                                               if(i==97){
                                               i=305;
                                               }
                                            }
                                            //if(Battery_Value !=(Battery_Value<=425 && Battery_Value>321)){
                                            //FLAG_1 = 0;
                                            //}

                                  }*/
                                  if(Battery_Value <=425 && Battery_Value > 310){
                                  FLAG_1 = 1;
                                  FLAG_2 = 1;
                                  //k++;
                                  if(Battery_Value==425){
                                  convert(425,14);
                                  }

                                }

                                 /*if(FLAG_2==1){
                                     FLAG_1=0;
                                     FLAG_2=0;
                                    }*/

                                    //if(Battery_Value !=(Battery_Value<=425 && Battery_Value>321)){
                                           // FLAG_1 = 0;
                                            //}

                                   if(Battery_Value <= 310 ){        //Battery ADC value for 9v 310,309
                                     //FLAG_7 = 1;
                                     while(Battery_Value<=400){
                                     Battery_Value = ADC_Read(1);
                                     LOAD = OFF;
                                     }
                                     LOAD = ON;
                                  }
                                  
                                  /*if(Battery_Value<310){
                                  LOAD = OFF;
                                  }

                                  if(Battery_Value> 440){
                                  LOAD = ON ;
                                  }*/

                              }

}
 

your code is not clear ...
a big part of code is commented !
the last part of code will never run because located after the ending parenthesis of wile(1) loop.
You never arm Timer0 interrupt.

You said you want use 8 bits for ADC
How do you acquire 13V batterie ?
Volt and point are not linear : because you get 430 points instead of 480 points for 12V
430 is over 8 bits capability !

why you don't use 10 bits and a resistive divider like this:

 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…