Strings empfangen klappt nicht

Ditron

Mitglied
11. Dez. 2011
281
6
18
Sprachen
  1. BascomAVR
Moin!

Ich versuche seit einiger Zeit Strings über die RS232 zu empfangen (Bascom). Leider klappt das nicht so wirklich. Einzelne Zeichen werden empfangen und auf dem LCD angezeigt, aber sobald ein String kommt, wird nur noch Müll angezeigt. Zum Senden von Strings nutze ich AVRTerm.

Hat jemand eine Idee?

Code:
$regfile = "m32def.dat"
$crystal = 1000000
$baud = 9600       'Baudrate der UART: 9600 Baud

$hwstack = 100
$swstack = 100
$framesize = 100

Config Portd = Output
Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Porta.3 , Rs = Porta.1
Config Lcd = 16 * 2
Cls
Cursor Off
Locate 1 , 1

Config Com1 = "9600" , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

' Die LEDs dienen nur zur Kontrolle
Led1 Alias Portb.0
   Config Led1 = Output
Led2 Alias Portb.1
   Config Led2 = Output
Led3 Alias Portb.2
   Config Led3 = Output

Dim B As Byte
Dim S As String * 10

On Urxc Onrxd
Enable Urxc
Enable Interrupts

Do
Set Led1
   ' Da ein 8-Zeichen-Display genutzt wird, wird der String S über 7 Zeichen gelöscht
   If Len(s) >= 8 Then
         S = ""
         Toggle Led3
   End If
Reset Led1
Loop

End

Onrxd:
   Cls
   Locate 1 , 1
   B = Inkey()
   B = B - 64
   S = S + Chr(b)
   Lcd S
   Print S
   Toggle Led2
Return
 
Hallo,

ich bin kein BASCOM-Programmierer aber mir scheint in der Onrxd: Subroutine etwas nicht zu stimmen.

Bei dem Inkey()-Befehl wird das erste Zeichen als ASCII-Wert in eine Variable übertragen.
Das bedeutet, dass beim Empfang des Zeichen´s "A" in der Variable B=65 steht.
Danach zählst Du 64 ab. ? -> Damit wird aus dem "A" ein [SOH]->1!
Danach wandelst Du mit dem Befehl CHR(b) diese 1 in ein ASCII-Zeichen. Was im String das Steuerzeichen [SOH] ergibt.
Ich weiß leider nicht was das Display mit diesen Steuerzeichen macht, aber sicher keine Ausgabe eines "A".

Lass einfach die Zeile mit B = B - 64 weg.

Tipp: Achte grundsätzlich beim Programmieren auf Groß- Kleinschreibung von Variablennamen,
da haben schon manche Stunden mit Fehlersuche verbracht.

LG
TrueNEO
 
Tipp: Achte grundsätzlich beim Programmieren auf Groß- Kleinschreibung von Variablennamen,
da haben schon manche Stunden mit Fehlersuche verbracht.
Bascom hat da so seine eigenen Ansichten was Groß- und Kleinschreibung betrifft. Leider.
Es wandelt die Buchstaben selber nach dem eintippen je nach Zusammenhang in große und kleine.
Bei der Interpretation der Namen wird es jedoch ignoriert.

Gruß
Dino
 
Danke für eure Antworten!

Das B = B - 64 stammt aus "Versuchen" mit einzelnen Zeichen, da muss ich die 64 abziehen um auf den richtigen Wert zu kommen. Dann werden mir auch die richtigen Zeichen auf dem Display angezeigt.
Ich befürchte mal, dass da ein grundsätzlicher Fehler drin ist. Leider bin ich noch nicht so fit der uC-Technik. Muss ich zB irgendwelche Fuse-Bits setzen?

Momentan läuft die Schaltung auf einem STK500 (falls diese Info relevant ist).
 
Hi,

Muss ich zB irgendwelche Fuse-Bits setzen?
mit den Fuse-Bits änderst du nur grundsätzliche "globale" Einstellungen. Zum Beispiel Systemtakt, bei welcher Spannung ein Reset ausgelöst werden soll, Programmierschnittstelle, Debug-Interface, Bootbereich, ...

Alle Einstellungen für die Timer, Counter, ADCs, UARTs, SPI, TWI, INT, ... werden in den Funktionsregistern durchgeführt und können während des Programmablaufs geändert werden.

Gruß
Dino
 
Danke für die Info.

Aber wo und wie kann ich nun den Fehler suchen? Gibts im Netz irgendwo ein funktionierendes Script? Dann könnte ich mal vergleichen und suchen, wo der Fehler ist...
 
Hallo Ditron,
du musst sicherlich die LCD und Print Befehle aus der ISR rausnehmen, sonst wird das nichts.
Die dauern so lange, dass in der Zwischenzeit einige Zeichen durchflutschen.
Lass die Ausgabe in der Do...Loop laufen.
Dazu musst du vielleicht noch feststellen, dass keine Zeichen mehr kommt und dann den String rausschicken.
 
Das Auslagern der LCD-Sachen brachte auch nix.

Ich befürchte mal, bei mir haut was mit der seriellen Kommunikation nicht hin.

Ich habe nun ein einfaches Print-Programm getestet:

Code:
$regfile = "m32def.dat"
$crystal = 1000000
$baud = 9600                                                'Baudrate der UART: 9600 Baud

$hwstack = 100
$swstack = 100
$framesize = 100

Config Portd = Output
Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Porta.3 , Rs = Porta.1
Config Lcd = 16 * 2
Cls
Cursor Off
Locate 1 , 1

Config Com1 = "9600" , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

Led1 Alias Portb.0
Config Led1 = Output

Print "Hallo"
Toggle Led1

End

und das zeigt mir das Bascom-Terminal als Antwort an: Èáììï
 
und das zeigt mir das Bascom-Terminal als Antwort an: Èáììï


Hallo Ditron!

Ich würde sagen.... da stimmt einfach nur die Baudrate im Terminalprogramm mit dem AVR nicht überein.
Code:
$baud = 9600                                                'Baudrate der UART: 9600 Baud
Hast du im Terminalprogramm auch ganz sicher 9600 eingestellt?


Grüße,
Cassio
 
Hi Ditron,

schau mal in den Projektbereich und suche nach der Zisternenanzeige von Markus. Da ist die Kommunikation zwischen zwei Atmels mit den UARTs gemacht. Da kannst du etwas abkupfern ;)

Gruß
Dino
 
@Cassio:
Ich bin nun nicht mehr an "dem" Rechner, bin aber ziemlich sicher, dass über 9600 eingetragen war... werde gleich morgen mal nachschauen.


@Dino:
Ich gehe gleich mal auf die Suche!
 
Hi
Wenn ich das richtig sehe, benutzt du den internen Quarz
$regfile = "m32def.dat"
$crystal = 1000000
$baud = 9600
Da ist es durchaus möglich, das dieser nicht sehr stabil läuft und du viele Fehlerhafte Bytes überträgst. Schraub doch mal versuchsweise due Baudrate runter. Ein weiterer Punkt ist ein Prescaler von 8. Irgendwo hab ich mal gelesen, das du dann´nicht 9200 Baud sondern nur 1200 Baud überträgst. wär auch mal ein Versuch, das Terminalprogramm dahingehend abzustimmen. Letzteres glaub ich zwar nicht so richtig, aber versuch's einfach mal.
Zuletzt fällt mir nur ein, das du in einer ISR empfangen solltest. Nun weiß ich nicht genau, wie schnell BASCOM ist und ob du den zuletzt empfangenen Wert auch verarbeitet hast. Da kenn ich mich mit BASCOM halt nicht aus. In Assembler lasse ich die Daten in einen Ringpuffer laufen, da hat das Programm alle Zeit der Welt, sich um die empfangenen Daten zu kümmern, ohne was zu übersehen.
Gruß oldmax
 
Guten Morgen!

Oldmax hat natürlich recht.....

Die Baudrate von 9600 passt nicht zum internen 1MHz!
Die Fehlerrate ist einfach zu groß!

Dirk hat doch HIER extra ein Programm bereit gestellt!
Damit kann man das ganz bequem ermitteln :wink:
9600_1MHz_Baudrate.gif

Die Fehlerrate sollte eigentlich nicht über 1% kommen..... und bei 9600 sind es 7%.


Grüße,
Cassio
 
Hallo zusammen,
Hmm...
laut Datenblatt mit UBRR=12 und gesetztem U2X-Flag sinds 0,2% bei 9600Baud
ja stimmt, ermittelt auch der USART Calculator. In der rechten Spalte sieht man die Werte bei U2X gesetzt. Der Fehler ist minimal kleiner als 0,2%, das reicht.

Gruß,
Dirk
 
Aber die Frage ist, ob Bascom das weiß... ansonsten Baudrate auf 4800 stellen (in Bascom) und dann selbst U2X in UCSRA setzen...
 
Aber die Frage ist, ob Bascom das weiß...

Hallo zusammen!

So sehe ich das auch! :wink:
Nur die Angaben von 1MHz Systemtakt und 9600baud im Programm, wird einen Fehler von 7% produzieren.

Wenn man natürlich selber Hand anlegt, dann geht es bestimmt auch mit 9600............


Grüße,
Cassio
 
So, melde Erfolg: Baudrate runter, Erfolg rauf!

Wie es ausschaut, scheint 4800 noch gut zu klappen, ab 9600 hauts nicht mehr hin. Bei den zu erwartenden Daten vermute ich mal, dass ich mit 4800 locker leben kann. Achja, diese ominöse Sache B = B - 64 ist nun auch hinfällig.

Vielen Dank für eure Hilfe! Habe ne Menge dabei gelernt :)
 
Hi Ditron,

Wie es ausschaut, scheint 4800 noch gut zu klappen, ab 9600 hauts nicht mehr hin.
...
Vielen Dank für eure Hilfe! Habe ne Menge dabei gelernt :)
Als Tip ...
Wenn du mit den UARTs arbeitest oder irgendwo anders nen sauberen Takt benötigst dann verlaß dich auf keinen Fall auf den internen Oszillator. Das ist ein RC-Oszillator mit der entsprechenden Toleranz. Nimm nen Quarz. Es ist streßfreier ;) Der Oszillator kann auch einige Prozent von der angegebenen Frequenz abweichen. Und wenn sich die Toleranz der Baudratenerzeugung mit der Toleranz des internen Oszillators zufällig in der gleichen Richtung summieren dann läuft es evtl nicht.

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)