Code:
'RS232 LCD mit MEGA8
'INFO:
'beim ersten programmieren: Einstellung: eeprom nicht jedesmal beim prog. löschen
' "Lieblingswerte" im Programm ändern sonst alles auf 65535 und minus dauert lange!!!
'Taster up=PB1 / right=PB0 / down=PD7 / left=PD6 / ok-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
'v0.5
'-letzte Einstellung im EEProm speichern
'-EEProm Inhalt wird im Menü angezeigt
'-Menü öffnen wenn ok lange gedrückt
'-Beleuchtung nur 5 Stufen
'-Menüreihenfolge geändert
'-EEProm Werte können gelesen werden ohne zu speichern
'-------------------------------------------------------------------------------
'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_ok 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 'für seriellen Empfang
Dim Bel As Word 'LCD Beleuchtung PWM
Dim Eebel As Eram Word 'eeprom speicher für PWM Beleuchung
Dim Baudrate As Word 'Baudrate ändern
Dim Eebaudrate As Eram Word 'eeprom speicher für Baudrate
'Dim Baudtest As Word 'Baudrate aus Register lesen
Dim Entprellen As Word
Dim Z_lcd As Byte 'Zeilendisplay 0= normal text mit max 80 Zeichen
Dim Eez_lcd As Eram Byte 'eeprom speicher LCD art
Dim Menue_merker As Word 'Taster lange drücken = Menü
'-------------------------------------------------------------------------------
'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 / aus EEProm lesen
Baudrate = Eebaudrate '9600
Z_lcd = Eez_lcd '0 = normale Ausgabe / 1 = Zeilenausgabe
Bel = Eebel '0 = Beleuchtung aus
Compare1b = Bel
Text_z = 1 'damit in der 1.ten Zeile angefangen wird
Entprellen = 300 'Entprellzeit
'Baudrate übernehmen
Select Case Baudrate
Case 1200 : Baud = 1200
Case 2400 : Baud = 2400
Case 4800 : Baud = 4800
Case 9600 : Baud = 9600
Case 14400 : Baud = 14400
Case 19209 : Baud = 19200
Case 65535 : Baud = 9600 'wenn nix im eeprom / Variable steht
Baudrate = 9600 'wenn nix im eeprom / Variable steht
End Select
'---------------------------------------------------------------------------------------------------------------
'---------------------------------------------------------------------------------------------------------------
Main:
'Werte ins EEProm schreiben
Eebaudrate = Baudrate '9600
Eez_lcd = Z_lcd '0 = normale Ausgabe / 1 = Zeilenausgabe
Eebel = Bel '0 = Beleuchtung aus
Main2: 'ohne speichern im EEProm
Waitms Entprellen
Cls
Lcd "Warte auf Empfang..." 'Hauptschleife
Do
'========================================
'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
'========================================
'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_ok , 0 , Taste_ok , Sub
'Tastendruck "MENÜ" auswerten, Taster lange gedrückt halten:
If Taster_ok = 1 Then
Menue_merker = 0 'Wert zurücksetzen
Else
Incr Menue_merker 'Merker hochzählen
End If
If Menue_merker = 5000 Then
Lcd "ok"
Print "ok"
End If
If Menue_merker > 65000 Then Goto Eeprom
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
'-------------------------------------------------------------------------------
Eeprom:
Cls
Lcd "EEPROM Inhalt: (1)"
Waitms 500 'damit nicht sofort wieder aus dem Menü gesprungen wird...
Do
Baudrate = Eebaudrate '9600
Z_lcd = Eez_lcd '0 = normale Ausgabe / 1 = Zeilenausgabe
Bel = Eebel '0 = Beleuchtung aus
'Werte aus EEProm anzeigen
Locate 2 , 1
Lcd "Baudrate: " ; Baudrate
Locate 3 , 1
Lcd "Anzeigeart: " ; Z_lcd ; " 0=norm" '0 = normale Ausgabe / 1 = Zeilenausgabe
Locate 4 , 1
Lcd "BelPWM: " ; Bel '0 = Beleuchtung aus
'If Taster_up = 0 Then
'Goto Anzeigeart
'End If
If Taster_down = 0 Then
Goto Baudrate
End If
If Taster_ok = 0 Then
Goto Main2 'ohne speichern im EEProm
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
Locate 1 , 18
Lcd "(2)"
'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
'rausgenommen weil man vom EEProm menü ohne speichern zurück kommt
'If Taster_up = 0 Then
'Goto Eeprom
'End If
If Taster_down = 0 Then
Goto Anzeigeart
End If
If Taster_ok = 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
Locate 1 , 18
Lcd "(2)"
'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
Locate 1 , 18
Lcd "(2)"
'Baudtest = Makeint(ubrrl , Ubrrh )
'Locate 2 , 1
'Lcd "Baud: " ; Baudtest 'Ubrrh
Return
'-------------------------------------------------------------------------------
Anzeigeart:
Cls
Lcd "Anzeigeart: " ; Z_lcd
Locate 1 , 18
Lcd "(3)"
Select Case Z_lcd
Case 0 :
Locate 2 , 1
Lcd "nach jedem Empfang"
Locate 3 , 1
Lcd "wird LCD geloescht"
Case 1 :
Locate 2 , 1
Lcd "in Zeilen scrollen"
Locate 3 , 1
Lcd "4Zeilen je 20Zeichen"
End Select
Do
Waitms Entprellen
If Taster_right = 0 Then
Z_lcd = 1
Cls
Lcd "Anzeigeart: " ; Z_lcd
Locate 1 , 18
Lcd "(3)"
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
Z_lcd = 0
Cls
Lcd "Anzeigeart: " ; Z_lcd
Locate 1 , 18
Lcd "(3)"
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 Beleuchtung
End If
If Taster_ok = 0 Then
Goto Main
End If
Loop
Return
'-------------------------------------------------------------------------------
'Beleuchtung:
Do
If Taster_right = 0 Then
Bel = Bel + 200
If Bel > 1000 Then Bel = 1000 'eigendlich 1023 aber bist 1000 sind genau 10 Stufen ;-)
Compare1b = Bel
Beleuchtung: 'hier in das Menue springen, damit sofort auch der aktuelle Wert mit Regler im LCD angezeigt wird
Cls
Lcd "Beleuchtung: " ; Bel
Locate 1 , 18
Lcd "(4)"
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 - 200
If Bel > 1023 Then Bel = 0 'funktioniert, weil 0 - ist gleich 65000 sowieso...
Compare1b = Bel
Cls
Lcd "Beleuchtung: " ; Bel
Locate 1 , 18
Lcd "(4)"
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_up = 0 Then
Goto Anzeigeart
End If
'If Taster_down = 0 Then
'Goto Baudrate
'End If
If Taster_ok = 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
Um viele Baudraten Ideal abdecken zu können, habe ich einen 14,7456 MHz Quarz verwendet - aber mit den 8MHz lief es auch schon.
Lesezeichen