Created
January 18, 2017 16:18
-
-
Save NT7S/3843b0386200926e0f263cc7059fd0c5 to your computer and use it in GitHub Desktop.
DAC Sine Wave on Empyrean/Arduino Zero
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
uint8_t sine_wave[256] = { | |
0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96, | |
0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE, | |
0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4, | |
0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8, | |
0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, | |
0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, | |
0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, | |
0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, | |
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, | |
0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, | |
0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB, | |
0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, | |
0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9, | |
0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3, | |
0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C, | |
0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, | |
0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A, | |
0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52, | |
0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C, | |
0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28, | |
0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18, | |
0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C, | |
0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, | |
0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, | |
0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, | |
0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, | |
0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15, | |
0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, | |
0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, | |
0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, | |
0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64, | |
0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D | |
}; | |
volatile uint8_t t = 0; | |
void setup() { | |
// Set up the generic clock (GCLK4) used to clock timers | |
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(3) | // Divide the 48MHz clock source by divisor 3: 48MHz/3=16MHz | |
GCLK_GENDIV_ID(4); // Select Generic Clock (GCLK) 4 | |
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization | |
REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW | |
GCLK_GENCTRL_GENEN | // Enable GCLK4 | |
GCLK_GENCTRL_SRC_DFLL48M | // Set the 48MHz clock source | |
GCLK_GENCTRL_ID(4); // Select GCLK4 | |
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization | |
// Feed GCLK4 to TC4 and TC5 | |
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable GCLK4 to TC4 and TC5 | |
GCLK_CLKCTRL_GEN_GCLK4 | // Select GCLK4 | |
GCLK_CLKCTRL_ID_TC4_TC5; // Feed the GCLK4 to TC4 and TC5 | |
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization | |
REG_TC4_CTRLA |= TC_CTRLA_MODE_COUNT8; // Set the counter to 8-bit mode | |
while (TC4->COUNT8.STATUS.bit.SYNCBUSY); // Wait for synchronization | |
REG_TC4_COUNT8_CC0 = 0x0A; // Set the TC4 CC0 register to some arbitary value | |
//TC4->COUNT8.CC[0].reg = 0x04; | |
while (TC4->COUNT8.STATUS.bit.SYNCBUSY); // Wait for synchronization | |
REG_TC4_COUNT8_CC1 = 0xAA; // Set the TC4 CC1 register to some arbitary value | |
while (TC4->COUNT8.STATUS.bit.SYNCBUSY); // Wait for synchronization | |
REG_TC4_COUNT8_PER = 0xFF; // Set the PER (period) register to its maximum value | |
while (TC4->COUNT8.STATUS.bit.SYNCBUSY); // Wait for synchronization | |
//NVIC_DisableIRQ(TC4_IRQn); | |
//NVIC_ClearPendingIRQ(TC4_IRQn); | |
NVIC_SetPriority(TC4_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority for TC4 to 0 (highest) | |
NVIC_EnableIRQ(TC4_IRQn); // Connect TC4 to Nested Vector Interrupt Controller (NVIC) | |
REG_TC4_INTFLAG |= TC_INTFLAG_MC1 | TC_INTFLAG_MC0 | TC_INTFLAG_OVF; // Clear the interrupt flags | |
REG_TC4_INTENSET = TC_INTENSET_MC1 | TC_INTENSET_MC0 | TC_INTENSET_OVF; // Enable TC4 interrupts | |
// REG_TC4_INTENCLR = TC_INTENCLR_MC1 | TC_INTENCLR_MC0 | TC_INTENCLR_OVF; // Disable TC4 interrupts | |
//REG_TC4_CTRLA |= TC_CTRLA_WAVEGEN_MFRQ; | |
//while (TC4->COUNT8.STATUS.bit.SYNCBUSY); | |
REG_TC4_CTRLA |= TC_CTRLA_PRESCALER_DIV1 | // Set prescaler to 64, 16MHz/64 = 256kHz | |
TC_CTRLA_ENABLE; // Enable TC4 | |
while (TC4->COUNT8.STATUS.bit.SYNCBUSY); // Wait for synchronization | |
analogWriteResolution(8); | |
} | |
void loop() { | |
// put your main code here, to run repeatedly: | |
//analogWrite(A0, sine_wave[REG_TC4_COUNT8_COUNT]); | |
analogWrite(A0, sine_wave[t]); | |
} | |
void TC4_Handler() // Interrupt Service Routine (ISR) for timer TC4 | |
{ | |
// Check for overflow (OVF) interrupt | |
if (TC4->COUNT8.INTFLAG.bit.OVF && TC4->COUNT8.INTENSET.bit.OVF) | |
{ | |
//t++; | |
REG_TC4_INTFLAG = TC_INTFLAG_OVF; // Clear the OVF interrupt flag | |
} | |
// Check for match counter 0 (MC0) interrupt | |
if (TC4->COUNT8.INTFLAG.bit.MC0 && TC4->COUNT8.INTENSET.bit.MC0) | |
{ | |
// Put your counter compare 0 (CC0) code here: | |
// ... | |
t++; | |
//REG_TC4_INTFLAG = TC_INTFLAG_MC0; // Clear the MC0 interrupt flag | |
TC4->COUNT8.INTFLAG.bit.MC0 = 1; | |
} | |
// Check for match counter 1 (MC1) interrupt | |
if (TC4->COUNT8.INTFLAG.bit.MC1 && TC4->COUNT8.INTENSET.bit.MC1) | |
{ | |
// Put your counter compare 1 (CC1) code here: | |
// ... | |
//t++; | |
REG_TC4_INTFLAG = TC_INTFLAG_MC1; // Clear the MC1 interrupt flag | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment