AM-Modulator und ATtiny85 


Elektronik-Labor   Projekte   AVR 





https://www.ak-modul-bus.de/stat/am_modulator_2.html 
https://www.ak-modul-bus.de/stat/3_kanal_hf_generator_3channel_rf_gen.html


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


Elektronik-Labor   Projekte   AVR