Code:
'RS232 LCD mit MEGA8
'INFO:
'Taster up=PB1 / right=PB0 / down=PD7 / left=PD6 / Menue=PD5
'v0.1 Funktion ok
'v0.2
'-PWM Beleuchtung
'-Baudrate einstellbar
'-CR muss gesendet werden
'-LF wird ignoriert
'v0.3
'-Zeilen Display und Auswahlmenü dafür
'v0.4
'-Zeilendisplay optimierung
'-------------------------------------------------------------------------------
'Konfiguration µC:
$regfile = "m8def.dat" 'MEGA8-Deklarationen
$hwstack = 32
$swstack = 8
$framesize = 24
'$crystal = 14745600 'Quarz: 14,7456 MHz
$crystal = 8000000
$baud = 9600 'Baudrate definieren
'-------------------------------------------------------------------------------
'Ein / Ausgänge definieren:
Ddrb = &B11111100 '0=Eingang
Ddrc = &B1111111
Ddrd = &B00011111 '0=Eingang
'PullUps setzen:
Portb = &B00000011 '1 = PullUp AKTIV
Portc = &B0000000 '1 = PullUp AKTIV
Portd = &B11100000 '1 = PullUp AKTIV
'-------------------------------------------------------------------------------
'LCD konfiguration
Config Lcd = 20 * 4 'LCD größe
Config Lcdpin = Pin , Rs = Portc.5 , E = Portc.4 , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0
Cursor Off Noblink
'-------------------------------------------------------------------------------
'PWM Timer konfigurieren
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 64
'-------------------------------------------------------------------------------
'Alias
Taster_up Alias Pinb.1
Taster_right Alias Pinb.0
Taster_down Alias Pind.7
Taster_left Alias Pind.6
Taster_menue Alias Pind.5
'Bel Alias Portb.2 'Displaybeleuchung
'-------------------------------------------------------------------------------
'Variablen
Dim Text As String * 80
Dim Text_z1 As String * 20
Dim Text_z2 As String * 20
Dim Text_z3 As String * 20
Dim Text_z4 As String * 20
Dim Text_z5 As String * 20
Dim Text_z As Byte 'merker in welcher Zeile geschrieben wird
Dim E_byte As Byte , E_flag As Byte
Dim Bel As Word 'LCD Beleuchtung PWM
Dim Baudrate As Word 'Baudrate ändern
Dim Baudtest As Word 'Baudrate aus Register lesen
Dim Entprellen As Word
Dim Z_lcd As Bit 'Zeilendisplay 0= normal text mit max 80 Zeichen
'-------------------------------------------------------------------------------
'Timer
'Timer1 = 2x / sec bei 8MHz
'Config Timer1 = Timer , Prescale = 256 'Teiler
'Const Timervorgabe = 49910
'Enable Timer1
'Enable Interrupts
'-------------------------------------------------------------------------------
'diverse
Config Debounce = 30 'Tastenentprellung = 30ms
'-------------------------------------------------------------------------------
Cls
Locate 1 , 5
Lcd "RS232 - LCD"
Locate 2 , 1
Lcd "T. Blome - 10/2009"
Print "RS232 LCD Tobias Blome"
Wait 1
'-------------------------------------------------------------------------------
'Für RS232:
On Urxc Onrxd 'Interrupt-Routine setzen
Enable Urxc 'Interrupt URXC einschalten
Enable Interrupts 'Interrupts global zulassen
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'Werte setzen
Entprellen = 300 'entprellzeit
Baudrate = 9600
Bel = 0 'Beleuchtung aus
Compare1b = Bel
Text_z = 1 'damit in der 1.ten Zeile angefangen wird
Z_lcd = 1 '0 = normale Ausgabe / 1 = Zeilenausgabe
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
Main:
Waitms Entprellen
Cls
Lcd "Warte auf Empfang..." 'Hauptschleife
Do
'Tasterabfrage
Debounce Taster_up , 0 , Taste_up , Sub 'Taster 1 entprellen; wenn gerdückt(0), zur Unterroutine "Taste1" springen
Debounce Taster_right , 0 , Taste_right , Sub
Debounce Taster_down , 0 , Taste_down , Sub
Debounce Taster_left , 0 , Taste_left , Sub
Debounce Taster_menue , 0 , Taste_menue , Sub
'If Taster_up = 0 Then Print "Hallo test"
'RS232 - Empfang umwandeln
If E_flag = 1 Then 'Empfangsstring komplett
If Z_lcd = 0 Then 'also normale Ausgabe
Print Text
Cls
Locate 1 , 1
Lcd Mid(text , 1 , 20)
Locate 2 , 1
Lcd Mid(text , 21 , 20)
Locate 3 , 1
Lcd Mid(text , 41 , 20)
Locate 4 , 1
Lcd Mid(text , 61 , 20)
Text = "" 'Inhalt löschen
Else 'wenn Zeilenausgabe
If Text_z = 1 Then Text_z1 = Text
If Text_z = 2 Then Text_z2 = Text
If Text_z = 3 Then Text_z3 = Text
If Text_z = 4 Then Text_z4 = Text
If Text_z = 5 Then Text_z5 = Text
Text = "" 'Inhalt löschen
If Text_z < 5 Then 'hier muss noch die Bedingung rein, dass nur wenn die ersten 3 Zeilen belegt sind, die 1te Zeile gelöscht wird!!!!
Incr Text_z 'hochzählen bis 5
Cls
Locate 1 , 1
Lcd Text_z1
Locate 2 , 1
Lcd Text_z2
Locate 3 , 1
Lcd Text_z3
Locate 4 , 1
Lcd Text_z4
Else
Text_z1 = Text_z2 'Text verschieben
Text_z2 = Text_z3
Text_z3 = Text_z4
Text_z4 = Text_z5
Text_z5 = "" 'muss leer gemacht werden
Cls
Locate 1 , 1
Lcd Text_z1
Locate 2 , 1
Lcd Text_z2
Locate 3 , 1
Lcd Text_z3
Locate 4 , 1
Lcd Text_z4
Print Text_z1 ; " " ; Text_z2 ; " " ; Text_z3 ; " " ; Text_z4
End If
End If
E_flag = 0 'Empfang neu setzen
End If
Loop
'-------------------------------------------------------------------------------
Taste_up:
Lcd "up"
Print "up"
Return
Taste_right:
Lcd "right"
Print "right"
Return
Taste_down:
Lcd "down"
Print "down"
Return
Taste_left:
Lcd "left"
Print "left"
Return
'-------------------------------------------------------------------------------
'Taste_Menue:
Do
If Taster_right = 0 Then
Bel = Bel + 100
If Bel > 1000 Then Bel = 1000 'eigendlich 1023 aber bist 1000 sind genau 10 Stufen ;-)
Compare1b = Bel
Taste_menue: 'hier in das Menue springen, damit sofort auch der aktuelle Wert mit Regler im LCD angezeigt wird
Cls
Lcd "Beleuchtung: " ; Bel
Locate 3 , 1
Select Case Bel
Case 000 : Lcd " (-) +---------- (+) "
Case 100 : Lcd " (-) -+--------- (+) "
Case 200 : Lcd " (-) --+-------- (+) "
Case 300 : Lcd " (-) ---+------- (+) "
Case 400 : Lcd " (-) ----+------ (+) "
Case 500 : Lcd " (-) -----+----- (+) "
Case 600 : Lcd " (-) ------+---- (+) "
Case 700 : Lcd " (-) -------+--- (+) "
Case 800 : Lcd " (-) --------+-- (+) "
Case 900 : Lcd " (-) ---------+- (+) "
Case 1000 : Lcd " (-) ----------+ (+) "
End Select
End If
If Taster_left = 0 Then
Bel = Bel - 100
If Bel > 1023 Then Bel = 0 'funktioniert, weil 0 - ist gleich 65000 sowieso...
Compare1b = Bel
Cls
Lcd "Beleuchtung: " ; Bel
Locate 3 , 1
Select Case Bel
Case 000 : Lcd " (-) +---------- (+) "
Case 100 : Lcd " (-) -+--------- (+) "
Case 200 : Lcd " (-) --+-------- (+) "
Case 300 : Lcd " (-) ---+------- (+) "
Case 400 : Lcd " (-) ----+------ (+) "
Case 500 : Lcd " (-) -----+----- (+) "
Case 600 : Lcd " (-) ------+---- (+) "
Case 700 : Lcd " (-) -------+--- (+) "
Case 800 : Lcd " (-) --------+-- (+) "
Case 900 : Lcd " (-) ---------+- (+) "
Case 1000 : Lcd " (-) ----------+ (+) "
End Select
End If
Waitms Entprellen
If Taster_down = 0 Then
Goto Baudrate
End If
If Taster_menue = 0 Then
Goto Main
End If
Loop
Return
'-------------------------------------------------------------------------------
Baudrate: 'berechnen: 8.000.000 MHz/(16*(51+1)) = 9615,3...(~ 9600Baud) 51 gleich von Baudtest = Ubrrl
Cls
Lcd "Baudrate: " ; Baudrate
Baudtest = Makeint(ubrrl , Ubrrh )
Locate 2 , 1
Lcd "Baud: " ; Baudtest 'Ubrrh
Do
Debounce Taster_right , 0 , Baudrate_add , Sub
Debounce Taster_left , 0 , Baudrate_sub , Sub
Waitms Entprellen
If Taster_up = 0 Then
Goto Taste_menue
End If
If Taster_down = 0 Then
Goto Anzeigeart
End If
If Taster_menue = 0 Then
Goto Main
End If
Loop
Return
'=========
Baudrate_add:
Incr Baudrate
Select Case Baudrate
Case 1 To 1200 : Baud = 1200
Baudrate = 1200
Case 1201 To 2400 : Baud = 2400
Baudrate = 2400
Case 2401 To 4800 : Baud = 4800
Baudrate = 4800
Case 4801 To 9600 : Baud = 9600
Baudrate = 9600
Case 9601 To 14400 : Baud = 14400
Baudrate = 14400
Case 14401 To 19209 : Baud = 19200 '19209 damit nicht versehentlich ein größerer Wert gewählt wird
Baudrate = 19200
End Select
Cls
Lcd "Baudrate: " ; Baudrate
Baudtest = Makeint(ubrrl , Ubrrh )
Locate 2 , 1
Lcd "Baud: " ; Baudtest 'Ubrrh
Return
'=========
Baudrate_sub:
Decr Baudrate
Select Case Baudrate
Case 1 To 2399 : Baud = 1200
Baudrate = 1200
Case 1201 To 4799 : Baud = 2400
Baudrate = 2400
Case 2401 To 9599 : Baud = 4800
Baudrate = 4800
Case 4801 To 14399 : Baud = 9600
Baudrate = 9600
Case 9601 To 19199 : Baud = 14400
Baudrate = 14400
Case 14401 To 28799 : Baud = 19200
Baudrate = 19200
End Select
Cls
Lcd "Baudrate: " ; Baudrate
Baudtest = Makeint(ubrrl , Ubrrh )
Locate 2 , 1
Lcd "Baud: " ; Baudtest 'Ubrrh
Return
'-------------------------------------------------------------------------------
Anzeigeart:
Cls
Lcd "Anzeigeart: " ; Z_lcd
Do
Waitms Entprellen
If Taster_right = 0 Then
Set Z_lcd
Cls
Lcd "Anzeigeart: " ; Z_lcd
Locate 2 , 1
Lcd "in Zeilen scrollen"
Locate 3 , 1
Lcd "4Zeilen je 20Zeichen"
Text_z1 = "" 'Text löschen
Text_z2 = ""
Text_z3 = ""
Text_z4 = ""
Text_z5 = ""
Text = ""
End If
If Taster_left = 0 Then
Reset Z_lcd
Cls
Lcd "Anzeigeart: " ; Z_lcd
Locate 2 , 1
Lcd "nach jedem Empfang"
Locate 3 , 1
lcd "wird LCD geloescht"
End If
If Taster_up = 0 Then
Goto Baudrate
End If
If Taster_down = 0 Then
Goto Main
End If
If Taster_menue = 0 Then
Goto Main
End If
Loop
Return
'-------------------------------------------------------------------------------
Onrxd:
E_byte = Udr
If E_byte = 13 Then '13 = CR (Enter)
E_flag = 1 '1=Ausgabe auf LCD
Elseif E_byte = 10 Then '10 LF (Linie Feed)
'tu nix - damit das Zeichen nicht auf dem LCD erscheint
Else
Text = Text + Chr(e_byte)
End If
Return
'===============================================================================
'Pinbelegung µC
'===============================================================================
' AT MEGA 8
' +---U---+
' Reset PC6 +1 28+ PC5
' RXD -> PD0 +2 27+ PC4
' <- TXD PD1 +3 26+ PC3
' PD2 +4 25+ PC2
' PD3 +5 24+ PC1
' PD4 +6 23+ PC0
' Vcc +7 22+ GND
' GND +8 21+ AREF
' XTAL1 PB6 +9 20+ AVCC
' XTAL2 PB7 +10 19+ PB5 /PROG - SCK
' PD5 +11 18+ PB4 /PROG - MISO
' PD6 +12 17+ PB3 /PROG - MOSI
' PD7 +13 16+ PB2
' PB0 + 14 15 + Pb1
' +-------+
'PB0 = Taster RIGHT
'PB1 = Taster UP
'PB2 =
'PB3 =
'PB4 =
'PB5 =
'PB6 =
'PB7 =
'PC0 = LCD DB7
'PC1 = LCD DB6
'PC2 = LCD DB5
'PC3 = LCD DB4
'PC4 = LCD E
'PC5 = LCD RS
'PC6 = RESET
'PC7 =
'PD0 = RXD Empfangen MAX 232
'PD1 = TXD Senden MAX 232
'PD2 =
'PD3 =
'PD4 =
'PD5 = Taster MENUE
'PD6 = Taster LEFT
'PD7 = Taster DOWN
'===============================================================================
'Pinbelegung AM LCD!!!!!!! ACHTUNG!!!!!
'===============================================================================
'Pin 1: GND
'Pin 2: +5V
'Pin 3: Kontrast (0-5V)
'Pin 4: RS -> AVR
'Pin 5: R/W -> GND (read/write mode, nur writen)
'Pin 6: E -> AVR
'Pin 7-10: -> GND
'Pin 11-14: -> AVR -> 11=DB4 / 12=DB5 / 13=DB6 / 14=DB7
'Pin 15-16: Beleuchtung
Lesezeichen