Stap 3: PWM Code
De eerste stap is om de Golf-tabel te maken. De tabel wordt opgeslagen in het RAM Atmega328 met behulp van de pgmspace-bibliotheek. Elke tabel Golf heeft 256 waarden van 0 tot 255, zodat elke waarde kan worden toegewezen aan een gegevenstype byte. De definitie van de sinus is hieronder weergegeven. Elke waarde is de amplitude van de Golf op een bepaald tijdstip. Dit vertegenwoordigt een periode van de Golf. Hoe hoger de frequentie die wordt gespeeld, hoe sneller de programmastappen via de tabel.#include "avr/pgmspace.h"
Golfvorm definities
PROGMEM prog_uchar waveTable [] {} =
sinusgolf
0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,
15,16,18,20,21,23,25,27,29,31,33,35,37,39,
42,44,46,49,51,54,56,59,62,64,67,70,73,76,
78,81,84,87,90,93,96,99,102,105,108,111,115,
118,121,124,127,130,133,136,139,143,146,149,
152,155,158,161,164,167,170,173,176,178,181,
184,187,190,192,195,198,200,203,205,208,210,
212,215,217,219,221,223,225,227,229,231,233,
234,236,238,239,240,242,243,244,245,247,248,
249,249,250,251,252,252,253,253,253,254,254,
254,254,254,254,254,253,253,253,252,252,251,
250,249,249,248,247,245,244,243,242,240,239,
238,236,234,233,231,229,227,225,223,221,219,
217,215,212,210,208,205,203,200,198,195,192,
190,187,184,181,178,176,173,170,167,164,161,
158,155,152,149,146,143,139,136,133,130,127,
124,121,118,115,111,108,105,102,99,96,93,90,
87,84,81,78,76,73,70,67,64,62,59,56,54,51,49,
46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,
16,15,14,12,11,10,9,7,6,5,5,4, 3,2,2,1,1,1,0,0,0,
};
Als u op de Arduino maken het PWM-signaal, moet de timer correct worden geïnitialiseerd. Voor dit gebruikte ik de C methode instellen van de timer zodat ik het beter kan controleren. De timer wordt gemaakt, zodat er een 32 kHz sampling rate voor onze audio en de output van het signaal op 11 van de Arduino geplaatst. Mij ook in staat stellen een overflow interrupt, zodat wanneer de timer-waarde meer dan 255 gaat, de interrupt wordt gegenereerd.
VOID Setup_timer2() {}
Timer2 klok Prescaler aan: 1
SBI (TCCR2B, CS20);
CBI (TCCR2B, CS21);
CBI (TCCR2B, CS22);
Timer2 PWM modus ingesteld op de juiste PWM fase
CBI (TCCR2A, COM2A0); duidelijk vergelijk Match
SBI (TCCR2A, COM2A1);
SBI (TCCR2A, WGM20); Modus 1 / fase Correct PWM
CBI (TCCR2A, WGM21);
CBI (TCCR2B, WGM22);
}
Dit is de overflow interrupt. Wanneer de interrupt optreedt bereken ik de volgende waarde die moet worden getrokken uit de tabel Golf en schrijf die waarde naar pin 11. Een variabele met de naam van de accumulator fase houdt spoor van waar het programma is in de tabel.
ISR(TIMER2_OVF_vect)
{
phaccu = phaccu + tword_m; zachte DDS, fase accu met 32 bits
icnt = phaccu >> 24; gebruik van de hogere 8 bits voor fase accu als frequentie informatie
waarde fron ROM sinus tabel lezen en verzenden van PWM DAC
OCR2A = pgm_read_byte_near (waveTable + icnt + (waveSelect << 8));
Als (icnt1 ++ == 125) {/ / verhogen variabele c4ms alle 4 milliseconden
c4ms ++;
icnt1 = 0;
}
}
Dat waarde wordt berekend met behulp van een tuning woord dat wordt gevonden door de frequentie die u wilt verdelen door de klok van een verwijzing, in dit geval de 32kHz verwijzing klok.
Const dubbele refclk = 31376.6; gemeten
tword_m = pow (2,32) * dfreq/refclk; calulate DDS nieuwe tuning woord