Morseuhr V3a       

von Ralf Beesner                  
Elektronik-Labor   Projekte   AVR 



 

Meine Morseuhr 3 "funkt" nun schon seit fünf Jahren tapfer die Uhrzeit, der Bascom-Spaghetti-Code hat sich also hinreichend bewährt. Ich habe allerdings im Laufe der Zeit einige kleinere Änderungen vorgenommen (das obige Foto ist daher nicht mehr so ganz aktuell). 




Hardware

Der Reset-Taster konnte entfallen, da die Uhr sich bisher nur ein- oder zwei mal aufgehängte, als ich sie berührte und dabei statisch aufgeladen war. Sollte das mal passieren, kann man auch kurz die Batterien entnehmen, um sie zu resetten. Der Lautstärkeeinsteller stand all die Jahre auf Maximum, da der Piezoschwinger bei 3 V und der verwendeten NF-Frequenz relativ leise ist. Man kann ihn also ebenfalls weglassen.

Den Quarz habe ich inzwischen mit 22pF-Bürdekapazitäten beschaltet. Der Oszillator schwingt zwar auch ohne sie sicher, aber Temperaturänderungen schlagen stärker durch (bei heftiger Sonneneinstahlung hatte ich über den Tag bis zu 20 Sekunden Gangabweichung). Offenbar ändern sich die Parasitärkapazitäten der internen ATtiny-Oszillatorschaltung recht stark bei Temperaturschwankungen. Aufgrund der parallelliegenden 22 pF Bürdekapazitäten fallen die Parasitärkapazitäten nun kaum noch ins Gewicht.

Mir war vorher nie wirklich bewußt, was für ein Präzisionsinstrument eine billige Quarzuhr darstellt: das Jahr hat ca. 31,5 Millionen Sekunden, und 30 Sekunden Abweichung pro Jahr bedeuten eine Genauigkeit von 10 hoch -6 . Bei vielen anderen Meßinstrumenten freut man sich schon über 1% Genauigkeit ....

 



Software

Durch die etwas zu großen Bürdekapazitäten läuft die Uhr tendenziell zu langsam. Der Befehl "K" (Korrsec; Korrektursekunden) macht sie um 0 .... 9 Sekunden pro Tag schneller (um Mitternacht wird die Uhr nicht auf "0", sondern den Wert von Korrsek zurückgesetzt, so daß sie mit etwas Vorsprung in den neuen Tag startet).

Die alte Softwareversion 1.04 ließ sich mit neueren BASCOM-Versionen nicht mehr übersetzen, da "Gong" versehentlich sowohl als Variablenname als auch als Unterprogrammname verwendet wurde. Das Unterprogramm ist nun in "_Gong" umbenannt.

Zwecks Stromersparnis läuft die Uhr nicht mit vollem Quarztakt, sondern nur mit 1/8 des Quarztaktes. Ursprünglich mußte der Vorteiler per Fusebit aktiviert werden. In der neuen Version wird der Takt zur Laufzeit des Programms auf ein Achtel reduziert. Der ATtiny kann so ganz normal auf Quarzbetrieb ohne den Vorteiler 1:8 gefust werden (hfuse df, lfuse fd, efuse ff).

Die Slim-Version (ohne Weckfunktion und Korrektursekunden) ist entfallen.

Update 1.05: die neueste BASCOM-Freeware-Version warf eine Fehlermeldung, Fehler korrigiert.

Download des Bascom-Quelltextes (Update 1.05):  0320-morseuhr3a.zip

' Attiny-45-Morseuhr Version 1.05 fat
'
' gibt alle 15 min. die Minutenzahl aus und zur vollen Stunde die Stundenzahl
' ("es ist X Uhr"),
' ausserdem kann die Zeit durch Eingabe von "T" unmittelbar abgefragt werden
'
' Befehlsliste:
'
' ?     Auflistung aller Befehle
' Z     Zeit setzen
' T     Zeit abfragen
' W     Weckzeit setzen
' A 1/0   Alarm  ein /aus
' E     Alarm Ende
' G 1/0   Gong (Schlagwerk) ein/aus
' M     Morsegeschwindigkeit setzen
' C     Check -> Ausgabe von Alarmstatus und Gongstatus
' K     Korrektur ; N Sekunden Wartezeit um Mitternacht ; N = 1 ...9
'
' Pinbelegung:
'
' PB0 Buzzer
' PB1 Punktkontakt
' PB2 Strichkontakt
' PB3 und PB4: Quarz
'
'
' Quarz schwingt mit 3,686400 MHz; Oszillator wird duch 8 geteilt (Takt ist dann 460800 Hz)
'
' Timer1- Vorteiler teilt durch 2048, Timer 1 dann durch 225 -> Sekundenimpulse
'
' Nach 60 Interrupts ist eine Minute um; mit Minuten wird weitergerechnet.
'
' Da der Quarz ohne Bürdekondensatoren betrieben wird, ist der Timer grundsätzlich etwas zu schnell
' Ausgleich durch Wait- Befehl in der Interrupt- Routine ( 110 µsec * 86400 sec/Tag  = 9,5 sec/Tag )
'
' Fusebits: lfuse: 0x7d   hfuse: 0xdf  (Taktquelle Quarzoszillator, Teiler 1/8 , kein Brown-Out)
'
'
' Bugfix Version 1.01: Geschwindigkeits- Feineinstellung in der Interrupt- Routine funktionierte nicht
' Die Wartezeit hatte keine Auswirkung, weil mit TCNT1 = 31 zwar der 8-Bit-Teiler, presetted wird,
' während der 200 µs Wartezeit lief aber der Vorteiler einfach weiter. Reset Vorteiler: GTCCR.PSR1 = 1
'
'
' Bugfix Version 1.02: GTCCR.PSR1 = 1 führt dazu, daß die Uhr stets zu langsam läuft (Bascom verbraucht
' Zeit für den Sprung in die Interrupt-Routine). Funktionalität des Befehls "K" daher umgedreht; "K"
' macht die Uhr um K Sekunden pro Tag schneller, indem er um Mitternacht die Uhr (um max. 9 Sek.) vorstellt
'
' Bugfix 1.03: Der Quarzoszillator ist ohne Bürdekapaziät relativ instabil. 2 * 22 pF eingebaut und Reset Vorteiler
' wieder deaktiviert. Uhr läuft mit 22 pF zu langsam; Funktion "K" daher beibehalten
'
' Bugfix 1.04: "Gong" wurde zwei mal verwendet; als Variable und als Unterprogrammname. Da neuere BASCOM-Versionen
' das "bemeckern", wurde das Unterprogramm in "_Gong:" umbenannt. Umschaltung auf Teilung des Quarztaktes durch 8
' muss nicht mehr durch fusebit gesetzt werden, sondern erfolgt zur Laufzeit des Programmes mit CLKPR
'
' Bugfix 1.05: In einer For-Next-Schleife war der Variablenname hinter dem "Next" falsch (Zeile 386). Ältere
' Bascom-Versionen hatten den offenbar gar nicht beachtet
'
' verwendeter Compiler: Bascom 2.0.7.9
'----------------------------------------------------------


$Regfile = "Attiny45.dat"
$Crystal = 460800                                           ' 3,6864 MHz / 8

$Hwstack = 32
$Swstack = 8
$Framesize = 24


' Variablen für Zeitberechnung

Dim S As Word                                               ' Sekunden
Dim T As Word                                               ' Tagesminuten 0 ..... 1440
Dim Korr As Byte
Dim Mi As Word ' Minuten- Rest zur vollen Stunde Dim V As Word ' Minuten- Rest zur vollen Viertelstunde Dim H As Word ' Stunden Dim Zh As Word ' Zehnerstelle Stunden Dim Eh As Word ' Einerstelle Stunden Dim Zmi As Word ' Zehnerstelle Minuten Dim Emi As Word ' Einerstelle Minuten Dim Wmi As Word ' Minuten Weckzeit Dim Wh As Word ' Stunden Weckzeit Dim Wzh As Word ' Zehnerstelle Weckstunden Dim Weh As Word ' Einerstelle Weckstunden Dim Wzmi As Word ' Zehnerstelle Weckminuten Dim Wemi As Word ' Einerstelle Weckminuten Dim Ta As Word ' Alarmzeit in Tagesminuten Dim Hilf As Word ' Hilfsgroesse für Tagesminutenberechnung Dim Alarm As Byte ' Ein- / Ausschalter Alarm Dim Gong As Byte ' Ein- / Ausschalter Gong ' Variablen für Morsezeichen- Erzeugung Dim I As Byte ' wird in Zählschleife verwendet Dim N As Word ' Aktueller Morsebuchstabe Dim M As Byte ' wird fürs Auslesen der Morsebits verwendet Dim L As Byte ' wird für niederwertigstes Bit von M verwendet ' Variablen für Morsezeichen- Decodierung Dim E As Byte ' resultierendes ACCII-Byte der Decodierroutine Dim D As Byte ' Morsebyte in der Decodierroutine Dim K As Byte ' Byte, in dem eine "1" geshiftet wird Dim J As Byte ' Zählvariable für tolerante Pausenprüfung Dim P As Byte ' Punktspeicher-Bit der Decodierroutine ' Variablen für Ziffern- Eingabe Dim G(4) As Byte ' nimmt die Ziffern auf Dim R As Byte ' Anzahl angeforderter Ziffern Dim W As Byte ' Zähler für Eingabewiederholung der Ziffern Dim Notbremse As Byte ' Timer für Ausstieg aus unvollständigen Eingaben Dim Txtstring As String * 84 Dim Txt(84) As Byte At Txtstring Overlay


' Variablen für Morsezeichen- Timing Dim Punktlaenge1 As Word ' Punktlänge in "Empfangsrichtung" Dim Punktlaenge2 As Word ' Punktlänge in "Senderichtung" Dim Punktachtel As Word
Dim Strichlaenge1 As Word ' Strichlänge Dim Strichlaenge2 As Word
Dim Wortpause1 As Word ' Länge Wortpause Dim Wortpause2 As Word


Mcucr.sm0 = 0 ' mcucr für Idle konfigurieren Mcucr.sm1 = 0 ' mcucr Idle zweites Bit Pcmsk.1 = 1 ' PCINT für PB1 freigeben Pcmsk.2 = 1 ' PCINT für PB2 freigeben Gimsk.pcie = 1 ' PCints aktivieren Sreg.7 = 1 ' Interrupts generell freigeben Portb = &B0000110 ' Pullups für Strich- und Punktkontakt Ddrb = &B00000000 ' erstmal alles Eingang ' Stromspar- Funktionen nutzen Didr0 = &B00011001 ' digitale Eingänge ausser PB1 und PB2 abschalten Acsr.acd = 1 ' Analog-Komparator ausschalten Prr.prusi = 1 ' usi abschalten (power reduction usi) Prr.pradc = 1 ' adc abschalten (power reduction adc) ' Morseton mit Timer0 erzeugen: ' ' Timer0 zählt das Register TCNT0 hoch. Es wird mit Register OCR0A verglichen. ' Wenn TCNT0 = OCR0A, wird Output OC0A/PB0 umgeschaltet (getoggled) ' Timer0 erzeugt so Dauerton; er wird jedoch nur an den Ausgangspin durchgeschaltet, ' wenn das Datenrichtungs- Register DDRB.0 = 1 ist. Bei 0 wird der Ton unterdrückt. Config Timer0 = Timer , Prescale = 64 , Compare A = Toggle , Clear Timer = 1 ' 1- Sekunden- Interrupts mit Timer 1 erzeugen Config Timer1 = Timer , Prescale = 2048 Enable Timer1

On Timer1 Ontimer1 ' Interrupt-Routine für Timer1-Overflow Const Tonhoehe1 = 12 Const Tonhoehe2 = 18 Buzzer Alias Ddrb.0 Punktkontakt Alias Pinb.1 Strichkontakt Alias Pinb.2 '---------------------------------------------------------- Init: CLKPR = 128 ' Clock-Umschaltung vorbereiten CLKPR = 3 ' Clock-Vorteiler auf 1:8 setzen CLKPR = 3 '--- vorläufige Werte ------- Punktlaenge1 = 80 ' Punktlänge in "Empfangsrichtung" Punktlaenge2 = 100 ' Punktlänge in "Senderichtung" Punktachtel = 10 Strichlaenge1 = Punktlaenge1 * 3 ' Strichlänge Strichlaenge2 = Punktlaenge2 * 3 Wortpause1 = Punktlaenge1 * 5 ' Länge Wortpause Wortpause2 = Punktlaenge2 * 5 Gong = 1 Korr = 0 Gosub Zeitausgabe ' Kontrollausgabe nach Reset '--- Hauptschleife ----------- Do Prr.prtim0 = 0 ' Timer0 anschalten Mcucr.se = 0 ' Sleeepmode verbieten Mcucr.pcie = 0 ' Tasteninterrupts verbieten If T > 1439 Then ' Prüfen auf Tageswechsel T = 0 S = Korr ' Falls Korr > 0, wird Uhr um Mitternacht um <Korr> Sekunden vorgestellt End If Gosub Zeitberechnung

If Gong = 1 Then Gosub _Gong
End If If Alarm = 1 Then Gosub Alarmsub
End If Gosub Menue

' Idle- Modus vorbereiten Prr.prtim0 = 1 ' Timer0 abschalten Mcucr.pcie = 1 ' Pin Change Interrupt enable Mcucr.se = 1 ' Sleep enable !SLEEP

Loop



'------- Zeitberechnungen und Ausgabe der Zeiten --------- Zeitberechnung: H = T / 60 ' Uhrzeit auf Stunden gerundet Mi = T Mod 60 ' Minuten- Rest (zur vollen Stunde) Zh = H / 10 ' Zehnerstelle Stunden Eh = H Mod 10 ' Einerstelle Stunden Zmi = Mi / 10 ' Einerstelle Minuten Emi = Mi Mod 10 'Einerstelle Minuten V = T Mod 15 ' V = 0 bei vollen Viertelstunden Return Weckzeitberechnung: Wh = Ta / 60 ' Uhrzeit auf Stunden gerundet Wmi = Ta Mod 60 ' Minuten- Rest (zur vollen Stunde) Wzh = Wh / 10 ' Zehnerstelle Stunden Weh = Wh Mod 10 ' Einerstelle Stunden Wzmi = Wmi / 10 ' Einerstelle Minuten Wemi = Wmi Mod 10 'Einerstelle Minuten Return _Gong: If S < 2 Then ' unterdrückt mehrfache Ausgabe If V = 0 Then ' volle Viertelstunde If Mi = 0 Then ' Sonderfall: volle Stunde Txtstring = " ES IST " Gosub Sendstring
If Zh > 0 Then ' wenn zweistellige Stundenzahl M = Zh ' Zehnerstunde senden Gosub Sendnumber
End If M = Eh ' Einerstunde senden Gosub Sendnumber
Txtstring = " UHR " Gosub Sendstring
Else ' zur 15., 30., 45. Minute nur Minutenausgabe M = Zmi ' Zehnerminute Gosub Sendnumber
M = Emi ' Einerminute Gosub Sendnumber
End If End If End If Return Zeitausgabe: ' wenn Taster gedrückt wurde Txtstring = " ES IST " Gosub Sendstring

If Zh > 0 Then M = Zh ' Zehnerstelle Stunden Gosub Sendnumber
End If M = Eh ' Einerstelle Stunden Gosub Sendnumber

Txtstring = " UHR " Gosub Sendstring

If Zmi > 0 Then M = Zmi ' Zehnerstelle Minuten Gosub Sendnumber
End If M = Emi ' Einerstelle Minuten Gosub Sendnumber
Txtstring = " MIN" Gosub Sendstring

Return Weckzeitaugabe: Gosub Weckzeitberechnung

M = Wzh ' Zehnerstelle Stunden Gosub Sendnumber
M = Weh ' Einerstelle Stunden Gosub Sendnumber
M = Wzmi ' Zehnerstelle Minuten Gosub Sendnumber
M = Wemi ' Einerstelle Minuten Gosub Sendnumber

Return Alarmsub: If T = Ta Then Txtstring = " SOS" Gosub Sendstring
If Punktkontakt = 0 Then ' Alarm abschalten mit "E", "I", "S" usw. Alarm = 0 End If End If Return '------- Aufbereitung der zu sendenden Morsezeichen ------ Sendnumber: M = M + 48 ' Ascii- Wert 0: 048 ; Ascii- Wert 9: 057 M = Lookup(m , Morsetabelle) ' Morsezeichen aus Tabelle holen Gosub Morse

Return Sendstring: For N = 1 To Len(txtstring) ' Textstring ausgeben M = Txt(n) M = Lookup(m , Morsetabelle) ' Morsezeichen aus Tabelle holen Gosub Morse
Next N

Return '------- Erzeugung der zu sendenden Morsezeichen ------- Morse: Ocr0a = Tonhoehe1

If M = 0 Then ' Sonderfall: Leerzeichen; Waitms Wortpause1
Goto Zeichenende
End If For I = 1 To 8 If M = 1 Then ' Das Byte hat nur noch den Wert 1; Zeichenende! Goto Zeichenende
End If L = M And &B00000001 ' niederwertigstes Bit lesen Buzzer = 1 If L = 1 Then Waitms Strichlaenge1 ' ist das Bit 1 -> dah Else Waitms Punktlaenge1 ' ist das Bit 0 -> dit End If Buzzer = 0 Waitms Punktlaenge1 ' Pause innerhalb des Morsezeichens Shift M , Right , 1 ' Bits um eine Stelle nach rechts shiften Next I

Zeichenende: Waitms Strichlaenge1 ' Pause zwischen Morsezeichen Return '--- Hier beginnt die Auswertung der Morse- Eingaben -------- '------ Menü ( Befehle bestehen aus 1 Zeichen ) ----- Menue: Gosub Decodekeyer

Select Case E

Case 65 ' 65 : Ascii - Wert "A" Txtstring = " ALARM?" Gosub Sendstring
R = 1 Gosub Readnumbers
If G(1) = 1 Then Alarm = 1 Else Alarm = 0 End If Case 71 ' 71 : Ascii - Wert "G" Txtstring = " GONG?" Gosub Sendstring
R = 1 Gosub Readnumbers
If G(1) = 1 Then Gong = 1 Else Gong = 0 End If Case 67 ' 67 : Ascii- Wert "C" Gosub Check

Case 75 ' 75 : Ascii- Wert "K" Txtstring = " KORRSEK?" Gosub Sendstring
R = 1 Gosub Readnumbers
Korr = G(1) Case 77 ' 77 : Ascii - Wert "M" Txtstring = " WPM?" Gosub Sendstring
Gosub Speed

Case 84 ' 84 : Ascii - Wert "T" Gosub Zeitausgabe

Case 87 ' 87 : Ascii - Wert "W" Txtstring = " WECKZEIT?" Gosub Sendstring
Gosub Weckzeitsetzen

Case 90 ' 90 : Ascii - Wert "Z" Txtstring = " ZEIT?" Gosub Sendstring
Gosub Zeitsetzen

Case 63 ' 63 : Ascii - Wert "?" Txtstring = "BEFEHLE: ALARM CHECK ENDE GONG KORRSEK MORSESPEED TIME WECKZEIT ZEITSETZEN" Gosub Sendstring

End Select Return ' ----- hier folgen die Subroutinen, die durch das Menü aufgerufen werden ------ Zeitsetzen: S = 0 ' Sekunden auf 0 setzen R = 4 Gosub Readnumbers

Hilf = G(3) * 10 ' G(3) Zehnerstelle Minuten T = G(4) + Hilf ' G(4) Einerstelle Minuten Hilf = G(2) * 60 ' G(2) Einerstelle Stunden T = T + Hilf
Hilf = 600 * G(1) ' G(1) Zehnerstelle Stunden T = T + Hilf ' T Tagesminuten If T > 1439 Then ' später als 23.59 Uhr T = 1 ' Workaround, damit der Gong nicht anspricht Txtstring = " RPT" Gosub Sendstring
End If Return Weckzeitsetzen: R = 4 Gosub Readnumbers

Hilf = G(3) * 10 Ta = G(4) + Hilf
Hilf = G(2) * 60 Ta = Ta + Hilf
Hilf = 600 * G(1) Ta = Ta + Hilf ' Ta: Tagesminuten Alarmzeit If Ta > 1439 Then Txtstring = " RPT" Gosub Sendstring
End If Return Speed: R = 2 Gosub Readnumbers

' Aus dem abgefragten Wert neue Geschwindigkeit berechnen Calcspeed: G(1) = 10 * G(1) ' Zehnerstelle WPM G(1) = G(1) + G(2) ' Einerstella addieren Punktlaenge1 = 1320 / G(1) ' aus WPM Punkitlänge errechnen Strichlaenge1 = Punktlaenge1 * 3 Wortpause1 = Punktlaenge1 * 5 Punktlaenge2 = 3 * Punktlaenge1 ' Sendegeschwindigkeit soll nur 2/3 der Punktlaenge2 = Punktlaenge2 / 2 ' Empfangsgeschwindigkeit sein Punktachtel = Punktlaenge2 / 8 If Punktachtel = 0 Then Punktachtel = 1 End If Strichlaenge2 = Punktlaenge2 * 3 Wortpause2 = Punktlaenge2 * 5 If G(1) < 10 Or G(1) > 30 Then ' auf plausiblen Wert prüfen G(1) = 2 G(2) = 0 Goto Calcspeed ' Neuberechnung mit Default- Werten End If Return Check: Txtstring = " ALARM " Gosub Sendstring
M = Alarm
Gosub Sendnumber
Txtstring = " GONG " Gosub Sendstring
M = Gong
Gosub Sendnumber
Txtstring = " KORRSEK " Gosub Sendstring
M = Korr
Gosub Sendnumber
Txtstring = " WECKZEIT " Gosub Sendstring
Gosub Weckzeitaugabe

Return '------ Morseingabe- Auswerteroutinen ------- Readnumbers: I = 0 Notbremse = 0 Do If Punktkontakt = 0 Or Strichkontakt = 0 Then ' Punkt - oder Strichkontakt gedrückt I = I + 1 Gosub Decodekeyer
G(i) = E ' jeweils Ascii- Wert einstellige Zahl abholen Select Case G(i) Case 48 To 57 G(i) = G(i) - 48 ' auf Zahleneingabe prüfen Case Else Txtstring = "RPT" Gosub Sendstring
Return End Select End If Notbremse = Notbremse + 1 Waitms 20 If Notbremse > 250 Then ' Ausstieg nach längerer Eingabepause (5 sec) Txtstring = "RPT" Gosub Sendstring
Return End If Loop Until I = R

Waitms 200 For W = 1 To R ' zur Kontrolle die Zahlen ausgeben M = G(w) Gosub Sendnumber
Next Return '------- Interpretation der eingegebenen Einzel- Morsezeichen ---- Decodekeyer: ' Prinzip: eine 1 wird in der Variablen "K" von links nach rechts geschoben. ' nur wenn Strich gedrückt wurde, wird die 1 in die Variable D übernommen Ocr0a = Tonhoehe2
D = 0 K = 1 Do If Punktkontakt = 0 Then ' Punktkontakt gedrückt Buzzer = 1 ' Ton an Waitms Punktlaenge2
Buzzer = 0 ' Ton aus Waitms Punktlaenge2
Shift K , Left ' Byteinhalt wandert 1 Stelle nach links, von rechts wird eine "0" eingeschoben End If Mark: If Strichkontakt = 0 Then ' Strichkontakt gedrückt Buzzer = 1 ' Ton an Waitms Strichlaenge2
D = D + K ' die 1 für den Strich wird in die Variable "D" übernommen Shift K , Left ' Byteinhalt wandert 1 Stelle nach rechts, von links eine "0" eingeschoben If Punktkontakt = 0 Then P = 1 ' wenn Punktkontakt ebenfalls gedrückt End If ' Punktspeicher setzen Buzzer = 0 ' Ton aus Waitms Punktlaenge2

If P = 1 Then ' Punktspeicher prüfen Buzzer = 1 ' Ton an Waitms Punktlaenge2
Buzzer = 0 ' Ton aus Waitms Punktlaenge2
Shift K , Left ' Byteinhalt wandert 1 Stelle nach links, rechts wird 0 eingeschoben P = 0 ' Punktspeicher zurücksetzen Goto Mark ' Prüfen, ob Strichkontakt bereits wieder gedrückt End If End If J = 0 Do ' wir warten max. halbe Punktlänge, um unexakte Gebeweise abzufangen If Punktkontakt = 0 Or Strichkontakt = 0 Then ' vorzeitiger Ausstieg, wenn Punktkontakt oder Strichkontakt gedrückt Exit Do End If Waitms Punktachtel
J = J + 1 Loop Until J = 4 ' Abbruch bei halber Punktlänge Loop Until Punktkontakt = 1 And Strichkontakt = 1 ' kein Kontakt mehr gedrückt; Morsezeichen fertig D = D + K ' eine 1 wird als Endbit angehängt E = Lookdown(d , Morsetabelle , 91) ' inverse Lookup in der Tabelle, um den zugehörigen Ascii- Wert zu ermitteln E = E - 1 ' Data- Elemente werden ab 1 gezählt, Ascii- Tabelle beginnt bei Null Return '--- Interrupt- Routine Sekundentakt ------ Ontimer1: ' Timer1-Overflow-Interrupt-Routine Tcnt1 = 31 ' Preset auf 31, damit der Timer 225 Takte bis Ueberlauf zählt S = S + 1 If S > 59 Then ' Minutenwechsel S = 0 T = T + 1 End If Return '--- Morsezeichen- Tabelle -------------------------- Morsetabelle: 'Ascii 0 - 32 ; hier wird nur Linefeed in <kn> umgesetzt Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , &B00101101 , 0 , , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 Data 0 , 0 , 0 , 0 , 0 , 0 , 0 ' Ascii 32 - 47 -> _!"#$%&'()*+,-./ Data 0 , 0 , &B01010010 , 0 , 0 , 0 , 0 , 0 , &B00101101 , &B01101101 , 0 , &B00101010 , &B01110011 , &B01100001
Data &B01101010 , &B00101001

'Ascii 48 - 57 -> 0123456789 Data &B00111111 , &B00111110 , &B00111100 , &B00111000 , &B00110000 , &B00100000 , &B00100001 , &B00100011 , &B00100111 , &B00101111

'Ascii 58 - 64 -> :;<=>?@ Data &B01000111 , &B01110011 , &B00101101 , &B00110001 , &B01101101 , &B01001100 , 0 'Ascii 65 - 90 ABCDEFGHIJKLMNOPQRSTUVWXYZ Data &B00000110 , &B00010001 , &B00010101 , &B00001001 , &B00000010 , &B00010100 , &B00001011 , &B00010000 , &B00000100
Data &B00011110 , &B00001101 , &B00010010 , &B00000111 , &B00000101 , &B00001111 , &B00010110 , &B00011011 , &B00001010
Data &B00001000 , &B00000011 , &B00001100 , &B00011000 , &B00001110 , &B00011001 , &B00011101 , &B00010011

'Ascii 91 - 127 -> Muell


Elektronik-Labor   Projekte   AVR