Das Programm nimmt zwei Zählerstände am Anfang und am Ende einer Schwingung auf und speichert sie in d1 und d2. In der Wartezeit zwischen den Flanken kann in aller Ruhe der Timer selbst ausgelesen werden, um ein Timeout zu erkennen. Der Timer sollte nämlich niemals mehr als 65000 erreichen, außer wenn die Modulation abgeschaltet wurde. Aus der Periodendauer wurde dann die Frequenz f berechnet. Zur Probe wurden Messwerte der Frequenz seriell ausgegeben. Das Ergebnis an einem analogen Sinusgenerator zeigt eine Zuverlässigkeit im Bereich 0,1 Hz, was sogar für WSPR reichen sollte.
Config Timer1 = Timer , Prescale = 1
start Timer1
TCCR1B = &H81 ' Timer1, Vorteiler 1, ICNC1: Input Capture Noise Canceler
ACSR.ACIC = 1 ' Analog Comparator als Input
do
timer1 = 0
while ACSR.ACO =0
if Timer1 > 65000 then exit while
wend
timer1 = 0
while ACSR.ACO=1
if Timer1 > 65000 then exit while
wend
d1 = ICR1
while ACSR.ACO=0
if Timer1 > 65000 then exit while
wend
while ACSR.ACO=1
if Timer1 > 65000 then exit while
wend
if timer1 < 65000 then
Regaddr = 3
Regdata = 6 ' CLK0 an
Call Siout(regaddr , Regdata) 'enable outputs
d2= icr1
d = d2-d1
f= 16000000/d
'print f
dd = f
Gfreq = 7074000+ dd
Clk = 0
Setfreq
else
Regaddr = 3
Regdata = 5 ' CLK1 an
Call Siout(regaddr , Regdata) 'enable outputs
end if
loop
// Modulationsfrequenz messen über Analog Comparator Pin7 = AN1Ein Problem war noch zu lösen: Wenn ich das SDR-Shield zusammen mit dem LCD-Shield von Elektor verwende, belegt dieses die benötigten Leitungen PD6 und PD7. Die oberen vier Leitungen sind der LCD-Datenbus mit den Leitungen D4 bis D7. Ein Test hat aber gezeigt, dass man sich die Ports leihen kann, wenn gerade keine LCD-Ausgabe ansteht. Allerdings hat das LCD anscheinend selbst interne Pullup-Widerstände, sodass ein offener Eingang hoch liegt. Deshalb musste ich den Vergleichspegel des Komparators in Richtung VCC verlegen. PD6 wird deshalb hochgeschaltet und dient als virtuelle Masse für das Tiefpassfilter.
TCCR1A = 0x00;
TCCR1B = 0x01; // Timer1 Timer 16 MHz, ICNC1: Input Capture Noise Canceler
TCCR1B = 0x81; // Timer1 Timer 16 MHz, ICNC1: Input Capture Noise Canceler
ACSR |= (1<<ACIC); // Analog Comparator Capture Input
pinMode(7, INPUT); //PD7 = AN1 = HiZ, PD6 = AN0 = 0
digitalWrite (7,1);
digitalWrite (6,1);
delay(2);
unsigned int d1,d2;
int FSK = 10;
int FSKtx = 0;
while (FSK>0){
TCNT1 = 0;
while (ACSR &(1<<ACO)){
if (TCNT1>65000) {break;
}
} while ((ACSR &(1<<ACO))==0){
if (TCNT1>65000) {break;}
}
TCNT1 = 0;
while (ACSR &(1<<ACO)){
if (TCNT1>65000) {break;}
}
d1 = ICR1;
while ((ACSR &(1<<ACO))==0){
if (TCNT1>65000) {break;}
}
while (ACSR &(1<<ACO)){
if (TCNT1>65000) {break;}
}
d2 = ICR1;
if (TCNT1 < 65000){
unsigned long codefreq = 1600000000/(d2-d1);
// d1 = codefreq /10;
// Serial.println(d1);
// delay (500);
if (codefreq < 350000){
if (FSKtx == 0){
digitalWrite (txOn,1); //Relais
digitalWrite (keyOut,1); //keyOut
si5351.output_enable(SI5351_CLK2, 1);
si5351.output_enable(SI5351_CLK1, 0); //RX off
}
si5351.set_freq((freqTX * 100 + codefreq), SI5351_CLK2);
FSKtx = 1;
}
}
else{
FSK--;
}
si5351.output_enable(SI5351_CLK2, 0);
si5351.output_enable(SI5351_CLK1, 1); //RX on
digitalWrite (txOn,0); //Relais
digitalWrite (keyOut,0); //keyOut
pinMode(7, OUTPUT); //LCD
digitalWrite (7,0);
digitalWrite (7,0);
FSKtx = 0;
}
}