mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik mehrere Pins vom Mega32 einlesen und Frage zu Ponyprog


Autor: Wolfram Quehl (quehl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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...

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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...

Autor: Wolfram Quehl (quehl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Falk:
Die Erwähnung der .set-Direktive lässt mich vermuten, dass Wolfram nicht 
in C programmieren will...

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Wolfram:
Sind das OneWire-Sensoren? Also DS1820 o.ä.?

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Autor: Wolfram Quehl (quehl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sind ZMD Sensoren TSic 506. digitaler Ausgang

Wie funktioniert denn der Switch in Assembler?

mfg

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Wolfram Quehl (quehl)

>Wie funktioniert denn der Switch in Assembler?

Welcher Prozessor?

Mfg
Falk

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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...

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Johannes M. (johnny-m)

>Im Betreff steht was von nem Mega32...

Ohje, bin heute bissel blind. 8-0

MfG
Falk

Autor: Wolfram Quehl (quehl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du willst Port und Pin "hochzählen"? Bei den Pins ist das ja kein 
Problem. Beim Port musste eben ne separate Abfrage machen.

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Autor: Wolfram Quehl (quehl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist das nicht mal wieder ein gutes Thema für ein Tutorial? Switch in 
Assembler, mit verketteten CPIs oder Sprungtabelle.

MFG
Falk

Autor: Wolfram Quehl (quehl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
.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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, in einer Schleife geht das nicht...

Dann bleibt vermutlich tatsächlich nur die Variante mit der Schieberei.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Autor: Wolfram Quehl (quehl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Quehl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Autor: Quehl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Troll Blaubär (blaubeer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Wolfram Quehl (quehl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.