Here's a small function I use to generate a sine wave with a digital to analog converter (DAC).
uint16_t sin_wave[128];
void setup()
{
for (int16_t i = 0; i < 128; i++)
{
float angle = TWO_PI * i / 128;
int16_t val = sin(angle) * (2048 - 1);
val += 2048;
sin_wave[i] = val;
}
}
128 is the number of steps (the granularity of your sine wave). 2048 is the waveform zero point offset.
The next step is to pass these values in a sweep from 0 to 127 to the output with an appropriate delay between each step. You could use a similar technique for just about any waveform. Either pre compute the steps or just compute and feed the values directly to your output as you go.