Elektronik-Labor Projekte AVR
'
' Less-sux Attiny24: Morsetrainer für 5er- Gruppen nach der Koch- Methode.
'
' Lektion 1 beginnt mit 4 Zeichen,
' jeweils 4 neue Zeichen pro Lektion - > 13 Lektionen, 12 Zwischenlektionen
' gerade Lektionen: nur neue Zeichen, ungerade Lektionen: alle bisherigen Zeichen
'
' Pseudo- Lektionsnummer 0 erzeugt PARIS- Schleife (für Geschwindigkeitskontrolle)
' Lektionsnummer wird mit Mäuseklavier an PA0...PA4 eingestellt
' Lektion 26 erzeugt 5er- Gruppen ohne Sonderzeichen und Zahlen
' Pin PA6 wird als Timer1-Ausgang OC1a verwendet, Ton wird durch Umschalten des
' Pins als Eingang / Ausgang ein- und ausgeschaltet. Tonhöhe wird über Poti an PA5
' und den ADC eingestellt.
'
' Geschwindigkeit ist in 11 Stufen schaltbar (4 Bits an PB0 bis PB2 und PA7).
' Unter 60 ZPM werden die Pausen verlängert, um auf niedrigere Geschwindigkeiten zu kommen
' ( 15 Zeichen pro Minute bis 100 ZPM)
'
' Der Bascom-Zufallsgenerator hat eine Macke (Bascom Version 1.11.9.8):
' Bei RND(2) kommt 0,1,0,1,0.... bei RND(4) kommt 0,1,2,3,0,1,2,3.....
'
' Daher statt RND(4) -> RND(12) / 3
'
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'
' Grundeinstelllungen:
$regfile = "attiny24.dat"
$crystal = 1000000
$hwstack = 40
$swstack = 10
$framesize = 20
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'Variablen und Konstanten dimensionieren:
'
Dim Weerndinit As Eram Word ' Initialisierungswert für den Pseudo-Zufallsgenerator im EEPROM
Dim ___rseed As Word ' Initialisierungs-Variable des Pseudo-Zufallsgenerators, siehe Bascom-Hilfe unter "Rnd()"
'
Dim I As Byte ' Für temporären Gebrauch als Schleifenzähler
Dim M As Byte ' Index des aktuellen Morsebuchstabens in unserer Tabelle
Dim L As Byte ' für niederwertigstes Bit beim bitweisen Erzeugen des Morsezeichens
Dim P As Byte ' für Port- Abfrage Geschwindigkeit und Zeichensatz
Dim A As Byte ' für gerde/ungerade Lektionen
Dim G As Byte ' Zählvariable
Dim R As Word ' für LowByte von Rnd()
Dim Wortindex As Word '
Dim Wortpos As Byte ' Portbits
Dim Wortstring As String * 8
Dim Wortlaenge As Byte
Dim Wortchar As String * 1
Dim Wortbyte As Byte At Wortchar Overlay ' Overlay- Variable (Byte- Wert von Wortchar)
Dim Tonhoehe As Word
Dim Punktlaenge As Word ' Punktlänge
Dim Strichlaenge As Word ' Strichlänge
Dim Zeichenpause As Word ' Länge der Pause zwischen den Zeichen
Dim Wortpause As Word ' Länge der Pause zwischen den Worten bzw. 5er-Gruppen
' Morseton mit Timer1 erzeugen:
Config Timer1 = Timer , Prescale = 1 , Compare A = Toggle , Clear Timer = 1
Start Timer1
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc
Enable Interrupts
Acsr.acd = 1 'Analog-Komparator ausschalten, spart etwas Strom
Porta = &B11011111 ' floatende Eingänge vermeiden
Portb = &B00001111 ' floatende Eingänge vermeiden
Ddra = &B00000000
Ddrb = &B00000000
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Main:
' Zufallsgenerator- Initialisierung ist beim Rowalt- Mini- Fuchsjagdsender "Floh" ausgeliehen:
' Zufallsgenerator zur Auswahl der jeweiligen Morsebuchstaben initialisieren:
' Damit der Pseudo-Zufallsgenerator nicht jedesmal nach dem Reset die gleichen Zeichenfolgen erzeugt, müssen wir ihn mit einem
' veränderlichen Startwert füttern. Wir lösen das auf einfachste Weise, indem wir hochzählen, wie oft das Programm bereits
' gestartet wurde und die Bits etwas rotieren lassen. Der entstandene Wert wird dann wieder im EEPROM abgelegt:
___rseed = Weerndinit 'Initialisierungswert aus dem EEPROM holen und Zufallsgenerator damit initialisieren
Rotate ___rseed , Left , 7 'Die Bits des Initialisierungswerts rotieren lassen...
Incr ___rseed 'und den Wert um 1 erhöhen. Damit sollte ein recht zufälliger Eindruck entstehen.
Weerndinit = ___rseed 'Und nun den neuen Wert im EEPROM ablegen.
' Auswahl Geschwindigkeit
P = Not Pinb ' Abfrage Portbits PB0 - PB7 und PA7
G = Not Pina.7
Shift G , Left , 3
P = P And &B00000111 ' PB3-PB7 werden weggeworfen
P = P Or G
Select Case P
Case 0
Punktlaenge = 74
Zeichenpause = 2400 ' eff. 15 ZPM
Case 1
Punktlaenge = 74
Zeichenpause = 1720 ' eff. 20 ZPM
Case 2
Punktlaenge = 74
Zeichenpause = 1350 ' eff. 25 ZPM
Case 3
Punktlaenge = 74
Zeichenpause = 1040 ' eff. 30 ZPM
Case 4
Punktlaenge = 74
Zeichenpause = 820 ' eff 40 ZPM
Case 5
Punktlaenge = 74
Zeichenpause = 480 ' eff 50 ZPM
Case 6
Punktlaenge = 74
Zeichenpause = 325 ' 60 ZPM
Case 7
Punktlaenge = 74
Zeichenpause = 222 ' 70 ZPM
Case 8
Punktlaenge = 65
Zeichenpause = 195 ' 80 ZPM
Case 9
Punktlaenge = 58
Zeichenpause = 173 ' 90 ZPM
Case Else
Punktlaenge = 52
Zeichenpause = 155 ' 100 ZPM
End Select
Strichlaenge = Punktlaenge * 3 'Strichlänge
' Lebenszeichen / Spruchbegin
Waitms 300
M = 51 ' Zeichen <KA> (Spruchbeginn)
M = Lookup(m , Morsetabelle_1) ' Morsezeichen aus Tabelle holen
Gosub Morse
Wait 2
' Auswahl Lektionen (also Umfang des Zeichensatzes)
P = Not Pina ' Abfrage und Invertierung Portbits PC0 ... PC7
P = P And &B00011111 ' Kapitelnummer; nur Bits PA0...PA4 berücksichtigen
Wortpause = Zeichenpause
Shift Wortpause , Left , 1 'Länge Wortpause = 2 * Zeichenpause
If P = 0 Then 'Verzweigung in die Ausgaben des Geschwindigkeits- Normwortes "Paris"
Gosub Paris 'Paris
End If
If P > 25 Then ' ungültige Eingabe abfangen
Gosub Gruppen
End If
' Erzeugung von 5er- Gruppen mit Zufallsgenerator
A = P Mod 2 ' A = 1 wenn P ungerade
Shift P , Left , 1 ' entspricht P = 2 * P -> P = 0, 2, 4 ....
Do
For G = 1 To 5
If A = 0 Then ' auschhliesslich die neuen Zeichen
R = Rnd(12) / 3 ' RND(12)/3, weil bei RND(4) kommt Zeichenfolge 0,1,2,3,0,1,2,3....
R = P + R ' P = 0, 4, 8, 12.... plus Zufallswert 0...3
Else
R = P + 2
R = 3 * R
R = Rnd(r) / 3
End If
M = Low(r) ' nur unteres Byte des Wortes verwenden
M = Lookup(m , Morsetabelle_1) ' Morsezeichen aus Tabelle holen
Gosub Morse
Next
Waitms Wortpause
Loop
' Ausgabe Normwort für Geschwindigkeitsmessungen
Paris:
Do
For G = 0 To 4
M = G
M = Lookup(m , Morsetabelle_2) ' Morsezeichen aus Tabelle holen
Gosub Morse
Next
Waitms Wortpause
Loop
' 5er- Gruppen ohne Sonderzeichen und Zahlen:
Gruppen:
Do
P = 26
For G = 0 To 4
R = Rnd(p) ' M = 0 .... 25
M = Low(r)
M = Lookup(m , Morsetabelle_3) ' Morsezeichen aus Tabelle holen
Gosub Morse
Next
Waitms Wortpause
Loop
' Morsezeichenerzeugung:
Morse:
Gosub Poti
If M = 0 Then ' Sonderfall: Leerzeichen statt nicht morsbarer ASCII- Zeichen
Waitms Wortpause
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
Ddra.6 = 1
If L = 1 Then
Waitms Strichlaenge ' ist das Bit 1 -> dah
Else
Waitms Punktlaenge ' ist das Bit 0 -> dit
End If
Ddra.6 = 0
Waitms Punktlaenge ' Pause innerhalb des Morsezeichens
Shift M , Right , 1 ' Bits um eine Stelle nach rechts shiften
Next I
Zeichenende:
Waitms Zeichenpause ' Pause zwischen Morsezeichen
Return
Poti:
Tonhoehe = Getadc(5) ' Tonhoehe durch Poti einstellbar
Tonhoehe = Tonhoehe + 1024 'für sinnvollen Einstellbereich
Ocr1ah = High(tonhoehe)
Ocr1al = Low(tonhoehe)
Return
End
'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Morsetabelle_1: 'Reihenfolge Koch- Methode:
' -> K M U R E S N A P T L W I . J Z - F O Y , V G 5 / Q 9 2 H 3 8 B ? 4 7 C 1 D 6 Ø X =
' -> zusätzliche: : ( ) + " ä ö ü ch <KA>
Data &B00001101 , &B00000111 , &B00001100 , &B00001010 , &B00000010
Data &B00001000 , &B00000101 , &B00000110 , &B00010110 , &B00000011
Data &B00010010 , &B00001110 , &B00000100 , &B01101010 , &B00011110
Data &B00010011 , &B01100001 , &B00010100 , &B00001111 , &B00011101
Data &B01110011 , &B00011000 , &B00001011 , &B00100000 , &B00101001
Data &B00011011 , &B00101111 , &B00111100 , &B00010000 , &B00111000
Data &B00100111 , &B00010001 , &B01001100 , &B00110000 , &B00100011
Data &B00010101 , &B00111110 , &B00001001 , &B00100001 , &B00111111
Data &B00011001 , &B00110001
Data &B01000111 , &B00101101 , &B01101101 , &B00101010 , &B01010010
Data &B00011010 , &B00010111 , &B00011100 , &B00011111 , &B00110101
Morsetabelle_2: ' für Paris-Schleife
Data &B00010110 , &B00000110 , &B00001010 , &B00000100 , &B00001000
Morsetabelle_3: ' für 5er-Gruppen
' 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
' ä ö ü ch
'Data &B00011010 , &B00010111 , &B00011100 , &B00011111