I had to generate this waveform: (why?)

  __    |____
  .     |    \
  .     |     \
~3000   |      \
  .     |       \
  .     |        \
  __    |         \________
        |                  \
        |                   \
        |                    \
        |                     \
        +----+----+-------+---+--------
          t0   t1    t2    t3

So what's the big deal?
The deal is that t0 through t3 are all <1ms and they should allow for in-circuit adjustments. I generated the slopes using Bresenham's line drawing algorithm - wrote it in assembly for faster results.

What did I learn?
Using the serial port on the AVR, using the serial port in Turbo C++ and in Visual C++.
It was also the first time I made an application using 'Visual' C++, up to now I had always written my own user interfaces from scratch (PDA and DataLogger), or had made text mode programs.
Most importantly, I found out out about this wonderful freeware program called VMLab for simulating microcontroller circuits. It even allowed me to write 'my own' 12-bit D/A converter using C++. I was able to simulate switches, the serial port, and observe the waveforms on a virtual scope. And the results on the real hardware were exactly the same!

Pics
Adjust the sliders in this VC++ app and hit the Send button, the new timings and slopes are fed to the microcontroller via the serial port.

The waveforms are from the following settings.

Output on VMLab scope:

How the steps look. The ramp is pretty much within the timing constraints.

The other ramp, but with a lesser slope:

Those spikes seen in the screenshots above are caused by rollover to the MS Byte. They last for 250ns (2M/C).
They were not visible on the scope at all.

After putting this basic filter at the output:

I got:

What's its use?

My teacher asked me the same question when I was testing it in the lab. I really enjoyed answering that:

From http://www.nist.gov/public_affairs/releases/n99-22.htm#release :

"NIST-F1 is referred to as a fountain clock because it uses a fountain-like movement of atoms to obtain its improved reckoning of time. First, a gas of cesium atoms is introduced into the clock's vacuum chamber. Six infrared laser beams then are directed at right angles to each other at the center of the chamber. The lasers gently push the cesium atoms together into a ball. In the process of creating this ball, the lasers slow down the movement of the atoms and cool them to near absolute zero..."

I did my training at the National Physical Laboratory, New Delhi, where a Cesium fountain clock is under construction. When you need to give that final cooling push to the atoms, you need to drop the laser current in the exact fashion as the wave shown above so that the atoms are at barely a few micro Kelvins of temperature. This wave has to be adjusted to find the optimum shape for cooling. So I made this circuit to replace the existing analog version.