ich möchte die Daten von mehreren Port-Pins mit der gleichen Subroutine verarbeiten. Geht das überhaupt? Die Schwierigkeit liegt darin, daß beim Einlesen eine Nummer erwartet wird und somit keine Variable möglich erscheint. Ich hatte schon daran gedacht, die Adressen der Pins im Speicher abzuspeichern, aber diese können dann auch nur in ein Register gebracht werden. Dann hatte ich noch an die .SET Variable gedacht. Aber das habe ich wohl nicht verstanden. Da kann ich mir nicht vorstellen, daß während der Laufzeit die Variable geändert werden kann. Andererseits kann ich den Sinn von .SET nicht erkennen. Als Alternative bliebe nur übrig, die Subroutine mit verschiedenen Portpins mehrmals zu schreiben. Das sehe ich aber als schlechte Programmierung an. Bei Ponyprog kann man eine Seriennummer in das Programm bringen. Hat da schon jemand Erfahrung mit? Ich denke, daß man da die Anzahl der Programmierungen des Flashspeichers festhalten kann. Um nicht immer daran zu denken, müßte wohl zweckmäßigerweise ein Script erstellt werden. An welche Adresse wäre es zweckmäßig, diese zu speichern? mfg
> Dann hatte ich noch an die .SET Variable gedacht.
Mit .set kann man Platzhalter erzeugen, aber keine Variablen!
Beschreibe doch bitte mal genauer, was Du machen willst. Aus dem Posting
oben werde ich nicht recht schlau. Und selbstverständlich kannst Du
beliebig viele Pins in einem Unterprogramm verarbeiten...
> Die Schwierigkeit liegt darin, daß beim Einlesen eine Nummer erwartet > wird und somit keine Variable möglich erscheint. Das verstehe ich überhaupt gar nie nicht...
ich will mehrere Temperatursensoren anschließen, die gleichartig verarbeitet werden, weil das die gleichen Sensoren sind. Bei der Verarbeitung muß der Pin jedoch mehrmals gelesen werden und das ist dann auch so mittendrin. Darum wollte ich die Pinnummer als Variable haben, die ich nach jeder Temperaturmessung umschalte. Soweit klar? mfg
@ Wolfram Quehl (quehl) >auch so mittendrin. Darum wollte ich die Pinnummer als Variable haben, >die ich nach jeder Temperaturmessung umschalte. Das kann man einfach über ein switch Konstrukt machen. switch(pin_nummer) { case 1: //lese Pin 1 break; case 2: //lese Pin 2 break; } MFG Falk
@Falk: Die Erwähnung der .set-Direktive lässt mich vermuten, dass Wolfram nicht in C programmieren will...
@ Johannes M. (johnny-m) >Die Erwähnung der .set-Direktive lässt mich vermuten, dass Wolfram nicht >in C programmieren will... Jetzt wo du es sagst . . . ;-) Ok, da eben ein switch in Assembler. MfG Falk
sind ZMD Sensoren TSic 506. digitaler Ausgang Wie funktioniert denn der Switch in Assembler? mfg
@ Wolfram Quehl (quehl)
>Wie funktioniert denn der Switch in Assembler?
Welcher Prozessor?
Mfg
Falk
@Falk: Im Betreff steht was von nem Mega32... @Wolfram: Ein switch ist nichts anderes, als eine Kette von Abfragen bzw. Vergleichen einer Variablen mit einer Reihe von konstanten Werten. Das in Assembler umzusetzen sollte eigentlich kein Problem sein, ist aber auch nur Teil der Lösung Deines Problems. Noch mal die Frage: Sind das OneWire-Sensoren? "Digitaler Ausgang" kann alles Mögliche sein...
@ Johannes M. (johnny-m)
>Im Betreff steht was von nem Mega32...
Ohje, bin heute bissel blind. 8-0
MfG
Falk
ja, sind 1-draht Sensoren, aber keine Dallas. Geben ein PWM Signal aus. Ich habe da z.B. SBIS Port, Pin stehen. Und diese Port und Pinnummer bekomme ich nicht als Variable. mfg
Du willst Port und Pin "hochzählen"? Bei den Pins ist das ja kein Problem. Beim Port musste eben ne separate Abfrage machen.
@ Wolfram Quehl (quehl) >ja, sind 1-draht Sensoren, aber keine Dallas. Geben ein PWM Signal aus. Ist es aber nicht der Witz an der Sache, dass das "1-Wire BUS" heisst? Die kann man doch alle an einen Draht hängen. Die Software muss dazu erstmal alles identifizieren (schau mal in der Codesammlung nach, Peter Danneger hat da mal was reingestellt) und danach über ihre Nummer ansprechen. Braucht sensationell nur 1 IO-Pin. >Ich habe da z.B. SBIS Port, Pin stehen. Und diese Port und Pinnummer >bekomme ich nicht als Variable. Naja, könnte man schon, wird aber aufwendig. Ein Switch (Assembler oder C) ist da einfacher. MFG Falk
@ Johannes M wie soll ich denn die Pins hochzählen, wenn die nicht in eine Variable gehen? Port könnte ich ja bei Bedarf noch fest machen. Sind eben die Anschlüsse nicht so variabel, aber die Pins? @ Falk die 1-Draht Anschlüsse bei ZMD sind keine Busanschlüsse, deswegen habe ich extra geschrieben, kein Dallas und in den vorherigen Posts extra das nicht so deutlich gesagt, damit es keine Irreführung mit dem Dallas Bus gibt. mfg
Nun, Du hast es ja (zumindest teilweise) schon richtig erkannt: Die .set-Direktive könnte Dein Freund sein, da Du damit Bezeichner auch relativ verändern kannst. Dann kannst Du mit sbic/sbis arbeiten. Ansonsten könntest Du den jeweils benötigten Pin auch maskieren (einfach eine 1 durch das Register schieben).
Ist das nicht mal wieder ein gutes Thema für ein Tutorial? Switch in Assembler, mit verketteten CPIs oder Sprungtabelle. MFG Falk
.set wäre zwar das Beste, wenn es funktionieren würde. Ich hab aber Zweifel, weil .xxx Anweisungen solche für den Assembler sind und nicht für die Laufzeit. Was soll denn der Assembler übersetzen, wenn ich schreibe .SET A=PortC .SET B=PIN2 SBSIS A,B .SET A=PortC .SET B=PIN3 JMp nach SBIS Was setzt der Assembler für A und B ein? Ich glaub so geht das nicht. Mit dem Schieben im Register werd ich mal überlegen. Alternativ hatte ich an einen echten Switch gedacht. Der würde so funktionieren: Anweisungen zum Einlesen der Pins als Subroutine. Im Z Register jeweils die Adresse der Subroutine speichern und mit ICALl aufrufen. Nachteil ist die höhere Taktzahl, zumal das Register Z schon verwendet wird und dann noch Push und Pop dazukommen. mfg
Stimmt, in einer Schleife geht das nicht... Dann bleibt vermutlich tatsächlich nur die Variante mit der Schieberei.
Wolfram Quehl wrote: > Nachteil ist die höhere Taktzahl, zumal das Register Z schon verwendet > wird und dann noch Push und Pop dazukommen. Eben. Manchmal ist es eben "billiger", einen Code mehrfach zu schreiben als ihn in einer Schleife aufzurufen. Flash hast Du schließlich reichlich verfügbar, bei der Rechenzeit (für zeitkritische Dinge) könnte es knapp werden, bei dem, was Du da noch alles reinbringen willst. ...
Falk wrote: > Ist das nicht mal wieder ein gutes Thema für ein Tutorial? Na dann schreib'... ;-) Nein, das denke ich nicht, denn das Tutorial kann nicht berücksichtigen, dass Wolfram noch jede menge andere zeitkritische Dinge in seinem Programm unterbringen möchte. Er kann es sich vermutlich nichtmal (ungestraft von anderen Programmteilen) leisten, während der Abfrage eines Temp-Sensors den Interrupt zu sperren und die Bit-Zeiten mittels Warteschleifen zu ermitteln. > Switch in > Assembler, mit verketteten CPIs oder Sprungtabelle. Ja, schon, aber das ist nun nicht gerade das Einsteiger-Thema. Nützlicher fände ich eine Einführung in die Programmierung mittels Zustandsautomaten (quasi-parallele Abarbeitung mehrerer Aufgaben statt nacheinander in einer Schleife), doch da fehlt mir die Kompetenz (Hintergrundwissen, fachlich korrekte Bezeichnungen), ein solches Tut zu schreiben. ...
ich denke, ich hab was passendes gefunden. Bitte um Beurteilung. .def SensorNr=R24 .equ ZMD=PinC ldi SensorNr,1 in Temp,ZMD and temp,SensorNr breq ich denke, sowas könnte durchaus ins Tutorial. Ich hatte ja auch versucht, am Anfang die Frage möglichst allgemein zu halten. Das Ergebnis jetzt ist auch nur allgemein. Wichtig war hier, die Sensor Nr. vorzugeben und nach dem Einlesen des Pins entsprechend weiter zu verarbeiten. Ein Schieben wie oben angegeben, wäre möglich, aber auch beliebige Pins wären möglich bei geringfügig mehr Code am Anfang. Der Sensor kostet übrigens etwas über 10 Euro bei Farnell. Genauigkeit +-0,1°. Darum halte ich diesen für den besten Temperatursensor. mfg
@ Wolfram Quehl (quehl) >ich denke, ich hab was passendes gefunden. Bitte um Beurteilung. >.def SensorNr=R24 >.equ ZMD=PinC >ldi SensorNr,1 >in Temp,ZMD >and temp,SensorNr >breq >ich denke, sowas könnte durchaus ins Tutorial. Ich hatte ja auch ??? Dir ist schon klar, dass das was du da oben geschrieben hast alles konstante Werte sind? Die kann man bequem im Quellcode einstellen, zur Laufzeit sind sie dann aber konstant. >Der Sensor kostet übrigens etwas über 10 Euro bei Farnell. Genauigkeit Bezeichnung? >+-0,1°. Darum halte ich diesen für den besten Temperatursensor. Sind sie WIRKLICH auf 0,1C GENAU oder haben die nur 0,1C Auflösung? MFG FaLK
TSIC 506 Genauigkeit lt. Datenblatt und mündl. Auskunft. Es gibt auch etwas weniger genaue. TSIC 306 mit 0,3°. Warum soll man das zur Laufzeit nicht verändern können? Ich kann doch dem SensorNr (R24) einen anderen Wert zuweisen, indem der Rest in einer Schleife liegt. Das soll doch den Unterschied zu den vielen IF Abfragen verdeutlichen bzw. zum Switch. Hier wird zum Einlesen und Abfragen der verschiedenen Pins kein Sprung innerhalb des Ablaufes gemacht, sondern erst, Wenn der nächste Pin dran ist. mfg
@ Quehl (Gast) >Warum soll man das zur Laufzeit nicht verändern können? Ich kann doch >dem SensorNr (R24) einen anderen Wert zuweisen, indem der Rest in einer >Schleife liegt. Das soll doch den Unterschied zu den vielen IF Abfragen >verdeutlichen bzw. zum Switch. Hier wird zum Einlesen und Abfragen der Nenene. Ich glaube du irrst. Wenn ich das richtig verstehe, dann hast du beispielsweise an PORTC und PORTD jeweils 8 Sensoren dran. Die müssen per One-Wire angesteuert werden. Um nun die Portadresse sowie die Bitnummer variabel zu gestalten, musst du - beim lesen anstatt IN den Befehl LD verwenden, da IN nur mit konstanten Adressen arbeitet. LD kann mit variablem Z-Pointer arbeiten. -dito anstatt OUT eben ST Also ldi ZH,0 ldi ZL,PORTC+0x20 Jetzt kann man die Subroutine aufrufen, PORTC kann nun mit ld r16,Z st Z,r16 gelesen und geschrieben werden. Um die Bitnummer variabel zu gestalten nimmt man einfach ein Byte und schreibt die entsprechnde Maske rein. Also 0x01 Bit 0 0x02 Bit 1 0x04 Bit 2 0x08 Bit 3 0x10 Bit 4 0x20 Bit 5 0x40 Bit 6 0x80 Bit 7 Über einen UND Vergleich kann man immer das Bit prüfen und weiterverarbeiten (Zero Flag), mit ODER Bits setzen (vorher lesen!). Wolltest du sowas? Andererseits könnte man auch eine Sensornummer definieren (0..15) und das mittels einer Sprungtabelle das abhandeln? Siehe mein Artikel. Wie findest du ihn? MfG Falk
Den Tutorial Artikel finde ich ganz gut. Aber das kannte ich vom Prinzip schon. Dort wird dargestellt, wie man von einem Eingang verschiedene Programme aufruft. Bei mir ist das aber umgekehrt, wie man von verschiedenen Eingängen dasselbe Programm aufruft. Mit Switch geht das nicht. Ich werde mir obiges nochmal genauer ansehen. Versuche, mit Speicherbefehlen auf I/O Adressen zuzugreifen, hat bei mir bisher nicht funktioniert. Darum werde ich die Befehle oben mal ausprobieren. Danke. mfg
Quehl wrote: > Den Tutorial Artikel finde ich ganz gut. Ich auch. > Aber das kannte ich vom Prinzip > schon. Ich auch. > Dort wird dargestellt, wie man von einem Eingang verschiedene > Programme aufruft. Bei mir ist das aber umgekehrt, wie man von > verschiedenen Eingängen dasselbe Programm aufruft. Mit Switch geht das > nicht. Nein, aber durch Funktionsaufruf bzw. Aufruf eines Unterprogrammes. In AVR-ASM wäre das call oder rcall. > Ich werde mir obiges nochmal genauer ansehen. Versuche, mit > Speicherbefehlen auf I/O Adressen zuzugreifen, hat bei mir bisher nicht > funktioniert. Dann hast Du vermutlich nicht an den Offset der Adressen des gemappten Bereiches gedacht. > Darum werde ich die Befehle oben mal ausprobieren. Danke. Probieren alleine wirds nicht bringen, ein Blick in die Befehlsbeschreibung kann auch manchmal hilfreich sein. > > mfg cu. Blaubeer
die Befehle funktionieren. Offset hatte ich schon richtig gemacht. Ich vermute, daß ich ein unteres Register verwendet habe, das nicht geht. Weiß ich aber nicht mehr. Trotzdem verstehe ich das nicht, warum das mit IN nicht gehen sollte. LD und IN laden ein Byteport in ein Register. Allenfalls könnte man überlegen, was im Einzelfall günstiger ist, weil man den nächsten Port berechnen kann und IN eine neue Zuweisung braucht. Aber bei z.B. 2 Ports lohnt sich der Aufwand mit der Berechnung vermutlich nicht. mfg
@ Wolfram Quehl (quehl) >Trotzdem verstehe ich das nicht, warum das mit IN nicht gehen sollte. LD >und IN laden ein Byteport in ein Register. Allenfalls könnte man IN hat als Adressparameter eine Konstante, welche zur Kompilezeit bekannt ist und während der Laufzeit fest ist. LD arbeitet mit Variablen (Pointern)als Adressparameter, welche zur Laufzeit geändert werden können. MFG Falk
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.