Oke, na veel zoeken en lezen kom ik eigenlijk sturctureel een oplossing tegen waarbij in de timer interupt een counter(accumulator) word gebruikt met IF statements. Aangezien de meeste DDS maar 1 frequentie hoeven te maken zie je in de interupt dus ook maar 1 accumulator.
In mijn geval zou ik dus 5 accumulators toepassen in de timer interupt. In onderstaande code (die ik op basis van een arduino voorbeeld heb aangepast) heb ik 1 accumulator gemaakt op basis van "t". Deze kan ik natuurlijk uitbreiden met "q", "x", "y" en "z":
Toch ben ik wel nieuwschierig naar uw opmerking betreffende modulo deling. Enige wat ik me hierbij kan voorstellen is als volgt:
1 accumulator -> "test"
door "test" te delen door modulo "period" komt een getal, alleen bij een heel getal is een periode voorbij en kan er een pulse gegeven worden.
Hierbij moet je dan wel kunnen detecteren dat het een heel getal is.
Zelf heb ik in mijn opleiding nooit echt veel met mod gedaan en alles wat ik heb gedaan is heel lang geleden. Internet kon me niet direct in de goede richting sturen dus wellicht kan u me het verduidelijken.
Verder kan ik dus de 5 fan accumulatoren gebruiken in de timer, maar ook een accumulator toevoegen om elke 1000ms een update van de frequency te doen, zodat deze ook niet meer in de main loop wordt uitgevoerd en als ik alles goed begrepen heb efficienter zou zijn.
alle feedback is welkom.
[code=C]
#ifndef F_CPU
#define F_CPU 20000000UL
#endif
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <stdlib.h>
//variables for PW pot monitoring
float pulseWidth;
int pulseWidthScaled;
int PWCurrent;
uint8_t PWTolerance = 8; //adjust this to increase/decrease stability of PW measurement
//variables for freq pot monitoring
int frequency;
int freqCurrent;
uint8_t freqTolerance = 2; //adjust this to increase/decrease stability of frequency measurement
unsigned int freqscaled;
long t;
long samplerate;
long period;
uint16_t Average_RPM = 10000; // Default RPM to start with
uint16_t Average_PW = 10; // Pulsewidth
void init_Timer() {
//TIMER INTERRUPT SETUP
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
// set compare match register- 100khz to start
OCR1A = 199; // = (20 000 000 / 100 000) - 1 = 159
TCCR1B |= (1 << WGM12); // turn on CTC mode
TCCR1B |= (1 << CS10); // Set CS10 bit for 0 pre-scaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
}
void init_Main(){
samplerate = 100000; // 100khz
//initialize variables
frequency = Average_RPM / 60 ; // initialize frequency from fan
period = samplerate/frequency; // Calculate 1 period versus complete samplerate
pulseWidth = Average_PW;
pulseWidthScaled = Average_PW*period; // Calculate length of pulse during period
}
void init_Ports(){
//set port/pin mode
DDRD |= (1<<DDD3); // set LED pin PD1 to output
}
void checkFreq() { // Function to be triggered if frequency needs to be adjusted during runtime
freqCurrent = Average_RPM / 60 ; // FAN RPM
if (abs(freqCurrent-frequency)>freqTolerance){ // if new value exceeds tolerance
frequency = freqCurrent; // new frequency
period = samplerate/frequency; // Calculate 1 period versus complete samplerate
pulseWidthScaled = Average_PW*period; // Calculate length of pulse during period
}
}
void checkPW() { // Function to be triggered if pulse width needs to be adjusted during runtime
PWCurrent = Average_PW;
if (abs(PWCurrent-pulseWidth)>PWTolerance){ // if new value exceeds tolerance
pulseWidth = PWCurrent; // new pulse width
pulseWidthScaled = Average_PW*period; // Calculate length of pulse during period
}
}
ISR(TIMER1_COMPA_vect){ // timer 1 interrupt
// increment t and reset each time it reaches period
t++;
if (t >= period){
t = 0;
}
if (pulseWidthScaled <= t && (!PD3)) { // Tijdelijk een loop voor pulse width en period, ligt eraan
PORTD |= (1<<PD3); // of een (enkele) pulse wordt gedetecteerd door het mobo
} // In dat geval is alleen de period voldoende en bij de start van de period
else if (PD3 && t > pulseWidthScaled){ // een pulse.
PORTD &= ~(1<<PD3);
}
}
int main(void)
{
cli(); // disable interrupts
init_Timer(); // initialize timer
init_Main(); // initialize startup variables
init_Ports(); // initialize ports
sei(); // enable interrupts
while (1) {
}
}
[/code]