Hallo Gemeinde.
Ich komme im Moment gar nicht weiter.
Device 8051
Sprache C
Ich möchte die 8 Pins eines Ports schalten.
Jedes gesetzte Pin soll gehalten bleiben.
Bspl.
Alle Pins sind auf Low.
Es wird ein Pin auf High gesetzt. z.B. Pin 5
Danach sollen automatisch die höherwertigen Pins (6 und 7) nacheinander
gesetzt werden.
Ist Pin 7 erreicht soll es bei Pin 0 weitergehen, bis wieder Pin 5
erreicht wird.
Dabei sollen die durchlaufenen Pins auf High bleiben.
Ist Pin 5 erreicht geht der ganze Port auf Low und es geht von vorn los.
Quasi wie eine Rotation, oder so. :o)
Hat jemand die zündende Idee?
Im Vorraus vielen Dank.
Kerno
Ist vermutlich auch für den 8051 anwendbar:
Für AVR: Wenn es ganz schnell gehen muss, dann mit Inline-Assembler,
weil Du damit Zugriff auf das Carry hast.
Ansonsten z.B. so:
1
uint8_tpattern=0x40;// Anfangswert (nur als Beispiel)
2
uint8_toldpattern=0x40;// = Anfangswert
3
4
do{
5
pattern|=(pattern<<1);
6
if(pattern==oldpattern)pattern|=1;// da wir kein Carry haben
Entschuldigt meine späte Antwort.
Danke für eure Denkanstöße.
Ich habe beide Varianten angesehen und mir angepasst.
@Peter:
In dieser Zeile habe ich noch das "+" eingefügt, da bleiben die
durchlaufenen Bits auf High. Sicher nur vergessen worden.
1
P2=*p++;
->
1
P2+=*p++;
Diese Funktion kann ich mir jetzt nicht so anpassen, wie ichs brauche,
damit´s bei 0 wieder los geht.
Werde mir aber bei Gelegenheit diese Variante nochmal vornehmen.
@Drachenjäger:
Dein
>> // hier die Ausgabe einfügen
habe ich an den Anfang der do-while Schleife gesetzt, sonst sind schon
das Anfangsbit und das nächste Bit gesetzt im ersten Durchlauf gesetzt.
Wenn ab dem Anfangswert z.B Pin 5 alle Pins bis Pin7 gesetzt sind,
dauert es ne weile bis bei Pin 0 weiter gemacht wird. Warum ist das so?
Ok habs: int -> u_char
Muss ich oldpattern mit einem Wert initialisieren?
Nein. Oder?
Ansonsten machte die Funktion auf Anhieb das, wie ich es mir vorgestellt
habe.
1
#include<stdio.h>
2
#include<at89c51xd2.h>
3
4
sfrport=0x90;
5
6
intmain(void){
7
8
intk;
9
unsignedcharpattern,oldpattern,startwert=32;
10
pattern=startwert;
11
12
while(1){
13
14
if(port==0xff){
15
pattern=startwert;
16
}
17
port=pattern;
18
pattern|=(pattern<<1);
19
if(pattern==oldpattern)pattern|=1;// da wir kein Carry haben
20
oldpattern=pattern;
21
for(k=20000;k>=0;k--);
22
}
23
return0;
24
}
Vielen Dank für die Anregungen.
Ich hatte schon nen Knoten in den Fingern.
Oh! Da da sehe ich schon eine weitere Hürde.
Meine "Rotation" darf nur über 7 Pins und nicht über 8 Pins gehen.
Ist Drachenjäger´s Version nur für 8 Pins machbar?
Grüße Kerno.
KernoKopp schrieb:
> In dieser Zeile habe ich noch das "+" eingefügt, da bleiben die> durchlaufenen Bits auf High. Sicher nur vergessen worden.
Nein.
Die Tabelle ist doch nur ein Beispiel.
Du mußt die Tabelle selber erstellen!
> Diese Funktion kann ich mir jetzt nicht so anpassen, wie ichs brauche,> damit´s bei 0 wieder los geht.
Siehst Du.
Peter
mhh...da bräuchte ich 49 Tabelleneinträge.
Ich habe eine Laufvariable, die nur die Zahl 1-7 annehmen kann.
-> Das ganze sieht aus wie ein Monatsplan. Einmal die Woche findet ein
Event statt. Welcher Tag das ist, legt der Benutzer fest.
Pin0 = Montag
Pin7 = Sonntag
Es gibt ein Event, welches an einem beliebigen Wochentag passiert.
z.B. Mittwoch = Pin2.
Da leuchtet der Mittwoch.
Den nächsten Tag leuchtet Mittwoch und Donnerstag
dann Mittwoch und Donnerstag und Freitag......
Das läuft dann weiter über den Sonntag bis zum Dienstag.
Dann Mittwoch kommt wieder das Event.
Oder interpretiere ich deine Funkiotn falsch.
Danke Kerno
KernoKopp schrieb:
> mhh...da bräuchte ich 49 Tabelleneinträge.> Ich habe eine Laufvariable, die nur die Zahl 1-7 annehmen kann.
???
Den mußt Du mir mal erklären.
Wenn Du nur 7 Möglichkeiten hast, dann kannst Du auch nur 7 Einträge
zugreifen.
Welche LED nun bei welchem Eintrag leuchtet, legst Du in der Tabelle
fest.
Egal, ob Du alle 8 LEDs einschaltest (0xFF) oder keine (0x00).
Peter
> Meine "Rotation" darf nur über 7 Pins und nicht über 8 Pins gehen.> Ist Drachenjäger´s Version nur für 8 Pins machbar?
Verstehe ich nicht ... oben hast Du doch von den Bits 0 bis 7
geschrieben!
Also, wenn Du z.B. die Bits 1-7 rotieren lassen willst (Bit 0 also
ignorierst), kannst Du
1
if(pattern==oldpattern)pattern|=3;
statt if (pattern==oldpattern) pattern|=1; schreiben.
Hallo Peter, Hallo Drachenbändiger,
vielen Dank für eure Mühen.
Jetzt ist der Groschen gefallen.:o)
Ich habe mal wieder viel zu kompliziert gedacht.
Eine solche "Rotation" ist völlig überflüßig.
Eine einfache Bitmaske (like Peter) ist da schon die Lösung.
Meine Laufvariable mit den Werten 1-7 wird ja extern erzeugt.
Da brauche ich mich nicht drum kümmern.
Somit kann ich mit ihr auf die Positionen im Feld zugreifen und mit dem
nächsten Wert ODER verknüpfen.
Machmal hat man eben Brett vorm Kopp ;o)
KernoKopp schrieb:
> Somit kann ich mit ihr auf die Positionen im Feld zugreifen und mit dem> nächsten Wert ODER verknüpfen.
Oh Gott, nein doch.
Du trägst genau alle die LEDs ein, die leuchten sollen !!!
Nix rotieren und nix oder.
Es wird immer der komplette Port gesetzt.
Und wenn nach i == 6 von vorne, dann einfach:
Hallo Peter, vielleicht ist mein TestCodeSchnippsel etwas ungünstig
gewählt.
Der Code macht vom Prinzip her das, wie ich mir das vorgestellt habe.
Die Werte im Feld wt sind auch nur nachempfunden, wie sie decodiert vom
DCF77 Signal, für die Wochentage als Dezimalzahl in dieser Reihenfolge,
kommen könnten.
Diese Dezimalzahlen sind er Index für das "pattern" Feld.
Hier im Code fängt meine Woche z.B. mit Freitag (4), da ein Feld ja bei
Index 0 anfängt, an. Vom DCF kommt da ja eine 5.
D.h es leuchtet als erstes der Pin für Freitag P1.4 (0x10)
Am Sonnabend soll nicht nur Sonnabend P1.5 (0x20), sondern auch
weiterhinder Freitag P1.4 leuchten. -> 0x10 | 0x20
Ist der Sonntag P1.6 (0x40)erreicht gehts bei Montag P1.0 (0x01) weiter.
Bis zum Donnerstag P1.3 (0x08)
Die 7 Tage einer Woche können einem belibeigen Tag anfangen zu zählen.
Aber P1.0 ist Montag......und P1.6 ist Sonntag.
Die Schleife und die Incrementierung ist nur um mal alles druchlaufen zu
lassen.
1
port=pattern[wt[i++]]|w;
2
w=port;
Ich mach mal wieder viel Lärm um Nichts.
Danke und Gruß Kerno
KernoKopp schrieb:
> D.h es leuchtet als erstes der Pin für Freitag P1.4 (0x10)
1
unsignedcharcodepattern[]={0x10,...
> Am Sonnabend soll nicht nur Sonnabend P1.5 (0x20), sondern auch> weiterhinder Freitag P1.4 leuchten. -> 0x10 | 0x20
1
unsignedcharcodepattern[]={0x10,0x30,...
Nun endlich klar?
Deine Rum-Oderei ist völlig unsinnig.
Die Tabelle sollte aber nicht mit Freitag anfangen, da DCF77 von Montag
.. Sonntag (1 .. 7) zählt.
Also zuerst den Wert für Montag in die Tabelle und zuletzt für Sonntag
und dann: