Der neue AM-Modulator auf der Basis
eines PLL-Chips SI5351 ist nun bei Modul-Bus erhältlich. Ich hatte die Hardware zunächst mit
einem ATtin45 entwickelt, und Roger hatte die Platine gezeichnet. Das
Ziel war, dass man nun alle Kanäle im Mittelwellenbereich quarzgenau
einstellen kann, um eigene Audioquellen über alte Röhrenradios hörbar
zu machen. Ein zweites Ziel lag mir besonders am Herzen: Der Generator
sollte auch als programmierbarer Oszillator und als universeller VFO im
Kurzwellenbereich einsetzbar sein und Aufgaben übernehmen wie im
Elektor-SDR-Shield.
In der weiteren Entwicklung zeigte sich, dass der Tiny45 zu wenig
Speicherplatz hat, um alle Aufgaben zu erfüllen. Wir sind dann auf den
Tiny85 umgesteigen. Da lag es nahe, die Tiny85-Platine aus dem
Lernpaket Mikrocontroller als USB-Interface und Programmiergerät zu
verwenden. Auf der PLL-Platine gibt es ja einen sechspoligen
ISP-Stecker, den ich zuerst mit einem SDK500 verwendet habe. Mit einem
geeigneten Übergangskabel kann ebenso die
Tiny85-Platine
als Programmierer dienen. Dazu wurde der Controller aus der Fassung
genommen und insgesamt sechs Leitungen wurden zur PLL-Platine geführt.
Nur die VCC-Leitung geht nicht direkt an den ISP-Stecker, sondern an
die Batterieklemme, sodass der Spannungsregler auf der PLL-Platine für
3,3 V sorgt. Das ist wichtig, weil der der SI5351 nicht mehr verträgt.
Die drei Leitungen zu PB0, PB1 und PB2 sind zwar eigentlich
5V-kompatibel, aber sie verfügen über Widerstände, die für eine
Spannungsanpassung sorgen.
Mit dieser Verbindung kann der Tiny85 genau so behandelt werden als
säße er in der Fassung. Das bedeutet, dass ich auch den Bootloader
verwenden kann, was die weitere Programmentwicklung mit Bascom sehr
viel einfacher macht. Und auch eine serielle Schnittstelle ist
vorhanden. Allerdings musste dazu noch ein Hürde überwudnen werden.
Das Lernpaket verwendet PB1 als TXD-Ausgang und PB2 als
RXD-Eingang. Auf der PLL-Platine gibt es aber einen Tastschalter an
PB2, mit dem man die AM-Kanäle umschalten kann. Ursprünglich war
deshalb der serielle Eingang an PB1 geplant. RXD musste also nun an PB2
verlegt werden. An der Anschlussreihe der Platine ist PB1 und PB2
zugänglich, sodass man auch hier den Zugang zur seriellen Schnittstelle
hat. Während der Entwicklung wird aber die Verbindung über den
ISP-Stecker verwendet.
Die Frage war also, wie man den Eingang PB2 sowohl für den Taster als
auch für die serielle Schnittstelle verwenden kann. Welches Ergebnis
liefert der Software-UART, wenn man auf die Taste drückt? Empfangen
wird dann ein Null-Byte, was in der normalen Kommunikation niemals als
erstes Zeichen einer Übertragung aufritt. Das ist also das
entscheidende Unterscheidungskriterium. Wenn eine Null erkannt wird,
war es der Schalter. Das Programm verzweigt dann in die
Behandlung der Tastenereignisse. Dort wird zuerst zur Entprellung
geprüft, ob der Tastendruck länger als 50 ms andauert und dann die
AM-Frequenz um 9 kHz erhöht. Am Ende wird noch abgewartet, bis die
Taste wieder losgelassen wird.
Config Portb = input
pORTb = 255 'Pullup 'Pullups an C0...C3
Open "comb.2:9600,8,n,1" For Input As #1
Open "comb.1:9600,8,n,1" For Output As #2
do
get#1,K
if k>0 then
Input #1 , F1
F = F1
Komm = Chr(K)
'print #2, Komm
'print #2, F
...
else
'print #2, "Taste"
waitms 50
if pINB.2=0 then
F2 = F2 + 9000
if F2 > 1650000 then F2 = 531000
F = F2
Clk = 2
Sifreq
do
waitms 50
Loop until pINB.2=1
end if
end if
loop
Die serielle Kommunikation läuft mit 9600 Baud und folgt dem
Protokoll, das ich für das Elektor SDR-Shield verwende. Wenn man z.B.
A7000 sendet, wird am ersten Ausgang CLK0 die Frequenz 7000 kHz
erzeugt. Und wenn man eine feinere Auflösung von einem Hz braucht,
sendet man a7000000. Für CLK1 lauten die Kommandos übrigens F und f.
Damit kann auch die Software zum SDR-Shield
eingesetzt werden. Die Abstimmung über die Schieberegler verwendet das
Kommando f und damit CLK1. Eine typische Anwendung ist der Bau
einfacher
Direktmischer für den Kurzwellenbereich. Der Kanal B wird übrigens vom
AM-Modulator verwendet. Wenn man also abweichend vom üblichen Einsatz
mal auf Langwelle aktiv werden will, kann man hier die passende
Frequenz einstellen.
Am Ende hat Roger noch einige Erweiterungen in die Software
gebracht. Bisher gab es für den AM-Modulator nur das 9-kHz-Raster, wie
es in Europa üblich ist. Aber es gibt auch Interessenten in den USA, wo
man ein 10-kHz-Raster verwendet. Nun kann man beim Start der Platine
den Taster gedrückt halten, um zwischen beiden Welten umzuschalten.
Außerdem wird nun die zuletzt verwendete AM-Frequenz im EEPROM
gespeichert. Auch die beiden anderen Kanäle CLK0 und CLK1 kann man
übrigens im EEPROM verewigen, sodass die Platine ohne Softwarekommandos
nach dem Start bis zu drei Frequenzen ausgibt. Die Kommandos dazu
lauten k, l und m, gefolgt von der Frequenz in Hz. Steht statt der
Frequenz eine Null, wird der Kanal abgeschaltet.
'AM-Modulator ATtin85 und SI5351
'531 kHz ... 1647 kHz, Raster 9 kHz
'Fuses E2, DE, FE, 1,8 V Brownout, 8 MHz
'AK Modul-Bus Computer GmbH, B. Kainka 31.3.2021
'R.Leifert: Neu eingebaut:
'-Frequenzgrenzen korrigiert
'-Schreiben der geänderten MW-Frequenz ins EEPROM
'-Toggeln des MW-Rasters bei gedrückter Taste bei Einschalten
$regfile = "attiny85.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 32
$framesize = 64
Dim Badr As Byte
Dim Bdat As Byte
Dim N As Byte
Dim Clk As Byte
Dim F As Single 'Frequenz für Si
Dim F0 As Single 'abgespeicherte Frequenzen für F0, Dim F1 As Single
Dim F1 As Single
Dim F2 As Single
Dim En As Byte
Dim Raster As Single 'Raster 9 oder 10 kHz
'Dim Zeile As String * 20
Dim Komm As String * 1
dim K as byte
Declare Sub Regwrite
Declare Sub Siinit
Declare Sub Sifreq
Config Portb = input
pORTb = 255 'Pullup 'Pullups an C0...C3
Open "comb.2:9600,8,n,1" For Input As #1
Open "comb.1:9600,8,n,1" For Output As #2
Config Sda = Portb.4
Config Scl = Portb.3
I2cinit
Waitms 10
Siinit
Waitms 100
Readeeprom Raster , 40 'Raster aus EEPROM-Adresse 40 lesen
If Raster < 9000 Or Raster > 10000 Then Raster = 9000 'Raster = 9kHz, wenn EEPROM leer
If Pinb.2 = 0 Then 'Taster gedrückt?
If Raster = 9000 Then 'Toggle Raster
Raster = 10000 '10 kHz US
F = 530000 'Startfrequenz f=530 kHz
Else
Raster = 90000 '9 kHz EU
F = 531000 'Startfrequenz f=531 kHz
End If
Writeeeprom F , 30
Writeeeprom Raster , 40
Do
Waitms 50
Loop Until Pinb.2 = 1 'Warte bis Taster losgelassen ist
End If
Readeeprom F, 10
if F<8000 then F = 0
Clk = 0
Sifreq
Readeeprom F, 20
if F<8000 then F = 0
Clk = 1
Sifreq
Readeeprom F, 30
if F<8000 then F = 531000
F2 = F
Clk = 2
Sifreq
Readeeprom Raster , 40 'Raster aus EEPROM-Adresse 40 lesen
If Raster < 9000 Or Raster > 10000 Then Raster = 9000 'Raster = 9kHz, wenn EEPROM leer
do
get#1,K
if k>0 then
Input #1 , F1
F = F1
Komm = Chr(K)
print #2, Komm
print #2, F
If Komm = "A" Then 'Clk0 kHz
F = F1 * 1000
Clk = 0
Sifreq
End If
If Komm = "a" Then 'CLK0 Hz
Clk = 0
Sifreq
End If
If Komm = "F" Then 'Clk1 kHz
F = F1 * 1000
Clk = 1
Sifreq
End If
If Komm = "f" Then 'Clk1 Hz
F = F1
Clk = 1
Sifreq
End If
If Komm = "B" Then 'Clk2 kHz
F = F1 * 1000
Clk = 2
Sifreq
End If
If Komm = "b" Then 'Clk2 Hz
Clk = 2
Sifreq
End If
If Komm = "k" Then 'CLK0 Hz EEPROM
writeeeprom F, 10
Clk = 0
Sifreq
End If
If Komm = "l" Then 'Clk1 Hz EEPROM
writeeeprom F, 20
Clk = 1
Sifreq
End If
If Komm = "m" Then 'Clk2 Hz EEPROM
writeeeprom F, 30
Clk = 2
Sifreq
End If
else
'print #2, "Taste"
waitms 50
if pINB.2=0 then
If Raster = 9000 Then '9 kHz-Raster EU
F2 = F2 + 9000
If F2 > 1620000 Then F2 = 531000 'Grenze bei 1611 kHz --> 531 kHz
Else
F2 = F2 + 10000 '10 kHz-Raster US
If F2 > 1710000 Then F2 = 530000 'Grenze bei 1700 kHz --> 530 kHz
End If
Writeeeprom F2 , 30 'MW-Frequenz ins EEPROM speichern
F = F2
Clk = 2
Sifreq
do
waitms 50
Loop until pINB.2=1
end if
end if
loop
Sub Siinit
Badr = 183 : Bdat = 128 : Regwrite 'Xtal 8pF
En = 15
Badr = 3 : Bdat = En : Regwrite 'Clk0 Clk1, Clk2 off
Badr = 15 : Bdat = 0 : Regwrite 'Xtal = PLL input
Badr = 16 : Bdat = 15 : Regwrite 'Clk 0:PLLA, 8mA out
Badr = 17 : Bdat = 15 : Regwrite 'Clk 1:PLLA, 8mA out
Badr = 18 : Bdat = 15 : Regwrite 'Clk 2:PLLA, 8mA out
Waitms 10
Restore Pll900
Badr = 26
For N = 26 To 33
Read Bdat
Regwrite
Next N
Waitms 50
End Sub
Sub Sifreq
Dim P1 As Dword
Dim P11 As Byte At P1 + 0 Overlay
Dim P12 As Byte At P1 + 1 Overlay
Dim P13 As Byte At P1 + 2 Overlay
Dim P2 As Dword
Dim P21 As Byte At P2 + 0 Overlay
Dim P22 As Byte At P2 + 1 Overlay
Dim P23 As Byte At P2 + 2 Overlay
Dim P3 As Dword
Dim P31 As Byte At P3 + 0 Overlay
Dim P32 As Byte At P3 + 1 Overlay
Dim P33 As Byte At P3 + 2 Overlay
Dim A As Dword
Dim B As Dword
Dim C As Dword
Dim D As Dword
Dim E As Dword
Dim G As Single
Dim R As Byte
Dim T As Byte
If F < 2000 Then
If F = 0 Then
En.clk = 1
Badr = 3 : Bdat = En : Regwrite 'Ausschalten
End If
If F > 0 Then
En.clk = 0
Badr = 3 : Bdat = En : Regwrite 'Einschalten
End If
Else
If F < 8000 Then F = 8000
If F > 150000000 Then F = 150000000
G = 900000000 / F 'Teiler
C = 1048575
R = 0 'R-Teiler R0...2
While G > 900
G = G / 2 : 'Multisynth-Teiler verkleinern
R = R + 16
' If R = 32 Then 'R-Teiler 4 vrmeiden
' G = G / 2
' R = R + 16
' End If
Wend 'Fout = Fvfo / G / R
A = G 'G = A + B / C
G = G - A
G = G * C 'B = (G - A) * C
B = G
D = B * 128
D = D / C 'D = Int(128 * B / C)
P1 = 128 * A
P1 = P1 + D
P1 = P1 - 512 'P1 = 128 * A + (128 * B / C) - 512
P2 = B * 128
E = D * C 'E = c * Int(128 * B / C)
P2 = P2 - E 'P2 = 128 * B - C * Floor ( 128 * B/C)
P3 = C
Badr = 8 * Clk
Badr = Badr + 42
Bdat = P32
Regwrite
Bdat = P31
Regwrite
Bdat = P13 + R
Regwrite
Bdat = P12
Regwrite
Bdat = P11
Regwrite
Swap P33
Bdat = P33 + P23
Regwrite
Bdat = P22
Regwrite
Bdat = P21
Regwrite
En.clk = 0
Badr = 3 : Bdat = En : Regwrite 'Einschalten
End If
End Sub
Sub Regwrite
I2cstart
I2cwbyte 192 'i2c Adresse SI5351A
Waitus 1
I2cwbyte Badr
Waitus 1
I2cwbyte Bdat
Waitus 1
I2cstop
Waitus 2
Badr = Badr + 1
End Sub
End
Pll900: 'PLLA 900 MHz
Data 255 , 255 , 0 , 16 , 0 , 240 , 0 , 0
Siehe auch:
Micro:bit steuert AM-Sender
AM-Modulatoren im Vergleich