Generate Sine Wave Using DAC in Embedded C: Simple Guide
To generate a sine wave using
DAC in embedded C, create a lookup table with sine values scaled to the DAC range, then output these values sequentially at a fixed rate using a timer interrupt or loop. This produces a smooth analog sine wave from the digital DAC output.Syntax
To generate a sine wave using DAC, you typically use these steps:
uint16_t sine_table[]: Array holding scaled sine values.DAC_SetValue(channel, value): Function to send a value to the DAC output.Timer interrupt or loop: To update DAC output at regular intervals.
This pattern outputs sine values repeatedly to create a wave.
c
uint16_t sine_table[] = { /* scaled sine values */ };
void output_sine_wave() {
for (int i = 0; i < TABLE_SIZE; i++) {
DAC_SetValue(DAC_CHANNEL_1, sine_table[i]);
delay_us(SAMPLE_DELAY);
}
}Example
This example shows how to generate a 1 kHz sine wave using a 12-bit DAC and a timer interrupt on a microcontroller. The sine values are precomputed and output in a loop with a delay to control frequency.
c
#include <math.h> #include <stdint.h> #define TABLE_SIZE 100 #define DAC_MAX 4095 #define PI 3.14159265 uint16_t sine_table[TABLE_SIZE]; void DAC_SetValue(uint16_t value) { // Hardware-specific DAC output code here // Example: DAC->DATA = value; } void delay_us(int us) { // Simple delay loop or timer-based delay volatile int count = us * 10; while(count--) {} } void generate_sine_table() { for (int i = 0; i < TABLE_SIZE; i++) { double angle = 2 * PI * i / TABLE_SIZE; double sine_val = (sin(angle) + 1) / 2; // Normalize 0 to 1 sine_table[i] = (uint16_t)(sine_val * DAC_MAX); } } int main() { generate_sine_table(); while (1) { for (int i = 0; i < TABLE_SIZE; i++) { DAC_SetValue(sine_table[i]); delay_us(10); // Adjust for frequency } } return 0; }
Common Pitfalls
Common mistakes when generating sine waves with DAC include:
- Not scaling sine values to DAC range, causing distorted output.
- Using delays that are too long or inconsistent, resulting in wrong frequency or jitter.
- Not using a timer interrupt for precise timing, leading to unstable waveforms.
- Ignoring DAC hardware initialization or configuration.
Always initialize DAC properly and use consistent timing.
c
/* Wrong: No scaling, values out of DAC range */ uint16_t wrong_table[] = {0, 1, 2, 3, 4, 5}; /* Right: Scale sine values to DAC max range */ uint16_t right_table[] = {0, 1023, 2047, 3071, 4095};
Quick Reference
| Step | Description |
|---|---|
| Create sine lookup table | Precompute sine values scaled to DAC range (0 to max DAC value) |
| Initialize DAC | Set up DAC hardware and enable output channel |
| Output values | Send sine values to DAC sequentially at fixed intervals |
| Control timing | Use timer interrupts or precise delays to maintain frequency |
| Repeat | Loop through sine table continuously for waveform |
Key Takeaways
Precompute and scale sine values to match your DAC resolution.
Use precise timing (timer interrupts preferred) to output values at consistent intervals.
Initialize and configure DAC hardware before outputting values.
Avoid delays that vary or are too long to keep sine wave frequency stable.
Loop through the sine table continuously to generate a smooth waveform.