Terfagter
03.03.2007, 18:38
Hallo,
habe mich jetzt die ganze Zeit durchs Forum gelesen, jedoch finde ich immer nur Bruchteile.
Ich möchte das Samsung 0282a 8x24 Zeichen mit 16 Pin Ansteuerung mit einem AtMega 16 betreiben und dort verschiedene Temperaturen und das Datum plus Uhr anzeigen lassen. Die Uhr soll eine Softclock sein mit 2 Tastern zum Stellen der Uhr. Der Quelltext ist von Andree-HB übernommen worden und nicht bearbeitet. (siehe Quelltext 1) Er benutzt aber leider ein Display das direkt mit Bascom zusammenarbeitet. Jetzt habe ich auf mikrocontroller.net einen Ansatz gefunden, um dieses Display anzusteuern, komme damit aber noch nicht richtig parat.(siehe Quelltext 2)
Ich würde gerne erstmal einfach eine Uhrzeit und ein Datum ausgeben, dafür müsste ich natürlich erstmal das Display ansteuern können.
Kann mir jemand beim Umschreiben des Codes helfen, sodass ich die Softclock benutzen kann? Die Temperatursensoren auszulesen wäre dann wieder kein Problem.
Gruß
Bene
'************************************************* ***********
'
'Atmega Softclock -> genau Uhrzeit ohne RTC (Real-Time-Clock)
'
'Benutzt wird ein Mega8/8, Fusebits auf Auslieferungszustand,
'Lcd An Portb , Taster Zum Stellen An Pd.0
'zum Hochzählen An Pd.3.
'zwischen XTAL ist ein 32.xxx Uhrenquarz
'14.08.2006, Andree-HB, www.pixelklecks.de
'************************************************* ***********
$regfile = "m8def.dat"
Config Lcdpin = Pin , Rs = Portb.0 , E = Portb.1 , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5
Config Lcd = 24 * 2
Initlcd
Cursor Off
Cls
Enable Interrupts
Config Date = Mdy , Separator = /
Config Clock = Soft
Config Portd = Input
Portd.0 = 1 'Taster1, Zeit/Datum stellen, PullUp ein, schaltet gegen Minus
Portd.3 = 1 'Taster2, Zahl hochzählen, PullUp ein, schaltet gegen Minus
Time$ = "00:00:00" 'Setzen auf Startwert
Date$ = "00/00/00" 'Setzen auf Startwert
Do
Locate 1 , 1
Lcd Time$ 'Zeige Zeit in Zeile1
Locate 2 , 1
Lcd _day ; "/" ; _month ; "/0" ; _year 'Zeige Datum in Form DD/MM/YYin Zeile2
'lcd Date$ 'zeige Datum in Form MM/DD/YY
If Pind.0 = 0 Then Gosub Time 'wiederhole Anzeige bis Taster 1 zum Stellen gedrückt, springe nach Sub "Time"
Loop
End
'Stunde
Time:
Waitms 200
Cls 'lösche Zeilen
Do
Locate 1 , 1
Lcd "Set Hour:" 'Stunden setzen
Locate 2 , 1
Lcd _hour
If Pind.3 = 0 Then 'Mit Taster 2
Incr _hour 'hochzählen
Locate 2 , 1
Lcd _hour
End If
If _hour > 23 Then 'Zählt bis Max, danach wieder ab 0
Cls
_hour = 00
End If 'solange, bis Taster 1 gedrückt
Loop Until Pind.0 = 0
Waitms 200
'Minute
Cls
Do
Locate 1 , 1
Lcd "Set Minute:"
Locate 2 , 1
Lcd _min
If Pind.3 = 0 Then
Incr _min
Locate 2 , 1
Lcd _min
End If
If _min > 59 Then
Cls
_min = 00
End If
Loop Until Pind.0 = 0
Waitms 200
Cls
'Tag
Cls
Do
Locate 1 , 1
Lcd "Set Day :"
Locate 2 , 1
Lcd _day
If Pind.3 = 0 Then
Incr _day
Locate 2 , 1
Lcd _day
End If
If _day > 31 Then
Cls
_day = 01
End If
Loop Until Pind.0 = 0
Waitms 200
Cls
'Monat
Cls
Do
Locate 1 , 1
Lcd "Set Month :"
Locate 2 , 1
Lcd _month
If Pind.3 = 0 Then
Incr _month
Locate 2 , 1
Lcd _month
End If
If _month > 12 Then
Cls
_month = 01
End If
Loop Until Pind.0 = 0
Waitms 200
Cls
'Jahr
Cls
Do
Locate 1 , 1
Lcd "Set Year :"
Locate 2 , 1
Lcd _year
If Pind.3 = 0 Then
Incr _year
Locate 2 , 1
Lcd _year
End If
If _year > 10 Then
Cls
_year = 00
End If
Loop Until Pind.0 = 0
Waitms 200
Cls
_sec = 00 'Springe Nach Setzen Von Zeit / Datum Wieder Zurueck
Return
'(################################################ #############################
Display Mit M50530 Aus Einem Siemenstelefon Optiset Memory E
Samsung 2138a Mit M50530 Controller / Ansteuerung Mit Attiny2313 Und Bascomdemo
Version 1.11.8.3
Die 2 Leds Sind Nur Zur Funktionskontrolle Während Der Erschaffung
dieses Quick-und-Dirty-Codes nötig und können entfallen.
Lcd - > Description
----------------------------------------
Pin 01 - > Ground - > Gnd
Pin 02 - > Data0 - > Portb.0
Pin 03 - > Data1 - > Portb.1
Pin 04 - > Data2 - > Portb.2
Pin 05 - > Data3 - > Portb.3
Pin 06 - > Data4 - > Portb.4
Pin 07 - > Data5 - > Portb.5
Pin 08 - > Data6 - > Portb.6
Pin 09 - > Data7 - > Portb.7
Pin 10 - > Ex - > Portd.3
Pin 11 - > R / W - > Portd.4
Pin 12 - > Oc2 - > Portd.5
Pin 13 - > Oc1 - > Portd.6
Pin 14 - > 8 , 2 Volt - > 8 , 2 Volt Poti Von 5..12v
Pin 15 - > 5 Volt - > 5 Volt
Pin 16 - > Ground - > Gnd
Ziel Ist Es , Das Lcd Per Rs232 / V24 Ansteuern Zu Können.
Das Display Soll Werte Einer Heizung(temp , Status Und Uhrzeit) Ausgeben.
Dazu Brauche Ich Funktionen Für Die Ausgabe Von Zeichenketten ,
Cursor Setzen(locate) Und Bildschirm Löschen(cls).
Jede Ausgabe Per V24 An Das Lcd Sieht Folgendermassen Aus:
@zssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcrlf
@ Ist Das Kennungszeichen Und Muß Am Anfang Stehen
Z Ist Die Zeile Von 1..8 , Z = 0 Macht Cls
Ss Ist Die Spalte(2stellig) Von 0..23
Xxx..xxx Ist Der Auszugebende String
Cr Muß Folgen
Lf Kann Folgen
################################################## #############################
')
$regfile = "2313def.dat" ' IC-Typ
Const Quarz = 8000000 ' Quarz..
$crystal = Quarz ' ..festlegen
$baud = 19200 ' Baudrate V24
$hwstack = 32 ' Hardwarestack
$swstack = 24 ' Softwarestack
$framesize = 24 ' Framsize
'################################ INIT Timer0 #################################
Const Pre = 8 ' ergibt alle x ms einen Interrupt
Config Timer0 = Timer , Prescale = Pre
On Ovf0 Tim0_isr ' Define the ISR handler
Enable Timer0
Const Reload = Int(quarz /((256 * Pre) * 100)) ' für 10 ms
'################################ INIT UART0 ##################################
On Urxc Ser_inp ' Interrupt-Routine setzen
Enable Urxc ' Interrupt URXC einschalten
'################################ INIT Watchdog ###############################
Config Watchdog = 2048 ' 2 Sekunden Watchdog
Const Sreload = 100 ' Sollwert für 1 Sekunde
Const Cdispinit = &B1111_1010 ' Display-SF
Const Lmax = 28 ' Max Buffer-Länge
'----------------------------- Display ----------------------------------------
Lcddata Alias Portb ' Portb 0-7 ist Data0-7 am Display (Pin 2-9)
' also 8-Bit-Modus
Ex Alias Portd.3 ' EX
Rw Alias Portd.4 ' R/W
Oc2 Alias Portd.5 ' OC2
Oc1 Alias Portd.6 ' OC1
Ddrd = &B111_1110 ' PortD Ausgang außer RxD
Ddrb = &B1111_1111 ' PortB Ausgang
Portd = &B000_0001 ' PortD alles auf 0 und RxD PullUp ein
Portb = &B0000_0000 ' PortB alles auf 0
Led_takt Alias Portd.2 ' 2s Takt
Led_v24 Alias Portd.1 ' V24-Bus-Kommunikation
Dim I As Byte ' Zählvariable
Dim L As Byte ' Zählvariable
Dim C As Byte ' ASCII-Wert des aktuellen Zeichens zum LCD
Dim Ch As String * 2 ' Str-Wert des aktuellen Zeichens zum LCD
Dim Led As Bit ' Merk-Bit für Takt-LED
Dim S As Byte ' Spalte für Locate
Dim Z As Byte ' Zeile für Locate
Dim Ioc As Byte ' Display-Modus
Dim D As Byte ' Datenbyte zum LCD
Dim T As Byte ' Temp-Variable in UP "Waitdisprdy"
Dim Now As Byte ' Zählvariable in UP "Waitdisprdy"
Dim Mscounter As Word ' 10ms-Counter
Dim Scounter As Byte ' 1s-Counter
Dim Buffer As String * 30 ' V24-Buffer
'================================================= =======================
Startup:
Enable Interrupts ' Freigabe der Interrups allgemein.
Wait 1 ' kleiner Vorsprung für LCD nach PowerON
Start Watchdog ' Watchdog starten
Gosub Lcd_init ' Init
Gosub Lcd_cls ' CLS
Gosub Lcd_home ' Home (eigentlich sinnlos, weil vorher CLS)
' ##################### Hauptprogramm ######################
Beginn:
Do
Nop ' sieht gut aus... ;-)
nop
nop
nop
nop
nop
nop
nop
nop
nop
Loop
' ##################### Ende Hauptprogramm #################
End 'End program
'************************************************* ***************************
Ser_inp:
'************************************************* ***************************
C = Udr ' Byte aus der UART auslesen
Led_v24 = 1 ' V24-LED an
If C > 31 And L < Lmax Then ' Grenzen für V24-String überwachen
Incr L
Buffer = Buffer + Chr(c) ' Buffer füllen
Else
If C = 13 Then ' <Enter> und damit String komplett
Disable Urxc ' V24 aus
Gosub Handle_buffer ' Buffer abarbeiten
Buffer = "" ' Buffer leeren
L = 0 ' Länge = 0
Enable Urxc ' V24 ein
End If
End If
Return
'************************************************* ***************************
Handle_buffer:
'************************************************* ***************************
If Mid(buffer , 1 , 1) = "@" And L > 3 Then ' erstes Zeichen ein @ ???
Ch = Mid(buffer , 2 , 1) ' Zeile holen...
Z = Val(ch) ' ... und in Zahl wandeln
Ch = Mid(buffer , 3 , 2) ' Spalte holen...
S = Val(ch) ' ... und in Zahl wandeln
If Z = 0 Then ' Zeile = 0... ?
Gosub Lcd_cls ' ...dann CLS
Else
Gosub Lcd_locate ' sonst Cursor setzen...
For I = 5 To L ' ... und ab da den String auf dem LCD ausgeben
Ch = Mid(buffer , I , 1) ' Zeichen holen...
C = Asc(ch) ' ...und als ASC and LCD_print übergeben
D = I + S ' Zeilenende auf LCD beachten
If D < 24 Then Gosub Lcd_print ' und Ausgeben...
Next I
End If
End If
Return
'************************************************* ***************************
Tim0_isr: ' Timer0-ISR
'************************************************* ***************************
If Mscounter < 1 Then ' Per Zählvariable eine 10ms-Funktion machen
Mscounter = Reload ' Reloadwert für 10ms
Gosub 10ms ' Funktion 10ms
Else
Mscounter = Mscounter - 1
End If
Return
'************************************************* ***************************
10ms: ' 10Milli-Sekunden-Interrupt
'************************************************* ***************************
Reset Watchdog
If Scounter < 1 Then ' Per Zählvariable eine 1s-Funktion machen
Scounter = Sreload ' Reloadwert für 1s
Gosub 1s ' Funktion 1s
Else
Scounter = Scounter - 1
End If
Return
'************************************************* ***************************
1s: ' Sekunden-Interrupt
'************************************************* ***************************
Led = Led Xor 1 ' Merk-Bit toggeln
Led_takt = Led ' Takt-LED blinken lassen
Led_v24 = 0 ' ggf. V24-LED aus
Return
'************************************************* ***************************
Lcd_cls: ' LCD löschen
'************************************************* ***************************
D = 1 : Ioc = 0
Gosub Writedata ' Clear Display, Cursor Home (CH)
Return
'************************************************* ***************************
Lcd_home: ' Cursor auf 0,0
'************************************************* ***************************
D = 0 : Ioc = 3
Gosub Writedata
Return
'************************************************* ***************************
Lcd_locate: ' Z=1..8 und S=0..23
'************************************************* ***************************
If Z < 9 And Z > 0 Then ' Z=1..8 ?
Select Case Z ' Zeilenadresse setzen
Case 1 : D = 0
Case 2 : D = 48
Case 3 : D = 96
Case 4 : D = 144
Case 5 : D = 24
Case 6 : D = 72
Case 7 : D = 120
Case 8 : D = 168
End Select
D = D + S ' Spalte zur Zeilenadresse addieren
Ioc = 3 ' Modus 3 (OC1 und OC2 = 1)
If S < 24 Then Gosub Writedata ' wenn S=0..23, dann Cursor setzen
End If
Return
'************************************************* ***************************
Lcd_print: ' Zeichen regulär drucken
'************************************************* ***************************
D = C : Ioc = 2
Gosub Writedata
Return
'================================================= ===========================
Writedatadirect: ' ein Byte zum Display ohne Busy-Abfrage
'================================================= ===========================
Portb = D ' Sequenz aus diversen AVR-ASM-Sourcen
Reset Rw ' pollin.de und LCD4Linux (mlcd) abgeguckt...
Reset Ex ' muss nicht alles korrekt sein, geht aber
Oc1 = Ioc.0
Oc2 = Ioc.1
Portb = D
Waitms 1
Set Ex
Waitms 1
Reset Ex
Return
'================================================= ===========================
Writedata: ' ein Byte zum Display mit Busy-Abfrage
'================================================= ===========================
Gosub Waitdisprdy
Gosub Writedatadirect
Return
'================================================= ===========================
Waitdisprdy:
'================================================= ===========================
Now = 0 ' TimeOUT vorbereiten
Do
Set Rw : Reset Oc1 : Reset Oc2 : Reset Ex ' R/W auf Lesen
Waitms 1
Set Ex ' Enable-Impuls
Config Portb = Input ' PortD nun Eingang
nop ' kurz warten
T = Pinb And &B1000_0000 ' einlesen und Bit7 maskieren
Incr Now ' TimeOUT-Counter hochzählen
Reset Ex ' Enable=L
Loop Until T = 0 Or Now > 64 ' Busy-Bit=0 oder TimeOUT zugeschlagen
Config Portb = Output ' PortD wieder Ausgang
Portb = 0 ' alle Pins wieder auf L
Reset Rw ' R/W wieder auf Schreiben
Return
'================================================= ===========================
Lcd_init:
'================================================= ===========================
D = Cdispinit : Ioc = 0 ' Init-Sequenz aus pollin.de-Pascal-Source
Gosub Writedatadirect ' übernommen und geht scheinbar
Waitms 5
D = Cdispinit : Ioc = 0
Gosub Writedatadirect
Waitms 5
D = Cdispinit : Ioc = 0
Gosub Writedatadirect
D = Cdispinit : Ioc = 0 ' nun weiter mit Busy-Abfrage
Gosub Writedata
Waitms 15
D = Cdispinit : Ioc = 0
Gosub Writedata
Waitms 15
D = &H50 : Ioc = 0
Gosub Writedata ' SE Set Entrymode: Cursor increment bei R+W, DispStart konstant
Waitms 15
D = &B00111100 : Ioc = 0
Gosub Writedata
Waitms 15
D = 1 : Ioc = 0
Gosub Writedata ' Clear Display, Cursor Home (CH)
Waitms 15
D = 0 : Ioc = 1
Gosub Writedata ' DisplayStart an Adresse 0
Waitms 15
D = &B00001101 : Ioc = 0
Gosub Writedata ' Underlin off (SU)
Waitms 15
D = &B00110100 : Ioc = 0
Gosub Writedata ' Cursor off
Waitms 15
Return
'================================================= ===========================
habe mich jetzt die ganze Zeit durchs Forum gelesen, jedoch finde ich immer nur Bruchteile.
Ich möchte das Samsung 0282a 8x24 Zeichen mit 16 Pin Ansteuerung mit einem AtMega 16 betreiben und dort verschiedene Temperaturen und das Datum plus Uhr anzeigen lassen. Die Uhr soll eine Softclock sein mit 2 Tastern zum Stellen der Uhr. Der Quelltext ist von Andree-HB übernommen worden und nicht bearbeitet. (siehe Quelltext 1) Er benutzt aber leider ein Display das direkt mit Bascom zusammenarbeitet. Jetzt habe ich auf mikrocontroller.net einen Ansatz gefunden, um dieses Display anzusteuern, komme damit aber noch nicht richtig parat.(siehe Quelltext 2)
Ich würde gerne erstmal einfach eine Uhrzeit und ein Datum ausgeben, dafür müsste ich natürlich erstmal das Display ansteuern können.
Kann mir jemand beim Umschreiben des Codes helfen, sodass ich die Softclock benutzen kann? Die Temperatursensoren auszulesen wäre dann wieder kein Problem.
Gruß
Bene
'************************************************* ***********
'
'Atmega Softclock -> genau Uhrzeit ohne RTC (Real-Time-Clock)
'
'Benutzt wird ein Mega8/8, Fusebits auf Auslieferungszustand,
'Lcd An Portb , Taster Zum Stellen An Pd.0
'zum Hochzählen An Pd.3.
'zwischen XTAL ist ein 32.xxx Uhrenquarz
'14.08.2006, Andree-HB, www.pixelklecks.de
'************************************************* ***********
$regfile = "m8def.dat"
Config Lcdpin = Pin , Rs = Portb.0 , E = Portb.1 , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5
Config Lcd = 24 * 2
Initlcd
Cursor Off
Cls
Enable Interrupts
Config Date = Mdy , Separator = /
Config Clock = Soft
Config Portd = Input
Portd.0 = 1 'Taster1, Zeit/Datum stellen, PullUp ein, schaltet gegen Minus
Portd.3 = 1 'Taster2, Zahl hochzählen, PullUp ein, schaltet gegen Minus
Time$ = "00:00:00" 'Setzen auf Startwert
Date$ = "00/00/00" 'Setzen auf Startwert
Do
Locate 1 , 1
Lcd Time$ 'Zeige Zeit in Zeile1
Locate 2 , 1
Lcd _day ; "/" ; _month ; "/0" ; _year 'Zeige Datum in Form DD/MM/YYin Zeile2
'lcd Date$ 'zeige Datum in Form MM/DD/YY
If Pind.0 = 0 Then Gosub Time 'wiederhole Anzeige bis Taster 1 zum Stellen gedrückt, springe nach Sub "Time"
Loop
End
'Stunde
Time:
Waitms 200
Cls 'lösche Zeilen
Do
Locate 1 , 1
Lcd "Set Hour:" 'Stunden setzen
Locate 2 , 1
Lcd _hour
If Pind.3 = 0 Then 'Mit Taster 2
Incr _hour 'hochzählen
Locate 2 , 1
Lcd _hour
End If
If _hour > 23 Then 'Zählt bis Max, danach wieder ab 0
Cls
_hour = 00
End If 'solange, bis Taster 1 gedrückt
Loop Until Pind.0 = 0
Waitms 200
'Minute
Cls
Do
Locate 1 , 1
Lcd "Set Minute:"
Locate 2 , 1
Lcd _min
If Pind.3 = 0 Then
Incr _min
Locate 2 , 1
Lcd _min
End If
If _min > 59 Then
Cls
_min = 00
End If
Loop Until Pind.0 = 0
Waitms 200
Cls
'Tag
Cls
Do
Locate 1 , 1
Lcd "Set Day :"
Locate 2 , 1
Lcd _day
If Pind.3 = 0 Then
Incr _day
Locate 2 , 1
Lcd _day
End If
If _day > 31 Then
Cls
_day = 01
End If
Loop Until Pind.0 = 0
Waitms 200
Cls
'Monat
Cls
Do
Locate 1 , 1
Lcd "Set Month :"
Locate 2 , 1
Lcd _month
If Pind.3 = 0 Then
Incr _month
Locate 2 , 1
Lcd _month
End If
If _month > 12 Then
Cls
_month = 01
End If
Loop Until Pind.0 = 0
Waitms 200
Cls
'Jahr
Cls
Do
Locate 1 , 1
Lcd "Set Year :"
Locate 2 , 1
Lcd _year
If Pind.3 = 0 Then
Incr _year
Locate 2 , 1
Lcd _year
End If
If _year > 10 Then
Cls
_year = 00
End If
Loop Until Pind.0 = 0
Waitms 200
Cls
_sec = 00 'Springe Nach Setzen Von Zeit / Datum Wieder Zurueck
Return
'(################################################ #############################
Display Mit M50530 Aus Einem Siemenstelefon Optiset Memory E
Samsung 2138a Mit M50530 Controller / Ansteuerung Mit Attiny2313 Und Bascomdemo
Version 1.11.8.3
Die 2 Leds Sind Nur Zur Funktionskontrolle Während Der Erschaffung
dieses Quick-und-Dirty-Codes nötig und können entfallen.
Lcd - > Description
----------------------------------------
Pin 01 - > Ground - > Gnd
Pin 02 - > Data0 - > Portb.0
Pin 03 - > Data1 - > Portb.1
Pin 04 - > Data2 - > Portb.2
Pin 05 - > Data3 - > Portb.3
Pin 06 - > Data4 - > Portb.4
Pin 07 - > Data5 - > Portb.5
Pin 08 - > Data6 - > Portb.6
Pin 09 - > Data7 - > Portb.7
Pin 10 - > Ex - > Portd.3
Pin 11 - > R / W - > Portd.4
Pin 12 - > Oc2 - > Portd.5
Pin 13 - > Oc1 - > Portd.6
Pin 14 - > 8 , 2 Volt - > 8 , 2 Volt Poti Von 5..12v
Pin 15 - > 5 Volt - > 5 Volt
Pin 16 - > Ground - > Gnd
Ziel Ist Es , Das Lcd Per Rs232 / V24 Ansteuern Zu Können.
Das Display Soll Werte Einer Heizung(temp , Status Und Uhrzeit) Ausgeben.
Dazu Brauche Ich Funktionen Für Die Ausgabe Von Zeichenketten ,
Cursor Setzen(locate) Und Bildschirm Löschen(cls).
Jede Ausgabe Per V24 An Das Lcd Sieht Folgendermassen Aus:
@zssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcrlf
@ Ist Das Kennungszeichen Und Muß Am Anfang Stehen
Z Ist Die Zeile Von 1..8 , Z = 0 Macht Cls
Ss Ist Die Spalte(2stellig) Von 0..23
Xxx..xxx Ist Der Auszugebende String
Cr Muß Folgen
Lf Kann Folgen
################################################## #############################
')
$regfile = "2313def.dat" ' IC-Typ
Const Quarz = 8000000 ' Quarz..
$crystal = Quarz ' ..festlegen
$baud = 19200 ' Baudrate V24
$hwstack = 32 ' Hardwarestack
$swstack = 24 ' Softwarestack
$framesize = 24 ' Framsize
'################################ INIT Timer0 #################################
Const Pre = 8 ' ergibt alle x ms einen Interrupt
Config Timer0 = Timer , Prescale = Pre
On Ovf0 Tim0_isr ' Define the ISR handler
Enable Timer0
Const Reload = Int(quarz /((256 * Pre) * 100)) ' für 10 ms
'################################ INIT UART0 ##################################
On Urxc Ser_inp ' Interrupt-Routine setzen
Enable Urxc ' Interrupt URXC einschalten
'################################ INIT Watchdog ###############################
Config Watchdog = 2048 ' 2 Sekunden Watchdog
Const Sreload = 100 ' Sollwert für 1 Sekunde
Const Cdispinit = &B1111_1010 ' Display-SF
Const Lmax = 28 ' Max Buffer-Länge
'----------------------------- Display ----------------------------------------
Lcddata Alias Portb ' Portb 0-7 ist Data0-7 am Display (Pin 2-9)
' also 8-Bit-Modus
Ex Alias Portd.3 ' EX
Rw Alias Portd.4 ' R/W
Oc2 Alias Portd.5 ' OC2
Oc1 Alias Portd.6 ' OC1
Ddrd = &B111_1110 ' PortD Ausgang außer RxD
Ddrb = &B1111_1111 ' PortB Ausgang
Portd = &B000_0001 ' PortD alles auf 0 und RxD PullUp ein
Portb = &B0000_0000 ' PortB alles auf 0
Led_takt Alias Portd.2 ' 2s Takt
Led_v24 Alias Portd.1 ' V24-Bus-Kommunikation
Dim I As Byte ' Zählvariable
Dim L As Byte ' Zählvariable
Dim C As Byte ' ASCII-Wert des aktuellen Zeichens zum LCD
Dim Ch As String * 2 ' Str-Wert des aktuellen Zeichens zum LCD
Dim Led As Bit ' Merk-Bit für Takt-LED
Dim S As Byte ' Spalte für Locate
Dim Z As Byte ' Zeile für Locate
Dim Ioc As Byte ' Display-Modus
Dim D As Byte ' Datenbyte zum LCD
Dim T As Byte ' Temp-Variable in UP "Waitdisprdy"
Dim Now As Byte ' Zählvariable in UP "Waitdisprdy"
Dim Mscounter As Word ' 10ms-Counter
Dim Scounter As Byte ' 1s-Counter
Dim Buffer As String * 30 ' V24-Buffer
'================================================= =======================
Startup:
Enable Interrupts ' Freigabe der Interrups allgemein.
Wait 1 ' kleiner Vorsprung für LCD nach PowerON
Start Watchdog ' Watchdog starten
Gosub Lcd_init ' Init
Gosub Lcd_cls ' CLS
Gosub Lcd_home ' Home (eigentlich sinnlos, weil vorher CLS)
' ##################### Hauptprogramm ######################
Beginn:
Do
Nop ' sieht gut aus... ;-)
nop
nop
nop
nop
nop
nop
nop
nop
nop
Loop
' ##################### Ende Hauptprogramm #################
End 'End program
'************************************************* ***************************
Ser_inp:
'************************************************* ***************************
C = Udr ' Byte aus der UART auslesen
Led_v24 = 1 ' V24-LED an
If C > 31 And L < Lmax Then ' Grenzen für V24-String überwachen
Incr L
Buffer = Buffer + Chr(c) ' Buffer füllen
Else
If C = 13 Then ' <Enter> und damit String komplett
Disable Urxc ' V24 aus
Gosub Handle_buffer ' Buffer abarbeiten
Buffer = "" ' Buffer leeren
L = 0 ' Länge = 0
Enable Urxc ' V24 ein
End If
End If
Return
'************************************************* ***************************
Handle_buffer:
'************************************************* ***************************
If Mid(buffer , 1 , 1) = "@" And L > 3 Then ' erstes Zeichen ein @ ???
Ch = Mid(buffer , 2 , 1) ' Zeile holen...
Z = Val(ch) ' ... und in Zahl wandeln
Ch = Mid(buffer , 3 , 2) ' Spalte holen...
S = Val(ch) ' ... und in Zahl wandeln
If Z = 0 Then ' Zeile = 0... ?
Gosub Lcd_cls ' ...dann CLS
Else
Gosub Lcd_locate ' sonst Cursor setzen...
For I = 5 To L ' ... und ab da den String auf dem LCD ausgeben
Ch = Mid(buffer , I , 1) ' Zeichen holen...
C = Asc(ch) ' ...und als ASC and LCD_print übergeben
D = I + S ' Zeilenende auf LCD beachten
If D < 24 Then Gosub Lcd_print ' und Ausgeben...
Next I
End If
End If
Return
'************************************************* ***************************
Tim0_isr: ' Timer0-ISR
'************************************************* ***************************
If Mscounter < 1 Then ' Per Zählvariable eine 10ms-Funktion machen
Mscounter = Reload ' Reloadwert für 10ms
Gosub 10ms ' Funktion 10ms
Else
Mscounter = Mscounter - 1
End If
Return
'************************************************* ***************************
10ms: ' 10Milli-Sekunden-Interrupt
'************************************************* ***************************
Reset Watchdog
If Scounter < 1 Then ' Per Zählvariable eine 1s-Funktion machen
Scounter = Sreload ' Reloadwert für 1s
Gosub 1s ' Funktion 1s
Else
Scounter = Scounter - 1
End If
Return
'************************************************* ***************************
1s: ' Sekunden-Interrupt
'************************************************* ***************************
Led = Led Xor 1 ' Merk-Bit toggeln
Led_takt = Led ' Takt-LED blinken lassen
Led_v24 = 0 ' ggf. V24-LED aus
Return
'************************************************* ***************************
Lcd_cls: ' LCD löschen
'************************************************* ***************************
D = 1 : Ioc = 0
Gosub Writedata ' Clear Display, Cursor Home (CH)
Return
'************************************************* ***************************
Lcd_home: ' Cursor auf 0,0
'************************************************* ***************************
D = 0 : Ioc = 3
Gosub Writedata
Return
'************************************************* ***************************
Lcd_locate: ' Z=1..8 und S=0..23
'************************************************* ***************************
If Z < 9 And Z > 0 Then ' Z=1..8 ?
Select Case Z ' Zeilenadresse setzen
Case 1 : D = 0
Case 2 : D = 48
Case 3 : D = 96
Case 4 : D = 144
Case 5 : D = 24
Case 6 : D = 72
Case 7 : D = 120
Case 8 : D = 168
End Select
D = D + S ' Spalte zur Zeilenadresse addieren
Ioc = 3 ' Modus 3 (OC1 und OC2 = 1)
If S < 24 Then Gosub Writedata ' wenn S=0..23, dann Cursor setzen
End If
Return
'************************************************* ***************************
Lcd_print: ' Zeichen regulär drucken
'************************************************* ***************************
D = C : Ioc = 2
Gosub Writedata
Return
'================================================= ===========================
Writedatadirect: ' ein Byte zum Display ohne Busy-Abfrage
'================================================= ===========================
Portb = D ' Sequenz aus diversen AVR-ASM-Sourcen
Reset Rw ' pollin.de und LCD4Linux (mlcd) abgeguckt...
Reset Ex ' muss nicht alles korrekt sein, geht aber
Oc1 = Ioc.0
Oc2 = Ioc.1
Portb = D
Waitms 1
Set Ex
Waitms 1
Reset Ex
Return
'================================================= ===========================
Writedata: ' ein Byte zum Display mit Busy-Abfrage
'================================================= ===========================
Gosub Waitdisprdy
Gosub Writedatadirect
Return
'================================================= ===========================
Waitdisprdy:
'================================================= ===========================
Now = 0 ' TimeOUT vorbereiten
Do
Set Rw : Reset Oc1 : Reset Oc2 : Reset Ex ' R/W auf Lesen
Waitms 1
Set Ex ' Enable-Impuls
Config Portb = Input ' PortD nun Eingang
nop ' kurz warten
T = Pinb And &B1000_0000 ' einlesen und Bit7 maskieren
Incr Now ' TimeOUT-Counter hochzählen
Reset Ex ' Enable=L
Loop Until T = 0 Or Now > 64 ' Busy-Bit=0 oder TimeOUT zugeschlagen
Config Portb = Output ' PortD wieder Ausgang
Portb = 0 ' alle Pins wieder auf L
Reset Rw ' R/W wieder auf Schreiben
Return
'================================================= ===========================
Lcd_init:
'================================================= ===========================
D = Cdispinit : Ioc = 0 ' Init-Sequenz aus pollin.de-Pascal-Source
Gosub Writedatadirect ' übernommen und geht scheinbar
Waitms 5
D = Cdispinit : Ioc = 0
Gosub Writedatadirect
Waitms 5
D = Cdispinit : Ioc = 0
Gosub Writedatadirect
D = Cdispinit : Ioc = 0 ' nun weiter mit Busy-Abfrage
Gosub Writedata
Waitms 15
D = Cdispinit : Ioc = 0
Gosub Writedata
Waitms 15
D = &H50 : Ioc = 0
Gosub Writedata ' SE Set Entrymode: Cursor increment bei R+W, DispStart konstant
Waitms 15
D = &B00111100 : Ioc = 0
Gosub Writedata
Waitms 15
D = 1 : Ioc = 0
Gosub Writedata ' Clear Display, Cursor Home (CH)
Waitms 15
D = 0 : Ioc = 1
Gosub Writedata ' DisplayStart an Adresse 0
Waitms 15
D = &B00001101 : Ioc = 0
Gosub Writedata ' Underlin off (SU)
Waitms 15
D = &B00110100 : Ioc = 0
Gosub Writedata ' Cursor off
Waitms 15
Return
'================================================= ===========================