PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ende des Strings beim UART ?



guenter1604
01.07.2007, 22:30
Hallo,

Vom Terminal soll ein String unterschiedlicher Länge zum ATMega8 übertragen werden.
Dazu wird im URXC Interrupt das Zeichen zum String hinzugefügt.
Wie frage ich das Ende des übertragenen Strings ab ?

$regfile = "m8def.dat"
$Crystal = 3686400
$baud = 38400

Dim S As String * 63 At &H60
Dim b(11) As Byte At &H60 Overlay
Dim n As Byte

On URXC OnRxD
Enable URXC
Enable Interrupts

Main:
If N > 62 Then
'Print s
n = 0
End If
Goto Main

Onrxd:
If ? Then
Ende des Strings ist erreicht, er kann jetzt verarbeitet werden
Else
Incr N
B(n) = Udr
End If
Return

peterfido
01.07.2007, 23:14
?=13

Fragezeichen gleich Dreizehn...

guenter1604
02.07.2007, 07:32
Das ist der Problempunkt. Wie muss ich das Ende des Strings abfragen ?
Wie soll der Microcontroller wissen, daß das letzte Zeichen übermittelt wurde ?

Jaecko
02.07.2007, 07:46
Naja, mal das letzte Zeichen abrufen:

letzteszeichen = RIGHT(empfangenes, 1)

und dann eben prüfen:

If letzteszeichen = Endzeichen Then ...

EDIT: Sorry, zu spät gesehen, dass ja der String eh schon zeichenweise aufgebaut wird... is noch etwas früh...

guenter1604
02.07.2007, 07:53
Hallo,

wäre das so richtig ?

Onrxd:
If udr = asc(10) or udr = asc(13) Then
varEnde = True
return 'Ende des Strings ist erreicht, er kann jetzt verarbeitet werden
Else
varEnde = False
Incr N
B(n) = Udr
End If

Jaecko
02.07.2007, 08:02
Naja... ASC(10) ... macht so ned viel sinn.
Wenn dann ASC(udr) = 10 oder udr = CHR(10) (sofern udr ein String ist)
Aber ansonsten dürfts klappen.

Kann noch sein, dass Bascom nen Umweg will in der Anweisung in der Form:
xCR = chr(13)
xLF = chr(10)
Und dann damit IF udr = xCR or udr = xLF...

Bascom kann ja blödeweise nur immer 1 "Rechen-Anweisung" pro Zeile.

guenter1604
02.07.2007, 08:22
Hallo Jaecko,

oops, da habe ich was verdreht...

ich werds mal so probieren.

Was hätst du von den Bascom Highlevel Befehlen ?

wenn ich per configserialin und buffered meinen UART mache, ist das sinnvoller ? Bascom schreibt ja man solle nicht direkt auf die Register zugreifen...

Jaecko
02.07.2007, 09:00
Ich nehm eigentlich nur die Highlevels her.
Direktzugriff auf Register hab ich bisher noch nie benötigt.
(Werd ich wohl auch nur im Notfall verwenden; warum mitm Löffel im Garten rumgraben wenn man nen Bagger hat O:) )

Direkt über die Register könnts im Fall der Fälle schneller sein.
(Irgendwo war mal was, dass ne Bascom-Anweisung 300µS braucht, ne direkte nur 80 oder so...)

guenter1604
04.07.2007, 09:57
Hallo,

noch ne Frage:

$regfile = "m8def.dat"
$crystal = 7372800
$baud = 19200

$hwstack = 40
$swstack = 16
$framesize = 32

Config Serialin = Buffered , Size = 63 , Bytematch = 13
Config Serialout = Buffered , Size = 63

Dim Rx_char As Byte
Dim Serinpstr As String * 63
Dim Cr_received As Bit

Enable Interrupts


Do

If Cr_received = 1 Then
Cr_received = 0
Input Serinpstr
End If

Loop

Serial0charmatch:
Cr_recieved = 1
Return

End

jetzt habe ich das mal mit Highlevels versucht.
Ist das so richtig ?

Bleibt durch Bytematch = 13 eventuell ein darauffolgendes 10 im Buffer hängen ?[/code]

kolisson
22.07.2007, 01:53
also.. irgendwie interessant dieser quelltext von guenter1604. das funktioniert ja super.
aber mal ne fräge dazu:
1. wo kommt denn der inhalt der variablen Serinpstr her ? da wird ja nirgens was zugewiesen. der inhalt stimmt aber.

2. und warum wird das gemacht ?

If Cr_received = 1 Then
Cr_received = 0

wer weiss mehr ?

gruss klaus

Torsten_G
22.07.2007, 09:55
Hi,



...
1. wo kommt denn der inhalt der variablen Serinpstr her ?
...


Von hier: Input Serinpstr

Das Programm erwartet an dieser Stelle eine Eingabe im Terminal-Fenster.



...
2. und warum wird das gemacht ?

If Cr_received = 1 Then
Cr_received = 0
...

Damit wird der nächste Input freigegeben, wenn der vorherige Empfangszyklus abgeschlossen ist, würde ich sagen...

Was ich allerdings im Code nicht entdecken kann, ist dere Aufruf der Sub "Serial0charmatch"?

Viele Grüße

Torsten

kolisson
22.07.2007, 11:11
Was ich allerdings im Code nicht entdecken kann, ist dere Aufruf der Sub "Serial0charmatch"?

das widerum scheint mir klar zu sein. das ist eine funktion von bascom, die bei übereinstimmung eines zeichens im serin-puffer mit einer vorgabe , hier die CR den int auslöst.

gruss

guenter1604
22.07.2007, 22:29
Hallo,

da am Code ein gewisses Interresse besteht, noch eine Ergänzung:

nach Input Serinpstr:

if Asc(serinpstr) = 10 then
Strsize = Len(serinpstr) - 1
Serinpstr = Right(serinpstr , Strsize)
end if

Das hat folgenden Sinn:

wenn ein String eintrifft, wird nach dem Zeichen 13 ein Interrupt ausgelöst, der das Ganze aus dem Buffer in die Variable holt. Jetzt kann aber noch ein 10 folgen, das im Buffer hängenbleibt. Dieses steht dann beim nächsten String am Anfang. Das wird durch den Code entfernt.

guenter1604
22.07.2007, 22:37
Von hier: Input Serinpstr

Das Programm erwartet an dieser Stelle eine Eingabe im Terminal-Fenster.

Hoffentlich nicht !

Der gepufferte Datenempfang soll das warten verhindern. Input wird erst aufgerufen, wenn der Interrupt einen eingegangenen String meldet.(If Cr_received = 1 Then...)
In der anderen Zeit bleibt die Hauptschleife ungebremst.

kolisson
26.07.2007, 22:57
hallo guenter1604.... schön, dass du da nochmal nachgelegt hast. für mich könnte dein code interessant sein, da ich kleine atmel-schaltungen als laderegler für solarmodule laufen lasse. zur kontrolle der funtion habe ich einen ringspeicher installiert, der mir bei meiner taktung etwa alle 20 minuten die ladespannung loggt.

von zeit zu zeit... speziell auch nach ner fehlfunktion, möchte ich halt den ringspeicher auslesen. derzeit mache ich das über nen taster. den kann ich mir ja mit deiner routine wohl sparen.

die erste routine, die du hier eingestellt hast war schon ziemlich genau, was ich wollte... sie funktionierte nur nicht richtig.

die abfrage
If Serinpstr <> "send" Then Print "falsches commando"
brachte nicht das gewünschte ergebnis

der vergleich mit nem andren string ... hier "send" ... kam nie als true aus.

vielleicht lags ja an dem asc= 10 ... ich werde es bald mal testen.


gruss

p.s.

genau dieser ansatz in punkto serielle kommunikation könnte sehr hilfreich sein, in bezug auf das zuletzt in der zeitschrift CT besprochene projekt des CT-lab. hier können beliebige datenquellen offenbar über das von ct (kostenlos) angebotene programm "labview" abgefragt und grafisch dargestellt werden.
da jeder, der atmels programmiert, früher oder später über ein protokoll nachdenkt, das es ermöglicht, die daten des mcu auszulesen, bietet sich das labview protokoll doch förmlich an.
ich werde an dieser stelle ein neues thema eröffnen, "LAB-VIEW - ATMEL - CT-LAB"

guenter1604
27.07.2007, 08:43
Hallo kolisson,

guck mal hier...

http://www.heise.de/ct/projekte/machmit/ctlab/ticket/10

kolisson
28.07.2007, 00:09
hallo guenter,
hab mir das mal angesehen. da hast du dir ja ganz schön mühe gemacht. bravo !

ich hab mir den quelltext mal gespeichert und muss es halt mal durcharbeiten. was ich machen will, ist ja im prinzip das gegenteil von dem, was du gemacht hast.

ich will kein ct-lab bauen, sondern ich möchte den parser (also den interpreter) für die labview commandos in einen atmel brennen, um dann über labview z.b. den adc abzufragen. genausogut könnte ich mit nem atmel nen frequenzzähler bauen und den dann über labview auf dem pc darstellen und abfragen.

kleine black-boxes als helferlein, die dann nicht jeweils ein eigenes display benötigen.

also danke für deinen code.. wenn ich da weitergekommen bin, werde ich es posten. bin im moment allerdings mit meinen elektozäunen im weinberg beschäftigt, so dass ich noch nicht weiss, wann ich dazu komme.

gruss

guenter1604
31.07.2007, 14:30
Hallo kolisson,

abber genau das macht doch LabView.
Es sendet nacheinander Abfragen an die Eingänge auf den Modulen.
Diese Antworten zeigt dann LabView als Balken, Wert, Diagramm usw. an.

Welche Befehle du von LabView aus sendest, und was mit den Antworten passiert ist alles im LabView festgelegt.
Der Parser ist "nur" dafür da, die Anfrage an das richtige IC durchzustellen und die Antwort ins richtige Format zu bringen.

Den Syntax dazu ist der gleiche den man auch im Terminal benutzt. CM hat ihn unter Downloads als PDF zusammengefasst.

Die Antwortzeiten liegen je nach Anzahl von Modulen und Anfragen bei ein paar Milisekunden, also relativ flott.

Man muß aber den Unterschied zwischen Diagramm und Oszilloskop beachten.

Das Lab benötigt pro Wert ein paar Millisekunden nicht pro Durchlauf. Ausserdem schwankt die Antwortzeit. ALSO als Oszi ungeeignet aber zum Gleichzeitigen erfassen von vielen Werten über längere Zeit SEHR GEEIGNET.

Mein Modul zielt darauf ab, von bestimmten Modulen in Intervallen Werte anzufordern und die Ergebnisse abzuspeichern. Das ganze OHNE Rechner.

Nutzen?

Wenn ein Gerät Stunden oder Tage im Dauertest geprüft werden soll, reicht es das LAB an den Probanden anzuschliessen. Eine Auswertung der Daten erfolgt dann später am Rechner.
Gespeichert werden die Daten idealerweise auf einer CF-Karte.

kolisson
01.08.2007, 11:21
hallo guenter,

ja labview macht das .. das habe ich schon verstanden. da ich aber kein ctlab bauen will, sondern sagen wir mal.. einen atmel als ctlab verwenden (als beispiel möchte ich z.b. den adc 0 eines atmel über labview auslesen oder um noch komplexer zu werden, zwei atmels und und über labview jeweils den adc 0 auslesen).

mein problem derzeit ist,m das die routine, die im ctlab sitzt und auf die anfragen des labview reagiert, in c oder pascal geschrieben ist. diese sprachen verstehe ich nur schwerlich.

ich suche also den bascom equivalent zu dem teil, der im ctlab sitzt.

ich habe derezeit nicht die zeit, mich da wirklich reinzuknien. ich wollte nur das thema hier nicht sinnlos verstreichen lassen. solltest du also verstehen, was ich genau suche, und ein stückchen code für mich haben, wäre das super.

ansonsten werde ich mich in ca 14 tagen mal genauer damit befassen und mit kleineren fragen (so sie dann auftreten) nochmal an dich wenden.

gruss

guenter1604
02.08.2007, 10:41
Hallo kolisson,


als beispiel möchte ich z.b. den adc 0 eines atmel über labview auslesen

...dann auf die nächsten c'ts warten. CM geht dann näher auf die LabView-Programmierung ein.

Der Code für einen AVR? Der Parserteil von meinem c't-Beitrag ist das:

Sub Checkserinp

If Asc(serinpstr) = 35 Then 'wenn der String mit # losgeht kanns für uns sein
Checkbuff = Mid(serinpstr , 4 , 1) 'Variable zweckentfremdet um Speicher zu sparen
Speicher = Asc(checkbuff)
If Speicher = 37 Then 'wenn an 4. Stelle ein % kommt ists für uns
Checkbuff = Mid(serinpstr , 2 , 2)
Speicher = Val(checkbuff)
Select Case Speicher
Case 1 To 9:
Speicher = Speicher * 30
Speicher = Speicher - 29
Checkbuff = Mid(serinpstr , 5 , 32)
Writeeeprom Checkbuff , Speicher
Serinpstr = "#Speicher " + Str(speicher) + " Wert " + Checkbuff + " geschrieben"
Call Writeserinp
Case 99: ' Tastenkonfiguration wird aufgerufen
Call Fblearn
Case 98:
Checkbuff = Mid(serinpstr , 5 , 5)
Speicher = Val(checkbuff)
If Speicher > 65000 Then Speicher = 65000
Writeeeprom Speicher , 8173
Serinpstr = "# Geschwindigkeit gespeichert"
Call Writeserinp
Case 97:
Timerlearn = 1
Timerstring = Mid(serinpstr , 5 , 9)
Serinpstr = "# Abfolge: " + Timerstring + " gespeichert"
Call Writeserinp
Case Else
Serinpstr = "# Speichererror FB-Modul"
Call Writeserinp
End Select
Else
Call Writeserinp 'kein % dann schick den String weiter
End If
Else
Call Writeserinp 'kein # dann schick den String weiter
End If
End Sub

Hier wird abgefragt, ob das erste Zeichen ein "#" ist und das 4. ein "%".

Das sind willkürliche Festlegungen, das kann man auch anders machen.
Das 2. und 3. Zeichen legt den Befehl fest der vom Labview kommt.
diese 2 Zeichen werden in eine Zahl gewandelt und mit Case Select abgefragt.
Hier könnte die Abfrage eines Pins des ATMegas stehen, um sie mit "Print" auf die Reise zu schicken.

Gruß Günter