Programmierbarer Quarzgenerator

Elektronik-Labor   Projekte   AVR 



Wenn man mal einen ganz bestimmten Quarz braucht ist er meistens gerade nicht da. Und manche Frequenzen sind auch nicht zu kaufen. Eine Spezialanfertigung ist jederzeit möglich, aber für Einzelstücke sehr teuer. Also braucht man einen programmierbaren Quarzoszillator. Es gab für diesen Zweck mal den CY27EE16, der z.B. im Elektor-SDR verwendet wurde. Aber leider wird dieses IC nicht mehr gebaut. Bei Modul-Bus gibt es noch den programmierbaren Taktoszillator mit einem ICS307-2 für den Bereich 2 MHz bis 120 MHz. Allerdings fehlt diesem die Fähigkeit, eine eingestellte Frequenz zu speichern. Wenn man aber einen kleinen Mikrocontroller wie den Tiny13 davorsetzt, könnte dieser ja eine Einstellung speichern und beim nächsten Einschalten verwenden. Das wäre dann wirklich ein programmierbarer Quarzgenerator.


 Der PLL-Taktgenerator ICS307-2

Der Tiny13 steuert hier direkt die drei Leitungen Data, Sclk und Strobe des Taktgenerators. Im ersten Test wurde dazu der DB9-Stecker verwendet, d.h. die Portleitungen ersetzen direkt die entsprechenden Ausgangsleitungen der RS232. Der Tiny13 muss nun genau die Daten schicken, die vorher direkt vom PC kamen. Es handelt sich um insgesamt 24 Bits, die in drei Steuerbytes liegen. Diese Bytes werden entweder direkt empfangen und in den Generator getaktet oder aber ins EEPROM des Tiny13 geladen, wo sie beim nächsten Start ausgelesen werden.

'ICS307-2
'Data (TXD),PB4, Clock (RTS),PB3, Strobe (DTR) PB0

$regfile = "attiny13.dat"
$crystal = 1200000
$hwstack = 8
$swstack = 16
$framesize = 16

Declare Sub Ics307

Ddrb = &B0011011
Portb = 0

Open "comb.2:9600,8,n,1,INVERTED" For Input As #1

Dim B0 As Byte
Dim B1 As Byte
Dim B2 As Byte
Dim B3 As Byte

Readeeprom B1 , 11
Readeeprom B2 , 12
Readeeprom B3 , 13
Ics307

Do
Get #1 , B0
If B0 = 65 Then
Get #1 , B1
Get #1 , B2
Get #1 , B3
Ics307
End If
If B0 = 66 Then
'MSB shifted out first when clock goes high, 8 Bit, 10 µs
Get #1 , B1
Get #1 , B2
Get #1 , B3
Writeeeprom B1 , 11
Writeeeprom B2 , 12
Writeeeprom B3 , 13
End If
Loop

Sub Ics307
'MSB shifted out first when clock goes high, 8 Bit, 10 µs
Shiftout Portb.4 , Portb.3 , B1 , 1 , 8 , 10
Shiftout Portb.4 , Portb.3 , B2 , 1 , 8 , 10
Shiftout Portb.4 , Portb.3 , B3 , 1 , 8 , 10
Pulseout Portb , 0 , 20
End Sub

End

 
Die Datenübertragung zum Taktoszillator verwendet den komfortablen Bascom-Befehl Shiftout zur Übertragung der drei relevanten Bytes. Danach wird mit Pulseout ein Strobe-Impuls erzeugt. Für den Empfang ist ein Software-UART mit 9600 Baud zuständig. Den drei Datenbytes B1, B2 und B3 wird ein Kommando vorangestellt, und zwar 65 für die direkte Ausgabe und 66 für die Speicherung ins EEPROM. Diese drei Bytes an den Adressen 10, 11 und 12 im EEPROM werden bei jedem Neustart gelesen und in den Oszillatorchip geschoben.

 

Download: PC-Softwware und Tiny13-Firmware: ICS307Tiny13.zip

Das vorhandene Programm zur Einstellung der Ausgangsfrequenz muss etwas angepasst werden, damit es nun die geünschten vier Bytes über die RS232 sendet. Das Beispiel zeigt eine Frequenz von 27,12 MHz, für die die drei Steuerbytes 60, 165 und 176 ermittelt wurden. Die Frequenz kann mit dem Schieber eingestellt werden. Zusätzlich wurde ein Eingabefenster hinzugefügt, dessen Frequenz mit der set-Taste auf den Schieber übertragen wird.
 

Private Sub HScroll1_Change()
xtal = 20000
f = HScroll1.Value * 5
f = f * 4
Text1.Text = f
s123 = 0 '10/2
fvco = f * 20
If f > 15000 Then
s123 = 4 '/5/2
fvco = f * 10
End If
If f > 30000 Then
s123 = 6 '/3/2
fvco = f * 6
End If
If f > 60000 Then
s123 = 1 '/2/2
fvco = f * 4
End If

Min = 10000
For RDW = 2 To 50
For VDW = 10 To 511
fr = xtal * 2 * (VDW + 8) / (RDW + 2)
If Abs(fr - fvco) < Min Then
Min = Abs(fr - fvco)
fre = fr
ne = RDW
ie = VDW
End If
Next VDW
Next RDW
Text2.Text = Str(f) + " " + Str(Int(fre)) + " " + Str(ne) + " " + Str(ie)

SENDBYTE 65
DELAY 2
Byte1 = &H38 + s123
SENDBYTE Byte1
DELAY 2
Byte2 = ie \ 2
SENDBYTE Byte2
DELAY 2
If (ie And 1) = 1 Then ne = ne + 128
Byte3 = ne
SENDBYTE Byte3
DELAY 2
Text3.Text = Str(&H38 + s123) + " " + Str(Byte2) + " " + Str(Byte3)

End Sub

Übrigens habe ich auch versucht, die Berechnung der Registerinhalte im Mikrocontroller laufen zu lassen. Das ist jedoch sehr aufwendig, da bei dem verwendeten Verfahren ca. 24000 Einstellungen durchprobiert werden, um diejenige zu finden, die am genauesten an der Wunschfrequenz liegt. Dazu war ein größerer Controller nötig und außerdem viel zu viel Rechenzeit. Deshalb bleibt es erstmal dabei, dass fertige Registerwerte übertragen werden müssen. Richtig praktisch wäre es, wenn der programmierbare Quarzoszillator auf einer kleinen Platine aufgebaut wäre. Das sollte ich mal versuchen. Vielleicht so oder noch kleiner?




Aufbau im DIP-14-Format 



Quarzoszillatoren gibt es im DIP-14-Format mit vier Anschlüssen. Um den programmierbaren Quarzoszillator in gleicher Weise einzusetzen habe ich ihn auf eine kleine zweiseitig bestückte Punktrasterplatine gesetzt. Die übliche Pinbelegung wurde übernommen, aber am Pin1 liegt jetzt der RXD-Eingang. Man braucht nur diesen einen Pin, um den Generator neu zu programmieren. Am Eingang liegt ein 10-kOhm-Widertans nach Masse und einer zwischen Pin 1 und dem seriellen Eingang PB2 des Controllers. Ohne angeschlossene RS232 ist damit der Nullpegel gesichert. Und +/-10V-Signale von einer RS232 werden durch die internen Schutzdioden des Controllers auf 0/5V-Pegel begrenzt.



1 NC oder Power-Down-Eingang, bzw. RXD-Input des Tiny13
7 GND
8 Signal-Ausgang
14 VCC



Auf der Unterseite liegt der ICS307-2. Weil beide ICs an der gleichen Betriebsspannung (3,3 V ...5 V) arbeiten, konnten die Controller-Ports und die Eingänge des Generators ohne Widerstände direkt verbunden werden. Der Oszillator wurde diesmal mit einem 16-MHz-Quarz gesteuert und dies in der Software angepasst.


Elektronik-Labor   Projekte   AVR