I'm trying to make a battery charger buck converter, driven by attiny85.
Based on the AVR458 reference design by Atmel.
However, i can't quite get it to work.
The problem is in current sensing, and to some degree, voltage too.
Schematic:
Layout:
I'm using 1.1V reference voltage instead of 2.5V, everything else is about the same as in AVR458.
The voltage sensing is running read_volt_amp in a loop.
It senses the voltage directly, and current differentially with x20 gain.
void read_volt_amp(void)
{
volatile uint32_t res;
if(half==0){
ADCSRA|=(1<<ADIF);
ADCSRA|=(1<<ADSC);
while((ADCSRA&(1<<ADIF))==0){}
ADCSRA|=(1<<ADIF);
res=ADCW;
//res=res*484UL;
//res=res/100UL;
//res=res*175UL;
//res=res/100UL;
cur_amp=(cur_amp+res)/2UL;
half=1;
ADMUX=(1<<REFS1)|(1<<MUX1)|(1<<MUX0);
}else{
ADCSRA|=(1<<ADIF);
ADCSRA|=(1<<ADSC);
while((ADCSRA&(1<<ADIF))==0){}
ADCSRA|=(1<<ADIF);
res=ADCW;
res=res*115UL;
res=res/10UL;
cur_volt=(cur_volt+res)/2UL;
half=0;
ADMUX=(1<<REFS1)|(1<<MUX2)|(1<<MUX1)|(1<<MUX0);
}
}
void setup_adc(void)
{
ADMUX=(1<<REFS1);
ADCSRA=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS0);
}
There is no control as of now, the PWM is fixed so there is a constant current (150mA) going through a test load, a 9V LED.
Problem is, the current read by the ADC can:
-A, vary within +-10
-B, is higher or lower than what is expected (consistent, but non-linear).
The higher the ADC prescaler, the weirder the current read-out is.
Without the half-half reading (that is, reading all in one go), the current reads 0, always.
If you remove voltage reading, it does read, but reads the same weird value.
If you read the current once, on a signal instead of a loop, then it gives the correct value.
Voltage reads correct all the time, with a bit of a noise on it (that fits the ripple actually seen).
I don't get it.
Is it some noise in the circuitry?
Is it software issue?
Being based on a reference design, i expected it to just work.