AVR Buck converter
After messing about with switching power supplies and looking at the
apparent simplicity of the Buck converter. I thought "Lets try to put
that in a microcontroller". This page is the results of these
experiments and tests.
Setup
Below is the general setup of a buck converter (image taken from wikipedia article).

These are the parts I used:
- S: BS250 P channel mosfet, controlled by AVR GPIO with one 22ohm
gate resistor
- D: BAT54-A
double Schottky diode, common anode
- L: 220uH coil with 0.5A saturation current
- C: 10uF 15V 0805 ceramic capacitor
- R: See scope traces loads
- Vi: 5V
- Vo: ~1.1V (attiny2313 comparator reference)
Microcontroller used is the ATtiny2313 running at 20MHz.
tn2313_pulseskip.c
The main C file initializes Timer 1 in fast PWM mode. As the top the
ICR register is used to make it easy to change the PWM frequency.
Currently OC1A and OC1B are used but only OC1A is used as control for
the BS250. The software uses the so called "pulse skip" scheme
described in this
microchip application note. This means that when output voltage is
higher then the reference voltage the next pulse is going to be
skipped.
The on board comparator with its reference are used for regulation. The
Capacitor voltage is sensed and used to check if the next PWM cycle
needs to be executed.
The CPU is immediately put to sleep to minimize interrupt latency. The
AVR always executes the current instruction until completion. In
general the microcontroller sits in an infinite loop while checking
events or something else. In this simple program no such thing is
needed so the CPU is put to sleep. This also means that the interrupt
can execute right away without any latency.
isrs.S
This assembler file contains the ISR for the OC1A compare interrupt. In
the interrupt the comparator output is checked, and depending on this,
the OC1A and OC1B output configuration is reset. This makes the OC
output pins on the microcontroller revert to their steady state (in
this case initialised to high). Switching of the FET. When the
comparator indicates that the output voltage has fallen below the
reference, the next PWM cycle is enabled.
Closeup from the built prototype.

Overall setup on my workbench.

Oscilloscope traces
Mosfet Gate and drain at 1Kohm load.

Output ripple at 1Kohm load. 40mv not too good, but this is with a
small output cap and no output filtering at all.

Gate source traces, the source has a 1 Ohm resistor to make it possible
to measure the current.

Gate and output traces at a load of around 18 ohms (22ohm, 100ohm
parallel). Notice the much higher duty cycle.

Conclusion
Creating a buck converter that works is easy. Making it optimal is a
bit harder. The current inductor is way to big to keep the regulation.
If you check the output voltage more frequently you improve the ripple.
If your ISR is not too complex, it really pays to write it in pure
assembler. I went from a 25 cycle ISR to a 8 cycle ISR with little
effort. What also helps is just using AVR instructions that do not
modify flags, this eliminates the save and restore of the flags, but
GCC inserts this regardless.
What next?
This seems to work pretty well. Next I want to try the forward
converter topology, inspired by this article
by Electronic Design.
Back
Last update at: 02-02-2011