After some extra reading I was able to understand how the tuning word (m) works.
I'm still having trouble understanding how to choose the proper reference clock.
I also moved on to implementing some other features such as buttons to increase and decrease voltage,
as well as changing the waveform. I've stumbled upon some new issues I'm currently stuck on.
When I'm running my code for some reason the code does not enter into the main loop, and
the cause of this is the interrupt where the output is generated. I'm not sure if there is something
I'm missing or I'm utilizing the interrupt improperly. I updated my old code to work with 8 bits instead,
for the increased accuracy I was receiving (until I can figure out the ref clock).
Here is my updated code (sorry for it being so long)
//Main Program Function Generator
#define ss 47
/*Slave Select Definitions*/
//ss - on pin 47 - Sending Waveforms
#define SignalSelection 2
#define FreqInc10 3
#define FreqInc100 4
#define FreqDec10 5
#define FreqDec100 6
/*Button Definitions*/
//button on pin 2
//button on pin 3
//button on pin 4`
//button on pin 5
//button on pin 6
LiquidCrystal lcd(24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34);// Initialize number of LCD data pins
Bounce bouncer = Bounce(SignalSelection, 10); //Create Debounce on button with 10ns
Bounce bouncer1 = Bounce(FreqInc10, 10); //Create Debounce on button with 10ns
Bounce bouncer2 = Bounce(FreqInc100, 10); //Create Debounce on button with 10ns
Bounce bouncer3 = Bounce(FreqDec10, 10); //Create Debounce on button with 10ns
Bounce bouncer4 = Bounce(FreqDec10, 10); //Create Debounce on button with 10ns
int SignalSelect ; //Store Pin Value
int IncFreq10 ;//Store Pin Value
int IncFreq100 ;//Store Pin Value
int DecFreq10 ;//Store Pin Value
int DecFreq100 ;//Store Pin Value
void writeDataFG(word val) ; //Used to write to Data -waveforms-
void setTimer() ; //Time for checking for overflow
word outVal = 0;
int freq = 250 ;
double refFrequency = 31376.6 ; //8 bit
unsigned long int tuningWordM;
long int phaseAccumulator ;
byte phaseAccumulatorMSBs ;
int signal = 0 ;
void setup()
{
Serial.begin(115200);
pinMode(ss, OUTPUT); //Slave Select -Sending Waveforms-
pinMode(ss2, OUTPUT); //Slave Select -DC Offset-
pinMode(ss3, OUTPUT); //Slave Select -Digi Pot-
pinMode(SignalSelection, INPUT) ; //Set pin as input
pinMode(FreqInc10, INPUT) ; //Set pin as input
pinMode(FreqInc100, INPUT) ; //Set pin as input
pinMode(FreqDec10, INPUT) ; //Set pin as input
pinMode(FreqDec100, INPUT) ; //Set pin as input
pinMode(SignalSelection, HIGH) ; //enable pullup
pinMode(FreqInc10, HIGH) ; //enable pullup
pinMode(FreqInc100, HIGH) ; //enable pullup
pinMode(FreqDec10, HIGH) ; //enable pullup
pinMode(FreqDec100, HIGH) ; //enable pullup
SPI.begin() ; //wake up spi bus
digitalWrite(ss, HIGH) ; //Set to master mode
//setTimer() ; //Initialize Timer
tuningWordM = ((pow(2, 32) * freq) / refFrequency); //Calculate initial tuning word
}
void writeDataFG(word val)
{
digitalWrite(ss, LOW);
byte holder = highByte(val) ;
holder = 0b00001111 & holder ; //Clear 4 MSB for config data
holder = 0b00110000 | holder ; //Add config data and 4 bits data
SPI.transfer(holder) ;
holder = lowByte(val) ;
SPI.transfer(holder) ;
digitalWrite(ss, HIGH) ;
}
void setTimer()
{
// Disable interrupts while setting registers
noInterrupts() ; //disable all interrupts
TCCR2A = 0;//Initialize Register A to 0
TCCR2B = 0;//Initialize Register B to 0
TCCR2B|= (1 << WGM22);//CTC Mode -Clear Timer on Compare Match (CTC) Mode-
TCCR2B |= (1 << CS20); // Prescaler x1
ASSR &= ~(1 << AS2);// Use system clock for Timer/Counter2
TIMSK2 = 0; // Reset Timer/Counter2 Interrupt Mask Register
TIMSK2 |= (1 << OCIE2A);// Enable Output Compare Match A Interrupt
interrupts(); //enable all interrupts
//OCR2A = 4;// Set compared value
}
ISR(TIMER2_COMPA_vect){
phaseAccumulator += tuningWordM; // Update phase accumulator counter, the phase accumulator will automatically overflow at 2^32
phaseAccumulatorMSBs = (phaseAccumulator >> 24); // Use the 8 MSBs from phase accumulator as frequency information
//If you want 10 bit shift by 22 and change BYTE to WORD
//phaseAccumulatorMSBs = phaseAccumulatorMSBs & 0x03FF ;
//The un-used 6 upper bits must be clear to ensure no random information
if(signal == 0)
{
outVal = sawtoothLookup[phaseAccumulatorMSBs];
outVal = outVal << 4 ;
writeDataFG(outVal) ;
}
else if(signal == 1)
{
outVal = squareLookup[phaseAccumulatorMSBs];
outVal = outVal << 4 ;
writeDataFG(outVal) ;
}
else if(signal == 2)
{
outVal = triangleLookup[phaseAccumulatorMSBs];
outVal = outVal << 4 ;
writeDataFG(outVal) ;
}
else if(signal == 3)
{
outVal = sawtoothLookup[phaseAccumulatorMSBs];
outVal = outVal << 4 ;
writeDataFG(outVal) ;
}
else
{
outVal = revsawtoothLookup[phaseAccumulatorMSBs];
outVal = outVal << 4 ;
writeDataFG(outVal) ;
}
}
void loop()
{
if((bouncer.update() == true) || ( bouncer1.update() == true) ||
(bouncer2.update() == true) || (bouncer3.update() == true) ||
(bouncer4.update() == true))
{ //check to see if any button changed state
SignalSelect = bouncer.read() ;//read debounced pin
IncFreq10 = bouncer1.read() ;//read debounced pin
IncFreq100 = bouncer2.read() ;//read debounced pin
DecFreq10 = bouncer3.read() ;//read debounced pin
DecFreq100 = bouncer4.read() ;//read debounced pin
if(SignalSelect == HIGH)
{
if(signal == 4)
{
signal = 0 ;//Only 5 total waves
}
else
{
signal = signal + 1 ;
}
if(signal == 0)
{
lcd.setCursor(15,0) ; //Set cursor to position 15 row 1
lcd.print("SineWave");
}
else if(signal == 1)
{
lcd.setCursor(15,0) ; //Set cursor to position 15 row 1
lcd.print(" Square ");
}
else if(signal == 2)
{
lcd.setCursor(15,0) ; //Set cursor to position 15 row 1
lcd.print("Triangle");
}
else if(signal == 3)
{
lcd.setCursor(15,0) ; //Set cursor to position 15 row 1
lcd.print("SawTooth");
}
else
{
lcd.setCursor(15,0) ; //Set cursor to position 15 row 1
lcd.print("RevSawTh");
}
}
else if(IncFreq10 == HIGH)
{
freq = freq + 10 ;
tuningWordM = ((pow(2, 32) * freq) / refFrequency); //calculate new tuning word
}
else if(IncFreq100 == HIGH)
{
freq = freq + 100 ;
tuningWordM = ((pow(2, 32) * freq) / refFrequency); //calculate new tuning word
}
else if(DecFreq10 == HIGH)
{
freq = freq - 10 ;
tuningWordM = ((pow(2, 32) * freq) / refFrequency); //calculate new tuning word
}
else if(DecFreq100 == HIGH)
{
freq = freq - 100 ;
tuningWordM = ((pow(2, 32) * freq) / refFrequency); //calculate new tuning word
}
else
{
//do nothing
}
}