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:
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