#define MAX_COUNT 308 // (16 MHz / SW_FREQ) / 2 = 16000000 / 26000 = 615 / 2 = 308
#define NO_OF_PULSES 260 // 26 kHz / 50 Hz = 520; 520 / 2 = 260 pulses in one half-cycle
const int lookUp[NO_OF_PULSES] = {
0, 4, 7, 11, 15, 19, 22, 26, 30, 33, 37, 41, 45, 48,
52, 56, 59, 63, 66, 70, 74, 77, 81, 84, 88, 92, 95,
99, 102, 106, 109, 113, 116, 120, 123, 126, 130, 133,
137, 140, 143, 146, 150, 153, 156, 159, 163, 166, 169,
172, 175, 178, 181, 184, 187, 190, 193, 196, 199, 201,
204, 207, 210, 212, 215, 218, 220, 223, 226, 228, 231,
233, 235, 238, 240, 242, 245, 247, 249, 251, 253, 256,
258, 260, 262, 264, 265, 267, 269, 271, 273, 274, 276,
278, 279, 281, 282, 284, 285, 287, 288, 289, 291, 292,
293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 302,
303, 304, 304, 305, 305, 306, 306, 307, 307, 307, 307,
308, 308, 308, 308, 308, 308, 308, 308, 308, 307, 307,
307, 307, 306, 306, 305, 305, 304, 304, 303, 302, 302,
301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291,
289, 288, 287, 285, 284, 282, 281, 279, 278, 276, 274,
273, 271, 269, 267, 265, 264, 262, 260, 258, 256, 253,
251, 249, 247, 245, 242, 240, 238, 235, 233, 231, 228,
226, 223, 220, 218, 215, 212, 210, 207, 204, 201, 199,
196, 193, 190, 187, 184, 181, 178, 175, 172, 169, 166,
163, 159, 156, 153, 150, 146, 143, 140, 137, 133, 130,
126, 123, 120, 116, 113, 109, 106, 102, 99, 95, 92, 88,
84, 81, 77, 74, 70, 66, 63, 59, 56, 52, 48, 45, 41, 37,
33, 30, 26, 22, 19, 15, 11, 7, 4
};
const int lookUp2[NO_OF_PULSES] = {
1, 5, 8, 12, 16, 20, 23, 27, 31, 34, 38, 42, 46, 49, 53,
57, 60, 64, 67, 71, 75, 78, 82, 85, 89, 93, 96, 100, 103,
107, 110, 114, 117, 121, 124, 127, 131, 134, 138, 141, 144,
147, 151, 154, 157, 160, 164, 167, 170, 173, 176, 179, 182,
185, 188, 191, 194, 197, 200, 202, 205, 208, 211, 213, 216,
219, 221, 224, 227, 229, 232, 234, 236, 239, 241, 243, 246,
248, 250, 252, 254, 257, 259, 261, 263, 265, 266, 268, 270,
272, 274, 275, 277, 279, 280, 282, 283, 285, 286, 288, 289,
290, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302,
303, 303, 304, 305, 305, 306, 306, 307, 307, 308, 308, 308,
308, 309, 309, 309, 309, 309, 309, 309, 309, 309, 308, 308,
308, 308, 307, 307, 306, 306, 305, 305, 304, 303, 303, 302,
301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 290, 289,
288, 286, 285, 283, 282, 280, 279, 277, 275, 274, 272, 270,
268, 266, 265, 263, 261, 259, 257, 254, 252, 250, 248, 246,
243, 241, 239, 236, 234, 232, 229, 227, 224, 221, 219, 216,
213, 211, 208, 205, 202, 200, 197, 194, 191, 188, 185, 182,
179, 176, 173, 170, 167, 164, 160, 157, 154, 151, 147, 144,
141, 138, 134, 131, 127, 124, 121, 117, 114, 110, 107, 103,
100, 96, 93, 89, 85, 82, 78, 75, 71, 67, 64, 60, 57, 53, 49,
46, 42, 38, 34, 31, 27, 23, 20, 16, 12, 8, 5
};
volatile bool positiveHalf = false;
volatile bool positiveHalf3 = false;
void setup()
{
pinMode(2, OUTPUT);
pinMode(5, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(50, OUTPUT);
// Timer1 Registers initialisation, see datasheet for more detail.
TCCR1A = 0;
TCCR1B = 0;
TCCR3A = 0;
TCCR3B = 0;
TCCR1A = 0b10110000; // Set OC1A (pin D9) on Compare Match; Disconnect OC1B (pin D10); PWM, Phase and Frequency Correct (Mode 8);
TCCR1B = 0b00010001; // PWM, Phase and Frequency Correct (Mode 8); Clock Select = System clock (No Prescaling) [Ref. Data Sheet, p. 132]
ICR1 = MAX_COUNT; // Period for 16MHz crystal, for a switching frequency of 16 kHz for 320 subdevisions per 50 Hz sin wave cycle.
TCCR3A = 0b10110000; // Set OC1A (pin D9) on Compare Match; Disconnect OC1B (pin D10); PWM, Phase and Frequency Correct (Mode 8);
TCCR3B = 0b00010001; // PWM, Phase and Frequency Correct (Mode 8); Clock Select = System clock (No Prescaling) [Ref. Data Sheet, p. 132]
ICR3 = MAX_COUNT; // Period for 16MHz crystal, for a switching frequency of 16 kHz for 320 subdevisions per 50 Hz sin wave cycle.
OCR1A = lookUp[0];
OCR1B = lookUp2[0];
OCR3A = lookUp[0];
OCR3B = lookUp2[0];
TIMSK1 = 0b00000001; // TOIE1 = 1: Overflow Interrupt Enable
TIMSK3 = 0b00000001; // TOIE3 = 1: Overflow Interrupt Enable
sei(); // Enable global interrupts.
}
void loop()
{
// place any code you want
}
ISR(TIMER1_OVF_vect)
{
static int i = 1; // Static means it will NOT be reinitialized
if (i >= NO_OF_PULSES) {
i = 0;
}
if (positiveHalf == true) {
OCR1A = lookUp[i];
OCR1B = lookUp2[i];
} else {
OCR1A = 0;
OCR1B = 0;
}
if (i == 1) {
positiveHalf = !positiveHalf;
OCR1A = 0;
OCR1B = 0;
}
i++;
}
ISR(TIMER3_OVF_vect)
{
static int j = 1; // Static means it will NOT be reinitialized
if (j >= NO_OF_PULSES) {
j = 0;
}
if (positiveHalf3 == false) {
OCR3A = lookUp[j];
OCR3B = lookUp2[j];
} else {
OCR3A = 0;
OCR3B = 0;
}
if (j == 1) {
positiveHalf3 = !positiveHalf3;
OCR3A = 0;
OCR3B = 0;
}
j++;
}