'# LCD-Routinen für M50530 #
'# ======================= #
'# #
'# Titel : 4 Bit LCD M50530 #
'# Autor : Arno Schweißinger #
'# Datum : 27.12.2013 #
'# MC : AtMega8 1MHz #
'# MC : #
'# Stromversorgung: MC 5V; #
'# LCD 5V & 8,2V #
'# 4bit-Interface M50530 #
'# #
'# DB4: Alias Portc.0 #
'# DB5: Alias Portc.1 #
'# DB6: Alias Portc.2 #
'# DB7: Alias Portc.3 #
'# OC1: Alias Portb.2 #
'# OC2: Alias Portb.1 #
'# EX: Alias Portb.0 #

' Ports ggf anpassen
_d4 Alias Portc.0
_d5 Alias Portc.1
_d6 Alias Portc.2
_d7 Alias Portc.3
_oc1 Alias Portb.2
_oc2 Alias Portb.1
_ex Alias Portb.0
Const _extime = 20 ' 20us Execution Time

$regfile = "m8def.dat"
$crystal = 1000000 ' Internal RC-Osc
' $lib "mcsbyte.lbx" ' use byte library for smaller code
' $lib "mcsbyteint.lbx" ' use byte library for smaller code
' MCSBYTEINT

Enable Interrupts
Config Date = Dmy , Separator = . ' ANSI-Format
Config Clock = Soft
' Date$ = "26.03.07"
Time$ = "23:17:45"

Declare Sub Lcd_init()
Declare Sub Lcd_str(message As String * 24)
Declare Sub Lcd_xy(_x As Byte , _y As Byte)
Declare Sub Lcd_cls
Declare Sub Lcd_byte(by As Byte)
Declare Sub Lcd_command(command As Byte)
Declare Sub Lcd_out(command As Byte)
Declare Sub Lcd_enable

Declare Sub Textausgabe
Declare Sub Striche


Dim Temp As Byte ' Übergabe an Sub
Dim Lcd_parameter As Byte ' Übergabe an Sub
Dim _ch As String * 1 ' char in sub Lcd_str
Dim _i As Byte ' Zählschleife Sub Lcd_str
Dim Text As String * 24 ' Ausgabe einer Zeile
Dim X As Byte , Y As Byte ' Übergabe Cursor Position

Dim Felder As Byte ' Sub Textausgabe Zählschleife
Dim Modfelder As Byte ' Sub Textausgabe Zählschleife
Dim Stunde As Byte ' Sub Textausgabe
Dim Index1 As Integer ' Sub Textausgabe
Dim Feldpos As Byte ' Sub Textausgabe
Dim Strich As String * 1 ' sub striche
Strich = "-" ' sub striche
Dim Ltext As Byte ' sub striche länge text
Dim Itext As Byte ' sub striche Zählschleife


'-------------------------
' Begin Hauptprogramm
'-------------------------
Call Lcd_init
Do
X = 1 : Y = 8
Call Lcd_xy(x , Y)
Call Lcd_str(time$)
Call Textausgabe
Waitms 200
Loop
End
'-------------------------
' Ende Hauptprogramm
'-------------------------

'****************************************************************************
Sub Textausgabe
'****************************************************************************

Index1 = Lookup(_min , Textfolge )
Feldpos = 0

For Felder = 0 To 11

X = Lookup(feldpos , Koordinaten )
Incr Feldpos
Y = Lookup(feldpos , Koordinaten )
Incr Feldpos
Call Lcd_xy(x , Y)

Text = Lookupstr(felder , Textfeld )
If Index1.felder = 1 Then
Call Lcd_str(text)
Else
Call Striche
End If
Next Felder
Feldpos = 0

Stunde = _hour ' kopie der Stunden
If Stunde = 0 Then Stunde = 12 ' Null Uhr gibt es nicht
If Stunde > 12 Then Stunde = Stunde - 12 ' Keine 13-24 stunden
If Index1.12 = 1 Then Incr Stunde ' Stunde weiter anzeigen
If Stunde = 13 Then Stunde = 1 ' Nullduchgang
Decr Stunde

For Felder = 0 To 11
X = Lookup(feldpos , Zahlenkoor )
Incr Feldpos
Y = Lookup(feldpos , Zahlenkoor )
Incr Feldpos
Call Lcd_xy(x , Y)
Text = Lookupstr(felder , Zahlentext )
If Felder = Stunde Then
Call Lcd_str(text)
Else
Call Striche
End If

Next Felder
End Sub

Sub Striche
Ltext = Len(text)
For Itext = 1 To Ltext
Call Lcd_str(strich)
Next Itext
End Sub


Sub Lcd_init()
Config _oc1 = Output
Config _oc2 = Output
Config _ex = Output
Config _d4 = Output
Config _d5 = Output
Config _d6 = Output
Config _d7 = Output
Lcd_parameter = &B11011010 ' set function mode (SF) 0b11011010
Call Lcd_command(lcd_parameter) ' 4bit-Modus einstellen 11 -4/8bit-FONT-2xDUTY-2xRAM
Lcd_parameter = $50 ' set entry mode (SE) 0b01010000
Call Lcd_command(lcd_parameter) ' Cursor selbst setzen
Lcd_parameter = $30 ' set display mode (SD) 0b00110011
Call Lcd_command(lcd_parameter) ' Display ein, Cursor nicht anzeigen
Call Lcd_cls
End Sub

Sub Lcd_str(message)
For _i = 1 To 24
_ch = Mid(message , _i , 1)
Temp = Asc(_ch)
If Temp = 0 Then Exit For
Call Lcd_byte(temp)
Next _i
End Sub

Sub Lcd_byte(by)
Reset _oc1 ' Write DATA RAM
Set _oc2
Call Lcd_out(by)
End Sub

Sub Lcd_xy(_x , _y )
Select Case _y
Case 1 : Lcd_parameter = $00 ' $00 Werte bei SF=$D8
Case 2 : Lcd_parameter = $30 ' $40
Case 3 : Lcd_parameter = $60 ' $80
Case 4 : Lcd_parameter = $90 ' $c0
Case 5 : Lcd_parameter = $18 ' $18
Case 6 : Lcd_parameter = $48 ' $58
Case 7 : Lcd_parameter = $78 ' $98
Case 8 : Lcd_parameter = $a8 ' $d8
Case Else : Lcd_parameter = $00
End Select
Lcd_parameter = Lcd_parameter + _x
Decr Lcd_parameter
Set _oc1 ' Write Cursor adress to RAM
Set _oc2
Call Lcd_out(lcd_parameter)
End Sub

Sub Lcd_cls
Lcd_parameter = $01 ' Command: Clear Home
Call Lcd_command(lcd_parameter)
Waitms 2
End Sub

Sub Lcd_command(command)
Reset _oc1 ' Command
Reset _oc2
Call Lcd_out(command)
End Sub

Sub Lcd_out(command)
' first high nibble
If Command.7 = 1 Then
Set _d7
Else
Reset _d7
End If
If Command.6 = 1 Then
Set _d6
Else
Reset _d6
End If
If Command.5 = 1 Then
Set _d5
Else
Reset _d5
End If
If Command.4 = 1 Then
Set _d4
Else
Reset _d4
End If
Call Lcd_enable

' second low nibble
If Command.3 = 1 Then
Set _d7
Else
Reset _d7
End If
If Command.2 = 1 Then
Set _d6
Else
Reset _d6
End If
If Command.1 = 1 Then
Set _d5
Else
Reset _d5
End If
If Command.0 = 1 Then
Set _d4
Else
Reset _d4
End If
Call Lcd_enable
End Sub

Sub Lcd_enable
Set _ex : Waitus _extime
Reset _ex : Waitus _extime
End Sub

Textfolge:
'********************************************************
' Decodieren der Minuten in Text
'
' 00:00 1. Zeile Data 1 , 8
' . Zeile
' 00:59 60. Zeile Data 5 , 17
'
' 1. Byte
' 0.Bit = Es ist
' 1.Bit = Eben War
' 2.Bit = Gleich
' 3.Bit = Kurz
' 4.Bit = Fünf
' 5.Bit = Zehn
' 6.Bit = Viertel
' 7.Bit = Zwanzig
'
' 2. Byte
' 0.Bit = Vor
' 1.Bit = Nach
' 2.Bit = Halb
' 3.Bit = Punkt
' 4.Bit = Stunde + 1
'********************************************************
Data 2049% '00
Data 2% '01
Data 521% '02
Data 521% '03
Data 533% '04
Data 529% '05
Data 530% '06
Data 530% '07
Data 549% '08
Data 549% '09
Data 545% '10
Data 546%
Data 546%
Data 581%
Data 581%
Data 577%
Data 578%
Data 578%
Data 645%
Data 645%
Data 641%
Data 642%
Data 642%
Data 5397%
Data 5397%
Data 5393%
Data 5394%
Data 5394%
Data 5389%
Data 5385%
Data 5121%
Data 5641%
Data 5641%
Data 5653%
Data 5653%
Data 5649%
Data 5650%
Data 5650%
Data 4485%
Data 4485%
Data 4481%
Data 4482%
Data 4482%
Data 4421%
Data 4421%
Data 4417%
Data 4418%
Data 4418%
Data 4389%
Data 4389%
Data 4385%
Data 4386%
Data 4386%
Data 4373%
Data 4373%
Data 4369%
Data 4370%
Data 4370%
Data 4359%
Data 4357% '59


Textfeld:
Data "Es ist"
Data "Eben war"
Data "gleich"
Data "kurz"
Data "fuenf"
Data "zehn"
Data "viertel"
Data "zwanzig"
' 2. Byte
Data "vor"
Data "nach"
Data "halb"
Data "Punkt"
' 4.Bit = Stunde + 1

Koordinaten:
Data 1 , 1 ' "Es ist "
Data 8 , 1 ' "Eben war "
Data 17 , 1 ' "gleich "
Data 1 , 2 ' "kurz "
Data 6 , 2 ' "fünf "
Data 12 , 2 ' "zehn "
Data 17 , 2 ' "viertel"
Data 1 , 3 ' "zwanzig"
Data 9 , 3
Data 13 , 3
Data 18 , 3
Data 1 , 4

Zahlentext:
Data "eins"
Data "zwei"
Data "drei"
Data "vier"
Data "fuenf"
Data "sechs"
Data "sieben"
Data "acht"
Data "neun"
Data "zehn"
Data "elf"
Data "zwolf"

Zahlenkoor:
Data 7 , 4
Data 12 , 4
Data 17 , 4
Data 1 , 5
Data 6 , 5
Data 12 , 5
Data 18 , 5
Data 1 , 6
Data 6 , 6
Data 11 , 6
Data 16 , 6
Data 20 , 6