Last active
May 30, 2019 18:27
-
-
Save kbob/6d886d63825c6ad0d29829e270f6ef9f to your computer and use it in GitHub Desktop.
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
// Ask Hackaday: How do you DIY a Top-Octave Generator? | |
// https://hackaday.com/2018/05/24/ask-hackaday-diy-top-octave-generator/?utm_source=feedburner | |
// Target Arduino Mega. | |
// N.B., Timer 1 has highest interrupt priority, so | |
// use it for the highest frequency oscillators. | |
// Note Comp Port/Pin Arduino Pin | |
// C OC1A PB5 pin 11 | |
// B OC1B PB6 pin 12 | |
// A# OC1C PB7 pin 13 | |
// A OC3A PE3 pin 5 | |
// G# OC3B PE4 pin 2 | |
// G OC3C PE5 pin 3 | |
// F# OC4A PH3 pin 6 | |
// F OC4B PH4 pin 7 | |
// E OC4C PH5 pin 8 | |
// D# OC5A PL3 pin 46 | |
// D OC5B PL4 pin 45 | |
// C# OC5C PL5 pin 44 | |
#define RND(a, b) (((a) + (b) / 2) / (b)) | |
#define OCR1A_COUNT (RND(F_CPU, 8372)) | |
#define OCR1B_COUNT (RND(F_CPU, 7902)) | |
#define OCR1C_COUNT (RND(F_CPU, 7459)) | |
#define OCR3A_COUNT (RND(F_CPU, 7040)) | |
#define OCR3B_COUNT (RND(F_CPU, 6645)) | |
#define OCR3C_COUNT (RND(F_CPU, 6272)) | |
#define OCR4A_COUNT (RND(F_CPU, 5920)) | |
#define OCR4B_COUNT (RND(F_CPU, 5588)) | |
#define OCR4C_COUNT (RND(F_CPU, 5274)) | |
#define OCR5A_COUNT (RND(F_CPU, 4978)) | |
#define OCR5B_COUNT (RND(F_CPU, 4699)) | |
#define OCR5C_COUNT (RND(F_CPU, 4435)) | |
void setup() | |
{ | |
// Start Timer/Counter 1. | |
TCCR1A = _BV(COM1A0) | _BV(COM1B0) | _BV(COM1C0); | |
TCCR1B = _BV(CS10); | |
TCCR1C = 0; | |
OCR1A = OCR1A_COUNT; | |
OCR1B = OCR1B_COUNT; | |
OCR1C = OCR1C_COUNT; | |
TIMSK1 = _BV(OCIE1C) | _BV(OCIE1B) | _BV(OCIE1A); | |
// Start Timer/Counter 3. | |
TCCR3A = _BV(COM3A0) | _BV(COM3B0) | _BV(COM3C0); | |
TCCR3B = _BV(CS30); | |
TCCR3C = 0; | |
OCR3A = OCR3A_COUNT; | |
OCR3B = OCR3B_COUNT; | |
OCR3C = OCR3C_COUNT; | |
TIMSK3 = _BV(OCIE3C) | _BV(OCIE3B) | _BV(OCIE3A); | |
// Start Timer/Counter 4. | |
TCCR4A = _BV(COM4A0) | _BV(COM4B0) | _BV(COM4C0); | |
TCCR4B = _BV(CS40); | |
TCCR4C = 0; | |
OCR4A = OCR4A_COUNT; | |
OCR4B = OCR4B_COUNT; | |
OCR4C = OCR4C_COUNT; | |
TIMSK4 = _BV(OCIE4C) | _BV(OCIE4B) | _BV(OCIE4A); | |
// Start Timer/Counter 5. | |
TCCR5A = _BV(COM5A0) | _BV(COM5B0) | _BV(COM5C0); | |
TCCR5B = _BV(CS50); | |
TCCR5C = 0; | |
OCR5A = OCR5A_COUNT; | |
OCR5B = OCR5B_COUNT; | |
OCR5C = OCR5C_COUNT; | |
TIMSK5 = _BV(OCIE5C) | _BV(OCIE5B) | _BV(OCIE5A); | |
// Enable output on pins. | |
DDRB |= _BV(DDB5); | |
DDRB |= _BV(DDB6); | |
DDRB |= _BV(DDB7); | |
DDRE |= _BV(DDE3); | |
DDRE |= _BV(DDE4); | |
DDRE |= _BV(DDE5); | |
DDRH |= _BV(DDH3); | |
DDRH |= _BV(DDH4); | |
DDRH |= _BV(DDH5); | |
DDRL |= _BV(DDL3); | |
DDRL |= _BV(DDL4); | |
DDRL |= _BV(DDL5); | |
// Disable millisecond timer. | |
TIMSK0 = 0; | |
} | |
void loop() | |
{ | |
__asm__ ( "sleep" ); | |
} | |
ISR(TIMER1_COMPA_vect) | |
{ | |
OCR1A += OCR1A_COUNT; | |
} | |
ISR(TIMER1_COMPB_vect) | |
{ | |
OCR1B += OCR1B_COUNT; | |
} | |
ISR(TIMER1_COMPC_vect) | |
{ | |
OCR1C += OCR1C_COUNT; | |
} | |
ISR(TIMER3_COMPA_vect) | |
{ | |
OCR3A += OCR3A_COUNT; | |
} | |
ISR(TIMER3_COMPB_vect) | |
{ | |
OCR3B += OCR3B_COUNT; | |
} | |
ISR(TIMER3_COMPC_vect) | |
{ | |
OCR3C += OCR3C_COUNT; | |
} | |
ISR(TIMER4_COMPA_vect) | |
{ | |
OCR4A += OCR4A_COUNT; | |
} | |
ISR(TIMER4_COMPB_vect) | |
{ | |
OCR4B += OCR4B_COUNT; | |
} | |
ISR(TIMER4_COMPC_vect) | |
{ | |
OCR4C += OCR4C_COUNT; | |
} | |
ISR(TIMER5_COMPA_vect) | |
{ | |
OCR5A += OCR5A_COUNT; | |
} | |
ISR(TIMER5_COMPB_vect) | |
{ | |
OCR5B += OCR5B_COUNT; | |
} | |
ISR(TIMER5_COMPC_vect) | |
{ | |
OCR5C += OCR5C_COUNT; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment