Morsedecoder für ATmega88



Was programmiert man Sinnvolles auf dem neuen Experimentierbord? Ein altes Projekt fiel mir ein, das ich schon einmal mit diskreten Bauelementen aufgebaut und später dann in Quick BASIC auf dem PC programmiert hatte. Das Projekt mit den diskreten Bauelementen wurde nie fertig. Es war zu umfangreich. Das Basicprogramm funktionierte. Damals nutzte ich die Parallelschnittstelle als Eingangsport.

 

Ein Morsedecoder auf dem  Atmel ATmega88 hat natürlich den Vorteil, dass der  fertig programmierte ATmega88 quasi als ein Decodierbaustein aufgefasst werden kann, der dann später als Blackbox in beliebigen anderen Schaltungen eingesetzt werden kann.  PD2 dient dabei als Eingang für die Morsezeichen im TTL-Pegel. Es sind zwei Ausgänge vorgesehen: PB0 – PB5 dienen als Schnittstelle für ein LCD-Display mit 1 oder 2 * 16 Zeichen, PD1 stellt den TXD- Ausgang des Hardware USART dar. Auf ihn wird der Klartext über die RS232 – Schnittstelle ausgegeben.

IMG_4529a
Der Testaufbau. Das Experimentierbord mit dem ATmega88 im Nullkraftsockel. Die kleine grüne Platine hat ebenfalls einen ATmega88, der hier Morsezeichen generiert um das Programm zu testen.
Das Programm wurde mit der kostenfreien Demoversion des BASCOM- AVR Compilers, von MCS-Electronics, erstellt.

Wer einen Morsedecoder programmieren will, der steht vor einigen Herausforderungen. Zum einen ist der Morsecode in der Länge variabel. Zum Beispiel besteht das Morsezeichen für das e aus einem Element (kurz), dagegen besteht das Morsezeichen für das q aus vier Elementen. (lang lang kurz lang) Will heißen: ein Morsezeichen variiert in der Länge.  Es hat sich eingebürgert, ein kurzes Element di (bzw. dit, wenn kein weiteres di folgt)  und ein langes Element dah auszusprechen. Ein dah hat die Länge von drei di.

 

Auch die Pausenzeiten zwischen den Elementen variieren. So ist die Pause zwischen zwei Elementen eines Zeichens genauso lang wie ein dit (Pause1), die Pause zwischen zwei Zeichen entspricht der Länge von drei dit (Pause2) und die Pause zwischen zwei Worten entspricht der Länge von sieben dit (Pause3).

 

Es reicht also nicht aus, eine Codetabelle zu erstellen und von einem Code in den anderen zu wandeln, vielmehr müssen die gerade genannten Besonderheiten des Morsecodes berücksichtigt werden.  Das folgende Programm erfüllt diese Bedingungen.

100504aa-013b

Das Flussdiagramm

 

Zum leichtern Verständnis, wird zunächst angenommen, das immer mit einer bekannten und gleich bleibenden Geschwindigkeit gemorst wird.

 

Nach dem Programmstart und der Initialisierung läuft das Programm in einer Endlosschleife, die immer wieder an dem Punkt1: aufsetzt. Es wird das Unterprogramm „I/O-ABFRAGE“ aufgerufen, dass den Port PD2 abfragt und den Signalzustand 1 für Morsetaste gedrückt und 0 für Morsetaste nicht gedrückt in der Variablen „letzterZustand“, sowie die Dauer, die die Taste gedrückt oder losgelassen war in der Variablen „Zeit“ zurückgibt.  Es wird dann geprüft ob der letzte Zustand 0 oder 1 war. War er 1 haben wir es mit einem Signal zu tun, war er 0 liegt eine Pause vor.

 

Gehen wir einmal davon aus, dass ein Signal anlag. Dann ist es natürlich von Interesse, ob es sich um ein dit oder ein dah handelte. Dies wird über die Zeit geprüft.  Ist die verstrichene Zeit aus der Variablen „Zeit“ kürzer als die vorher definieret „Strichzeit“ dann liegt ein Dit vor und der Variablen „Element“ wird ein Punkt zugewiesen, ist sie länger oder gleich der Strichzeit lag ein dah an und der Variablen „Element“ wird ein Strich zugewiesen.  Das Programm ergänzt den aufgenommen „Zeichencode“ um das erkannte Element.  Dann folgt ein Sprung zu Punkt1 und ein neuer Durchlauf beginnt.

 

Lag jedoch kein Signal an, dann ist zu prüfen um welche Art von Pause es sich handelt. War die Zeit kleiner als die vorher definierte „Pause1“, dann handelt es sich um die Pause1. Hier ist keine weitere Aktion erforderlich. Es folgt also ein Sprung zu "Punkt1:" um auf das nächste Signal zu warten.  Ist die verstrichene Zeit größer oder gleich der 

„Pause1“, dann kann es sich nur um ein Ende des gerade gemorsten Buchstabens oder um das Ende des gerade gemorsten Wortes handeln. In jedem Fall ist nun das Morsezeichen, welches sich nun vollständig in der Variablen „Zeichencode“ befindet in dem Unterprogramm „DECODIEREN“ in Klartext zu übersetzen.  DECODIEREN übergibt das Ergebnis in der Variablen „Buchstabe“.  Diese wird der Variablen „Ausgabe“ zugewiesen. Dann ist zu prüfen, ob es sich um eine Pause zwischen einen Buchstaben oder um eine Pause zwischen zwei Worten handelt. Dies geschieht mit einem Vergleich von „Zeit“ mit der vorher definierten „Pause3“. Ist die Zeit kleiner als „Pause3“, dann handelt es sich um eine Pause zwischen zwei Buchstaben; ist die Zeit größer oder gleich „Pause3“, handelt es sich um eine Pause nach einem beendeten Wort. In diesem Fall muss der Variablen „Ausgabe“ noch ein Leerzeichen „  „ (Space) angehängt werden.

 

Anschließend erfolgt mit dem Unterprogramm „AUSGABE“ die Ausgabe der Variablen „Ausgabe“ an das LCD-Display und an die RS232-Schnittstelle. Die Variable „Zeichencode“ wird gelöscht und mit einem Sprung zu Punkt1: erfolgt ein neuer Durchlauf.

100504aa-008a
Der Sourcecode (zur Ansicht bitte draufklicken)

Wie funktioniert das nun mit wechselnden Geschwindig- keiten? Im Unterprogramm „I/O- ABFRAGE“ werden ja die Signal- und Pausenzeiten erfasst. Daher übergibt „I/O-ABFRAGE“ die Zeiten an ein weiteres Unterprogramm „NEUZEITEN“. Dort werden immer 10 aufeinander folgende Zeiten in der Feldvariablen „Zeitfeld()“  gesammelt und anschließend  im Unter- programm „SORTZEITFELD“  so sortiert, dass die kürzeste Zeit 

100504aa-011a
Ausgabe über die RS232-Schnittstelle an das Hyper-Terminal
 im ersten Eintrag „Zeitfeld(1)“ steht. Dieser Wert bildet die  Grundlage für die Neudefinition aller Zeiten in Unterprogramm „REINIT“. Er wird zur neuen Punktzeit. Bei dem Sortieralgorithmus, in „SORTZEITFELD“ handelt es sich um einen schlichten Bubblesort, da nur wenige Elemente sortiert werden müssen und die Sortierung nicht zeitkritisch ist.





zurueck