CW-Ausgabe für den PFS154
Für die weitere Arbeit habe ich mir ein kleines Entwicklungsboard
mit einer Programmierschnittstelle gebaut. Was erst nicht funktionieren
wollte, geht jetzt doch, die Programmierung über fünf Leitungen. Dioden
zum Vortäuschen nicht angeschlossener Ports sind nicht mehr nötig, denn
inzwischen habe ich die Software des Programmers besser verstanden.
Man muss erst auf Convert klicken. Und von da auf To New IC, oder wenn man das schon definiert hat To Package.
In diesem Fall habe ich bereits ein S08-Gegäuse definiert, was in einer PDK-Datei festgehalten wurde.
Im Fenster Package Seting wurde S08 gewählt. Und - ganz wichtig
- O/S Test Select: Only Program PIN. Dann werden die Pinne 2, 6
und 7 nicht mehr getestet. Damit klappt das Programmieren nun
problemlos. Es ist angenehm, dass man das Kabel danach abziehen kann.
Am Ende bin ich aber doch wieder bei den Dioden gelandet und habe die
drei freien Anschlüsse damit versorgt. Der Grund: Die Software will
sich einfach nicht merken, dass der O/S-Test nur für die Programm-Pinne
gelten soll. Da musste ich es jedes Mal neu eingeben und noch dazu
jedes Mal wieder eine neue Datei dafür erzeugen. Deshalb dachte ich
mir, Löten ist seliger denn Tippen.
CW-Ausgabe
Die
CW-Ausgabe soll Bytes als Zahlen senden, also r.B. den Wert 241 als drei
Zeichen 2 - 4 - 1. Als Ausgabeport wurde PB3 gewählt. Die Geschwindigkeit ist
60 BPM, also 100 ms für einen Punkt und 300 ms für einen Strich. Die Funktionen
Dot und Dash enthalten jeweils die zusätzlich erforderliche Pause von 100 ms.
Die Geschwindigkeit gilt für die Arbeit mit dem langsamen RC-Generator ILRC.
static void Dot (void)
{
Byte t;
t = 85;
do
{
PB.3 = 1; //CW-Ton an PB3
.delay(25);
PB.3 = 0;
.delay(25);
} while (--t);
.delay(5000); //ca. 100 ms
}
static void Dash (void)
{
Byte t;
t = 255;
do
{
PB.3 = 1; //CW-Ton an PB3
.delay(25);
PB.3 = 0;
.delay(25);
} while (--t);
.delay(5000); //ca. 100 ms
}
Die entscheidende Aufgabe ist das Abtrennend er drei dezimalen Ziffern.
static void CW_Send (void)
{
BYTE cnt, d_cnt, Digit, j;
WORD CW_Out, i;
CW_Out = A;
d_cnt = 3;
do
{
j= 10;
i = 0;
do //Digits abtrennen 2 5 5
{
if (CW_OUT >= 100)
{
i++;
CW_OUT = CW_OUT - 100;
}
} while (--j);
if (i == 0) {Dash();}
if (i == 1) {Dot(); Dash(); Dash(); Dash(); Dash();}
if (i == 2) {Dot(); Dot(); Dash(); Dash(); Dash();}
if (i == 3) {Dot(); Dot(); Dot(); Dash(); Dash();}
if (i == 4) {Dot(); Dot(); Dot(); Dot(); Dash();}
if (i == 5) {Dot(); Dot(); Dot(); Dot(); Dot();}
if (i == 6) {Dash(); Dot(); Dot(); Dot(); Dot();}
if (i == 7) {Dash(); Dash(); Dot(); Dot(); Dot();}
if (i == 8) {Dash(); Dash(); Dash(); Dot(); Dot();}
if (i == 9) {Dash(); Dash(); Dash(); Dash(); Dot();}
.delay(10000); // + ca. 200 ms = ca. 300 ms
j= 10;
i = 0;
do
{
i = i + CW_OUT;
} while (--j);
CW_OUT = i;
} while (--d_cnt);
}
Übungsprogramm mit Fünfergruppen
Jetzt ist noch ein schönes kleines Morse-Übungsgerät daraus geworden.
Das Batteriefach und der Mini-Lautsprecher stammen aus einem
ausgeschlachteten Gerät. Alles läuft extrem stromsparend mit zwei
AAA-Zellen. Ich kann über Jumper insgesamt vier Geschwindigkeiten
wählen: 60, 80, 100, 120 BpM. Es werden jeweils 20 Gruppen, also
insgesamt 100 zufällige Buchstaben gesendet. Nach einer kurzen Pause
kommen dann dieselben Buchstabengruppen erneut, wobei man z.B. die
Geschwindigkeit erhöhen kann oder nur zur Kontrolle mitlesen. Das hat
sich insgesamt als sehr motivierend erwiesen, gerade weil es nur auf
einem kleinen Gerätchen läuft und nicht auf einem größeren Computer,
der bekanntlich oft für Ablenkungen sorgt. Ich bleibe jetzt hoffentlich
mit den Übungen am Ball, damit ich im realen Funkverkehr schneller und
fehlerfreier werde.
Die eigentliche Erzeugung zufälliger Morsezeichen habe ich aus einem
älteren Projekt kopiert, das in Bascom für den Sparrow, also den Tiny13
geschrieben wurde (Siehe Morse-Sputnik). Die Übertragung von Bascom
nach Mini-C lief glatter als gedacht. Allerdings fiel dabei wieder auf,
dass der Compiler weder multiplizieren noch dividieren kann. Mit
Schleifen, Additionen und Subtraktionen geht es aber auch.
Was auch fehlt, ist eine Zufallsfunktion. Dazu habe ich mir die
Byte-Variablen rnd und r gebildet, die beim Start des Programms
nicht initialisiert werden und damit einen zufälligen Inhalt haben. Die
Zufallszahl rnd wird jedes Mal um r erhöht, und danach wird r um 1
erhöht. Was dabei herauskommt, ist zwar nicht völlig zufällig, sondern
kann sich nach einiger Zeit wiederholen. Aber für die Morseübungen
reicht es völlig. Und ich kann rnd und r nach einer Übung wieder auf
die alten Werte stellen, sodass dasselbe noch einmal wiederholt wird.
Die Geschwindigkeit wird über zwei Jumper an PB5 und PB6 abgefragt und
daraus ein Wert für speed berechnet. Die Nachbarpinne B4 und B7 werden
dazu nur kurz an GND geschaltet, damit nicht über die
Pullup-Widerstände unnötig viel Energie verbraten wird. Ich will hier
nämlich mit wenigen µA auskommen, man weiß ja nicht, wie lange ich noch
üben muss. Aus speed wird dann festgelegt, wie viele NF-Schwingungen
ein Punkt oder ein Strich haben muss. Außerdem ergibt sich daraus die
Pausenlänge innerhalb und zwischen den Zeichen.
#include "extern.h"
Byte speed, rnd, r;
static void Dot (void)
{
Byte t;
t = 85;
if (speed == 2) {t=64;}
if (speed == 3) {t=51;}
if (speed == 4) {t=42;}
do
{
PB.3 = 1; //CW-Ton an PB3
.delay(25);
PB.3 = 0;
.delay(25);
} while (--t);
t = 50;
if (speed == 2) {t=38;}
if (speed == 3) {t=30;}
if (speed == 4) {t=25;}
do
{
.delay(100); //ca. 2 ms
} while (--t);
}
static void Dash (void)
{
Byte t;
t = 255;
if (speed == 2) {t=192;}
if (speed == 3) {t=153;}
if (speed == 4) {t=127;}
do
{
PB.3 = 1; //CW-Ton an PB3
.delay(25);
PB.3 = 0;
.delay(25);
} while (--t);
t = 50;
if (speed == 2) {t=38;}
if (speed == 3) {t=30;}
if (speed == 4) {t=25;}
do
{
.delay(100); //ca. 2 ms
} while (--t);
}
static void CW_Send (void)
{
BYTE cnt, d_cnt, Digit, j;
WORD CW_Out, i;
CW_Out = A;
d_cnt = 3;
do
{
j= 10;
i = 0;
do //Digits abtrennen 2 5 5
{
if (CW_OUT >= 100)
{
i++;
CW_OUT = CW_OUT - 100;
}
} while (--j);
if (i == 0) {Dash();}
if (i == 1) {Dot(); Dash(); Dash(); Dash(); Dash();}
if (i == 2) {Dot(); Dot(); Dash(); Dash(); Dash();}
if (i == 3) {Dot(); Dot(); Dot(); Dash(); Dash();}
if (i == 4) {Dot(); Dot(); Dot(); Dot(); Dash();}
if (i == 5) {Dot(); Dot(); Dot(); Dot(); Dot();}
if (i == 6) {Dash(); Dot(); Dot(); Dot(); Dot();}
if (i == 7) {Dash(); Dash(); Dot(); Dot(); Dot();}
if (i == 8) {Dash(); Dash(); Dash(); Dot(); Dot();}
if (i == 9) {Dash(); Dash(); Dash(); Dash(); Dot();}
.delay(10000); // + ca. 200 ms = ca. 300 ms
j= 10;
i = 0;
do
{
i = i + CW_OUT;
} while (--j);
CW_OUT = i;
} while (--d_cnt);
}
static void CW_Gruppe (void)
{
BYTE j, i, d, b, t;
j = 5;
i = 0;
do
{ rnd += r;
r +=1;
d = rnd & 31;
if (d > 24) d = rnd & 15;
d = d + 2;
if (d == 19) d = 27;
if (d == 21) d = 28;
b = 1;
do
{
d = d << 1;
b +=1;
} while (d < 128);
do
{
d = d << 1;
b += 1;
if (d >= 128) {Dash();}
if (d < 128) {Dot();}
} while (b < 8);
t = 50; // + ca. 200 ms = ca. 300 ms
if (speed == 2) {t=38;}
if (speed == 3) {t=30;}
if (speed == 4) {t=25;}
do
{
.delay(200);
} while (--t);
} while (--j);
.delay (20000);
}
void FPPA0 (void)
{
.ADJUST_IC SYSCLK=IHRC/16, IHRC=16MHz, VDD=5.0V;
PAC=0xCF;
PA=0xFF;
PADIER = 32; //.5=1; //Reset
PAPH = 32;
PBC = 15;
PBPH = 240; //Pullups PB4...PB7
while (1)
{
Byte m, rnd2, r2;
CLKMD = 0xF4; //ILRC
CLKMD.4 = 0;
rnd2 = rnd;
r2=r;
do
{
.delay(5000);
} while (PA.5==0);
m = 20;
do
{
PBC= 0x9F;
PB = 0x00;
PBPH = 0x60;
speed = 1;
if (PB.5==0) {speed +=1;}
if (PB.6==0) {speed +=2;}
PBC= 0xFF;
PBPH = 0;
CW_Gruppe ();
} while(--m);
.delay (250000);
rnd = rnd2;
r = r2;
}
}