Files
AVR_Learning/Make AVR Examples/Chapter13_Advanced-PWM-Tricks/dds/dds.c

57 lines
2.0 KiB
C

/* Direct-digital synthesis */
// ------- Preamble -------- //
#include <avr/io.h> /* Defines pins, ports, etc */
#include <util/delay.h> /* Functions to waste time */
#include <avr/power.h>
#include "pinDefines.h"
#include "fullSine.h"
static inline void initTimer0(void) {
TCCR0A |= (1 << COM0A1); /* PWM output on OCR0A */
SPEAKER_DDR |= (1 << SPEAKER); /* enable output on pin */
TCCR0A |= (1 << WGM00); /* Fast PWM mode */
TCCR0A |= (1 << WGM01); /* Fast PWM mode, pt.2 */
TCCR0B |= (1 << CS00); /* Clock with /1 prescaler */
}
int main(void) {
uint16_t accumulator = 0;
uint16_t accumulatorSteps = 880; /* approx 440 Hz */
uint8_t waveStep;
int8_t pwmValue;
// -------- Inits --------- //
clock_prescale_set(clock_div_1); /* CPU clock 8 MHz */
initTimer0();
BUTTON_PORT |= (1 << BUTTON); /* pullup on button */
// ------ Event loop ------ //
while (1) {
if (bit_is_clear(BUTTON_PIN, BUTTON)) {
SPEAKER_DDR |= (1 << SPEAKER); /* enable speaker */
accumulator += accumulatorSteps; /* advance accumulator */
waveStep = accumulator >> 8; /* which entry in lookup? */
pwmValue = fullSine[waveStep]; /* lookup voltage */
loop_until_bit_is_set(TIFR0, TOV0); /* wait for PWM cycle */
OCR0A = 128 + pwmValue; /* set new PWM value */
TIFR0 |= (1 << TOV0); /* reset PWM overflow bit */
}
else { /* button not pressed */
SPEAKER_DDR &= ~(1 << SPEAKER); /* disable speaker */
}
} /* End event loop */
return 0; /* This line is never reached */
}