Hallo, kann mir jemand mit folgenden Problem helfen : Ich bin dabei, einen Converter für ein serielles LCD zu bauen, damit über den UART Txd ein Display mit einfachen Printbefehlen steuern kann. Aber : Ich möchte gerne auswerten, wenn ein String übertragen wurde, also CHR(10) bzw. (13) gesendet wird. Ich arbeitet mit dem UDR-Register, welches o.g. "ASCII-Zahlen) überträgt. Wenn ich aber den Interupt auslöse onRXD und sage if udr = 10 then "string-Ende" reagiert er garnicht, auch nicht bei UDR = 13, nämling dann soll der "fertige" String übergeben werden und zur Anzeige kommen. Vielleicht kann mir jemand helfen...? Gruss Alex
Du musst schon Dein Program herzeigen, damit wir Dir sagen koennen was daran nicht stimmt.
Alle empfangenen Zeichen in einen Ringbuffer im SRAM ablegen. Dabei immer die letzten beiden Zeichen auf 10 und 13 prüfen. Der Ringbuffer sollte so groß sein, dass er den maximal möglichen String fassen kann. Der Einfachheit halber kann man das zuletzt empfangene Zeichen auch in einem weiteren Register halten, so wird das Prüfen des letzten und des aktuellen Bytes (mit CPI) bequemer (da ohne Zugriff auf den Buffer). Ein ähnliches System habe ich auch im Hinterkopf, allerdings ist mir der Mega8 dazu etwas zu groß (Overkill), der Tiny2313 hat mir aber etwas zuwenig SRAM (für Ringbuffer) für ein 8x24-LCD. ...
Hallo, ich nutze BASCOM und verstehe nicht, warum if udr = 13 then ... nicht anschlägt.. Ich poste nochmal das Listing, am WE... Gruss
du verwendes inkey vermute ich als Eingabesequenz Das gibt dir den ASC vom eingegangenen Wert an. Ist kein Zeichen im Puffer gibts 0 zurück. Der Print gibt die nachfolgenden Zeichen auf der UART aus + CR + LF, es sei denn du brungst nach dem Print und Zeichenfolge ein ; Semikilon, dann bringt er das nicht. kuck mal ob du Semikolon al Abschluss von deinem Print hast, wenn ja, dann raus damit
Hallo, @ Marko Ich nutze diese Geschichte mit Interrupt, wenn ein Zeichen auf Uart empfangen wurde... OnRXD und dann im Interupt "Sting1" = "String1" + chr(udr) Also packe immer ein Zeichen dazu und dann möchte ich, wenn udr = 10 then "String2" = "String1" also vollständigen String übergeben und dann lcd "String2" Gruss A. Arndt
> ich nutze BASCOM und verstehe nicht, warum if udr = 13 then ... > nicht anschlägt.. <Spekulation> Das I/O-Register "udr" behält seinen Wert nicht bis in alle Ewigkeit. Wenn man in ASM (also Maschinensprache) darauf zugreift, dann ist der Inhalt anschließend weg. In ASM muss man auch udr in ein Register einlesen (in temp,udr) und dann das Register überprüfen oder in den String (SRAM-Bereich) kopieren. Vielleicht sollte man (auch in Basic) mit einer Hilfsvariablen arbeiten. Also (QBASIC-Syntax): temp=udr if temp=10 then string2=string1 string1="" else string1=string1+temp endif Allerdings würde das Stringkopieren für eine ISR zu lange dauern, in ASM setze ich mir für sowas in einem reservierten Register ein Bit als Flag (Variable vom Typ Boolean, davon bis zu 8 Stück für verschiedene Zwecke in einem gemeinsamen Register), worauf das Hauptprogramm den etwas aufwendigeren Job (hier das Kopieren des Strings, Löschen des Empfangsstrings und die anschließende Ausgabe an das LCD) übernimmt. ISRs müssen nämlich so kurz wie möglich sein, sonst besteht die Gefahr, dass Interrupts verschluckt werden. In der ISR würde dann stehen (QBASIC-Syntax): temp=udr if temp=10 then flags=flags or 1 else string1=string1+temp endif In der Mainloop wird dann zyklisch "flags" abgefragt: do 'andere Mainloop-Jobs... if flags and 1 then flags=flags and (255-1) 'Flag löschen string2=string1 'String kopieren string1="" 'RX-String löschen lcd string2 'String an LCD endif loop </Spekulation> Wie gesagt, QBASIC-Syntax (außer "lcd"), BASCOM kenne ich nicht weiter, AVRs programmiere ich in ASM, das bietet viel mehr Freiheiten und Übersichtlichkeit (ASM ist eindeutig...). Aber ganz so einfach wird das auch nicht, denn die LCD-Ausgabe ist relativ langsam, da das LCD nach jedem Byte beschäftigt ist und die Ausgaberoutine entweder mit Wartezeiten arbeitet oder das Busy-Flag des LCDs abfragt (und auch nur wartet). Dies ist ein Grund, weshalb ich inzwischen meine LCD-Ausgaben über Ringbuffer laufen lasse und die Zeichenausgabe vom Ringbuffer zum LCD über Timer (und Jobflag) synchronisiere. Somit wird das nächste Zeichen immer erst ausgegeben, wenn der nächste "Termin" ran ist. Dazwischen wird nicht gewartet, sondern die Mainloop durchlaufen und "geschaut, was es sonst noch so zu tun gibt", also alle Jobflags und ggf. Tastenflags der Entprellung abgefragt. ...
schon klar, so oder so, der chr 10 /13 muss aber gesendet werden und den Int auslösen. Den Int löst jedes Zeichen ausser chr(0) aus. ich denk aber auf der print-seite haste den semikolon drinne.
Hallo, hier endlich mein Code : $crystal = 12000000 ' frequency used $baud = 9600 ' baud rate Config Portb.1 = Output Config Portd.5 = Output Config Portc.1 = Output Config Lcdpin = Pin , Db4 = Portb.5 , Db5 = Portb.4 , Db6 = Portb.3 , Db7 = Portd.6 , E = Portd.7 , Rs = Portb.0 Config Lcd = 20 * 4 Config Timer1 = Pwm , Pwm = 8 , Prescale = 1 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down Dim Lcd_contrast As Byte Dim Backlight As Byte Enable Interrupts Dim Inco As String * 16 Dim Incom As String * 16 On Urxc Onrxd Enable Interrupts Enable Urxc Lcd_contrast = 190 Backlight = 60 Pwm1a = Lcd_contrast Pwm1b = Backlight Initlcd Cursor Off Cls Locate 1 , 1 Lcd " Serielles LCD V1.0" Linestart: If Inco <> "" Then Goto Show Print "gesend. Char :" ; Incom Wait 1 Goto Linestart Show: Locate 4 , 1 Lcd " " Locate 4 , 1 Lcd " Data:" ; Inco Print Incom Wait 2 Incom = "" Goto Linestart End Onrxd: Incom = Incom + Chr(udr) If Udr = 13 Then Inco = Incom Return ********************** E N D E ************************** Ich möchte doch nur, wenn eine String vollständig ist, also die Sendung von ASCII 10 + 13 das der "gesammelte" Sting incom zu inco vollständig übergeben wird.... H I L F E Gruss A. Arndt
Hallo nochmal, warum ist eigentlich die Quarzfrequenz für den Uart-Betrieb so von Bedeutung ? Gruss Alexander
Kussu mal ins Datasheet. Da steht eine Abbildung drin, woraus sich die U(S)ART die Taktfrequenz (Schieberegister) aus dem Quarz holt. Diese Frequenz wird noch geteilt und dann mittels des UBRRx weiter geteilt. Letztenendes ergibt das dann eben 9600 Hertz z.B.
UART taktet mit dem 16-fachen der Baudrate. Nun nimm mal übliche Baudraten mal 16 und nimm davon das kleinste gemeinsame Vielfache. Nun multipliziere das mit Ganzzahlen und schau dir die Werte mal an, besonders die, die in der Nähe der Max-Werte der AVRs liegen. Und dann vergleiche deine Ergebnisse mal mit den Tabellen für Baudraten in den AVR-Datenblättern im Kapitel U(S)ART. Dann bedenke, dass alles eine gewisse Toleranz hat. Auch die Baudrate des PCs. Ein kleiner Baudratenfehler (z.B. wegen eines Standardquarzes aus deinem Sortiment) kann ohne Weiteres mit dem PC funktionieren, falls der PC auch in die gleiche Richtung abweicht. Weicht er in die andere Richtung ab, dann wird es knapp, dann kann es passieren, dass die Abtastpunkte des Empfängers im Laufe der 10...12 Bits nicht mehr das Bit treffen, sondern davor oder danach. Uns schon gibt's Müll. Mit Quarzen, die ein Vielfaches von 1,8432MHz haben, bleibt man aber mit Sicherheit in der Toleranzgrenze. Es würde deinem Shop sicher nicht schaden, wenn du die Rubrik "Baudratenquarze für Mikrocontroller" eröffnest und die Reihe: 1,8432MHz, 3,6864MHz, 7,3728MHz, 14,7456MHz, 18,4320MHz beschaffst und anbietest. Plane mich aber bitte nicht mehr ein, ich habe mich bereits bei CSD eingedeckt, weil Reichelt sie nicht hatte. ;-) Dein BASCOM-Programm ist mir zu kryptisch (ich kann kein BASCOM), sei mir nicht böse, wenn ich mich damit nicht befasse. Leider habe ich kein LCD 4X20, also kann ich auch kein entsprechendes Programm in ASM schreiben. Eine Version für 4x27 (Pollin) nützt dir ja nix, das hat ja 2 Controller und ist daher nicht kompatibel. Auch die Version für 8x24 nützt nix, sie hat ja den Controller MS50530. ...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.