Digitaler Funktionsgenerator

An ATmega8 built in 2003 for a Facharbeit on direct digital synthesis. The hardware is long gone; this is its firmware — the original assembly, not a reimplementation — running instruction by instruction on a simulated ATmega8 at 6.5536 MHz, driving a simulated HD44780 and an R-2R ladder you can hear.

Anzeige
Bedienung
Ausgang
R-2R-Leiter, ungefiltert nach Bessel-Filter
Frequenz
Signalform
Echtzeit
MCU-Takte

Tasten: Z −−  X −  C +  V ++  Leertaste Signalform  B Hüllkurve. Gedrückt halten wiederholt, wie am echten Gerät.

What is actually running

programm/avr/da-test.asm, assembled unmodified with tavrasm and executed by a cycle-accurate AVR core. The 24-bit phase accumulator, the sine and triangle tables, the BCD frequency arithmetic and the 4-bit LCD driver are all AVR machine code. Timer1 fires its compare interrupt every 25 cycles, so the DAC updates 262144 times a second — and the output frequency is exactly the accumulator step divided by 64.

The simulation lives inside the AudioWorklet and is clocked by your sound card: each output frame advances the MCU by exactly 6553600 ÷ sample rate cycles. What you hear is PORTD, sample for sample.

The other two firmwares are the same program with a branchless interrupt: giving square and sawtooth their own wave tables, like sine and triangle already had, drops the ISR from 17 cycles to 13. One build spends those four cycles on a higher sample rate, the other on a per-sample amplitude multiply. Both add four waveforms — Orgel, Glocke, Puls 25%, and Treppe, the sawtooth quantised to 8 levels instead of 256.

262144 Hz was the arithmetically perfect rate here: 6553600/25 = 218, which is what made the frequency display a plain shift and the tuning steps exactly 0,5 Hz. The faster build gives that up and rescales the arithmetic; the envelope build keeps it, and spends its four cycles on a sixth key at PC5 instead — free on the real board, since the original uses only PC0–PC4 and PC6 is /RESET. Hold it to sustain, release it and the note decays to silence in about half a second. Try it on Glocke.

The third firmware is a dedicated step sequencer. It plays from power-on — there is no mode to activate — because the generator’s key handling was cut out of the source altogether: everything between mainloop: and update:, which also saved 348 bytes of flash. The sixth key on PC5, free on the real board since the original uses only PC0–PC4 and PC6 is /RESET, is simply run/stop.

Line 1 is the pattern itself, as note letters — capital for a natural, lower case for a sharp, -- for a rest, so A2A3A2C4--E4G3E3 is the whole riff at a glance. Line 2 carries the playhead, the cursor, that step’s note, its accent and glide flags, its waveform and the edit target.

An earlier version drew the pattern as a bar chart using the HD44780’s eight user-defined characters, which looked better but cost about 5 ms of LCD traffic on every step — and for that whole time the main loop never gets back to the envelope, so notes started late. Plain letters cost one character per step. The keys are edge-triggered and sampled on a timer too, which removed the blocking debounce waits that used to stall the loop for tens of milliseconds. Time from a step firing to the note reaching full amplitude went from 21 ms to about 5.

/+ pick the step and the form key cycles what −−/++ edit: Pitch, Accent, Glide or Waveform. Selection and edits never touch the sounding note — you hear a change when that step next comes round.

Faithful, and where it isn't

The Bessel low-pass is the board's own — 2nd order, 20 kHz, the filter the Facharbeit specifies. Switch it off to hear the bare ladder staircase that the paper's chapter on filtering is about.

Two things are not from 2003: a steep anti-alias filter, needed because the DAC runs at 262 kHz and your sound card does not, and a 10 Hz DC blocker on the speaker feed. The scope taps the signal ahead of both. LCD instruction timing is not modelled — the firmware ties R/W low and never reads the busy flag, so it cannot tell.