PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Baudrate auslesen?



TobiasBlome
28.10.2009, 17:13
Hallo,
ich möchte im laufenden µC Programm die Baudrate einstellen können.
Wie kann man diese dann wieder auslesen?

Also:

Baud = 9600 ' legt die Baudrate fest

Variable = Baud ' macht bei mir einen Fehler

Variable = $Baud 'gibt IMMER 186 zurück!!!

vielen Dank,
Tobias

Richard
28.10.2009, 17:48
Moin moin.


Ich vermute die Badrate ist ein einem (Welchem (?)) Register
abgelegt. Das sollte sich auslesen lassen ein Blick ins Datenblatt
sollte auch das Register finden lassen. Das ist halt bei Bsic ein
Problem, Mensch verblödet. In ASS oder C muß man die Register
selber setzen und weiß deshalb wo die Baudrate zu finden ist.

Ich bin ach etwas verblödet und weiß es nicht....

Gruß Richard

TobiasBlome
28.10.2009, 17:53
Mensch verblödet.


tja - Register? äh wie ließt man denn ein Register aus? Ich habe einen MEGA8.

Meine Hofnung war ja, dass wenn man die Baudrate so einfach schreiben kann - dass das Auslesen ebenso einfach ist...

Tobias

PicNick
28.10.2009, 18:19
Die Baudrate wird eingestellt in den Registern
UCSRA Bit U2X
und
UBRRL
UBBRH

Wenn man diese Register überhaupt lesen kann (das ist garnicht gesagt, und ich hab's noch garnicht probiert) dann z.B -->

DIM baudwert as WORD

Baudwert = MAKEINT( UBRRL, UBBRH )

Richard
28.10.2009, 18:21
Moin moin.

Wie eine Variable halt ausgelesen wird. Dazu muß man
natürlich wissen wie das Regster sich nennt und das steht
auch im Datenblatt. :-) Ich habe alle Datenblätter bin aber
eifach zu Fauel die für Dich zu durchsuchen. Du willst etwas
wissen, dann mache etwas dafür. NUR was Du selber erarbeitest
bildet Dich auch, vorverdautes macht nicht eimal satt!

Gruß Richard

uwegw
28.10.2009, 18:27
Laut Datenblatt sind diese Register übrigens auslesbar. Und wie du von dem dort gespeicherten Wert wieder auf die tatsächliche Baudrate kommst, muss du nun selbst nachschauen...

TobiasBlome
28.10.2009, 21:39
Die Baudrate wird eingestellt in den Registern
UCSRA Bit U2X
und
UBRRL
UBBRH

...

Baudwert = MAKEINT( UBRRL, UBBRH )

Danke für die super ausfühliche Antwort!

in UBRRL Steht der Wert drin :-)
UBRRH (war ein Schreibfehler drin) ist bei mir immer 0

Morgen werde ich mal sehen, wie ich aus den Werten die richtigen Baudraten bekomme... 9600Baud=51 und 14400Baud=34

Auf jeden Fall vielen Dank!

Tobias

uwegw
28.10.2009, 21:50
Morgen werde ich mal sehen, wie ich aus den Werten die richtigen Baudraten bekomme... 9600Baud=51 und 14400Baud=34

Ok, dein AVR läuft also mit 8MHZ...

PicNick
29.10.2009, 08:43
Lt. Datenblatt geht das:
Bei U2X = 0
Baudrate = cpu / ( 16 * (Baudwert + 1))
Bei U2X = 1
Baudrate = cpu / ( 8 * (Baudwert + 1))

TobiasBlome
29.10.2009, 16:28
Hall Robert,
du bis ja superschnell :-)

aber ich habe trotzdem noch in das Datenblatt gesehen - will ja nicht faul sein =)

Die Abweichung ist wohl wegen der Fehlertoleranz, wenn die Quarzfrequenz nicht 100%ig zur Baudrate passt - oder?

9600 Baud eingestellt -> Angezeigt wird 51 d.h.

8MHz/(16*(51+1)) = 9615,3...(~ 9600Baud)
8MHz/(16*(34+1)) = 14285,7...(~14400Baud)

Aber ich will sowieso noch einen Quarz mit 14,7456 MHz einbauen und dann passt auch die Rechnung :-)

Im Datenblatt S.136 steht: Asynchronous Normal mode bzw. Asynchronous Double Speed - was ist damit gemeint?

Tobias

PicNick
29.10.2009, 18:01
Async normal mode --> UCSRA Bit. U2X = 0
Da wird der QuartzOszillator durch 16 dividiert
Async double --> UCSRA Bit. U2X = 1
Da wird der QuartzOszillator durch 8 dividiert

Mit dem, was da rauskommt, wird immer die Zahl in UBRR runtergezählt
bei Null ist dann ein Takt.
Funzt eigentlich genauso wie die anderen µC- Counter auch.

Einige Baudraten können nicht genau erwischt werden, die Abweichung findest du in der Tabelle beim Mega32 auf S. 163.
Welchen Mega verwendest du ?

D.h. beim Rückrechnen musst du da gewissermassen runden.

Was hast du denn in etwa vor, sowas wie "AutoBaud" ?

TobiasBlome
29.10.2009, 20:12
Also zu meinem Vorhaben:
Ich nutze zur Fehlersuche bei µC oder um Testwerte anzuzeigen gerne die RS232 Schnittstelle. Deshalb möchte ein LCD 4*20 mit 5 Tastern up, down, left, right und Menue programmieren, um "mal eben" ohne PC die "Daten auszulesen" - nichts wildes - aber für mich brauchbar ;-)

Damit ich da etwas variabel bin möchte ich unteranderem die Baudrate wählen können.

Über select Case wähle ich die Baudrate und möchte diese natürlich auch als Rückmeldung im Auswahlmenü anzeigen. Da Bascom anscheined weder Baud noch $Baud ausgeben kann lese ich dies nun über die Register aus.

Als letztes möchte ich noch auswählen können, ob der Text über alle Zeilen verteilt nacheinander ausgegeben wird oder ob jeweils die erste Zeile gelöscht wird und alle anderen aufrücken. So könnte ich 4 Variablen untereinander anzeigen (ich will ja keinen Roman auf dem LCD anzeigen :-) )

ich benutze einen MEGA8@8MHz intern

die Serielle Schnittstelle frage ich so ab:



Onrxd:

E_byte = Udr


If E_byte = 13 Then '13 = CR (Enter)
E_flag = 1
Elseif E_byte = 10 Then '10 LF (Linie Feed)
'tu nix
Else
Text = Text + Chr(e_byte)
End If

Return


und teile alles auf 4 Zeilen auf:


'RS232 - Empfang umwandeln
If E_flag = 1 Then 'Empfangsstring komplett
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
E_flag = 0 'Empfang neu setzen

End If


Gedankengang:
Wenn die Variable Text mehr als 60 Zeichen hat(also schon in die 4.te Zeile geschrieben wird), nach der Textausgabe die ersten 20 Zeichen in der Variable Text löschen - beim nächsten Empfang wird an der Stelle weitergeschrieben - so könnte der Text Zeilenweise hoch rutschen.

ABER wenn mein LCD so aussieht:

Variable1(CR)
Variable2(CR)
Variable3(CR)
Variable4(CR)

dann sind das keine 60 Zeichen und wenn nun die Variable5 auf das LCD gesendet werden soll muss ja Variable 1 gelöscht werden

ok - ich muss nochmal darüber nachdenken -
(sorry nun hab ich hier einen Roman geschrieben.... :-# )

Tobias

TobiasBlome
29.10.2009, 22:05
so - fertig \:D/
Empfang läuft. Sobald "CR" empfangen wurde wird der Text in die 1. Zeile geschoben und eine Variable (Text_z)eile hochgezählt. Wenn der Zähler in der 5ten Zeile angekommen ist, (die 5te Zeile gibt es ja gar nicht) wird der Inhalt von der 2ten Zeile in die 1te geschoben und von der 3ten in die 2te und 4te in 3te und 5te in 4te. 5te wird dann gelöscht. Damit rutscht alles nach oben. und es kann wieder empfangen werden.

Es gibt bestimmt noch "schönere und sparsamere" Möglichkeiten aber diese ist eine leicht nachvollziehbare und sie funktioniert.

Also wer zufällig auch ein LCD mit Tasten zum auslesen möchte kann meinen Code gerne nutzen.

Belegung ist im Code und Schaltplan ist nur noch ein Max232 dran...

Tobias



'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

PicNick
30.10.2009, 06:25
Aha, I see.

Also ich würde die Registerwerte für die auswählbaren Baudraten in einer Tabelle anlegen, daraus auswählen lassen und dann setzen.
Denn das Rückrechnen ist ein Sport (s.o) und soooo viele Baudraten gibt's ja auch wieder nicht. Ist ja kein fliessender Wert.

oberallgeier
30.10.2009, 09:13
... soooo viele Baudraten gibt's ja auch wieder nicht ...Über diese Tatsache war ich mal gestolpert, als ich eine Fehleranpassung durch einen optimialen UBRR-Wert suchte. Das würde schon funktionieren - aber leider nur mit Floatingpoint-Werten *ggg*. Dazu siehe z.B. diese Tabelle. (https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=438494&sid=07a51533ed3a9fc4229858bc044b971a#438494)

Gento
30.10.2009, 11:27
Statt Registerklimmzüge , ist es nicht sinniger sich die Baudrate in Dim Baudrate Long zu merken !

Gento

TobiasBlome
30.10.2009, 21:12
Also ich belass es (vorerst) so, das ich die aktuelle Baudrate in einer seperaten Variable ablege.


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


Ich denke das Programm ist bis auf weiteres fertig - wie gesagt bei Interesse:



'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. :-)

Tobias :mrgreen: