Hallo Community, ich brauche dringend hilfe bei einer Aufgabenstellung! Aufgabe: Das Programm soll fortwährend von einem Port ein Byte einlesen und die Anzahl der 1 des eingelesenen Bytes sollen gezählt werden. Hat der zähler 255 erreicht wird ein "Alarm" (Interrupt) ausgelöst. Dieser "Alarm" kann nur durch eine "Quittierung" (Interrupt) gelöscht werden. Problem: Wie lese ich den Wert des Ports ein und überprüfe diesen auf 1 ? Und wie setzte ich den "Alarm" zurück. Also mit der Quittierung ? Vielen Dank für die Antworten!
Dennis schrieb: > Hat der zähler 255 erreicht wird ein "Alarm" (Interrupt) ausgelöst. > Dieser "Alarm" kann nur durch eine "Quittierung" (Interrupt) gelöscht > werden. Vergiß das mit den Interrupts. Interrupts gibt es nur bei speziellen Bedingungen, nicht für beliebige Berechnungen. Was soll denn gezählt werden und wie schnell?
> Vergiß das mit den Interrupts. Interrupts gibt es nur bei speziellen > Bedingungen, nicht für beliebige Berechnungen. Interrupt soll ausgelöst werden wenn der Zähler 255 erreicht hat. > Was soll denn gezählt werden und wie schnell? Die anzahl der '1' auf dem Port. Bsp.: Im Port steht 0010 1111b. Dann müsste der zähler auf 47d. Ist das eingelesene Byte aber 1111 1111b. Ist der zähler auf 255d und ein Interrupt soll ausgelöst werden.
Dennis schrieb: > Wie lese ich den Wert des Ports ein und überprüfe diesen auf 1 ? Welche Programmiersprache? > Das Programm soll fortwährend von einem Port ein Byte einlesen und die > Anzahl der 1 des eingelesenen Bytes sollen gezählt werden. Wie erkennst du, dass das Byte "gültig" und "noch nicht ausgewertet" ist? Denn sonst zählst du ja einfach bei einem Bytewert ungleich 0 den Zähler mehr oder weniger schnell hoch. Etwa 8 mal schneller, wenn alle 8 Bits high sind, als wenn nur 1 Bit high ist. Ist dir das klar? Dennis schrieb: > Ist der zähler auf 255d und ein Interrupt soll ausgelöst werden. Kann man machen. Ist aber "durch die Brust ins Auge". Wozu unnötigerweise ein Interrupt, wenn du gerade erst selbst eigenhändig das Ergebnis berechnet hast? > Die anzahl der '1' auf dem Port. Bsp.: Im Port steht 0010 1111b. > Dann müsste der zähler auf 47d. Ich zähle da nur 5 einsen > Ist das eingelesene Byte aber 1111 1111b. Da sehe ich klar und deutlich 8 Einsen. > Im Port steht 0010 1111b. Dann müsste der zähler auf 47d. > Ist das eingelesene Byte aber 1111 1111b. Ist der zähler auf 255d Das sind jeweils nur die Binäre bzw. die Dezimale Darstellung der selben Zahlen. Du musst dir dringend das Kapitel "Darstellung von Dezimalzahlen im Dualsystem" nochmal ansehen. > und ein Interrupt soll ausgelöst werden. Der 8051 bietet hierfür keine Funktionalität. Poste doch einfach mal den Originaltext der Hausaufgabe...
:
Bearbeitet durch Moderator
> Welche Programmiersprache? Assembler Das ist einfach die Aufgabe. Den Sinn dahinter einfach nicht hinterfragen, soll zur Übung für eine Prüfung dienen. Aufgabe wurde genau so wie oben bereits beschrieben gestellt. >Wie erkennst du, dass das Byte "gültig" und "noch nicht ausgewertet" ist? Damit habe ich auch ein Problem.
>Der 8051 bietet hierfür keine Funktionalität. Poste doch einfach mal den
Originaltext der Hausaufgabe...
Hier die Origianle Aufgabenstellung. Mir ist bewusst das einiges hier
noch fehlt und die Aufgabenstellung auch sehr gut beschrieben ist.
(Sarkasmus)
Das ist nicht die Anzahl, sondern der Wert an dem Port, d.h. Du mußt den Wert vergleichen:
1 | if (P0 == 255) |
2 | mache_was(); |
Bzw. in Assembler
1 | mov a, #255 |
2 | cjne a, p0, weiter |
3 | call mache_was |
4 | weiter: |
Einen Interrupt kann man dafür nicht verwenden.
:
Bearbeitet durch User
Peter, eben nicht. Siehe Aufgabenstellung, GEILES Deustch: "Ist in Abhängigkeit von der Anzahl wir eine Adresse erhöht".. Also doch Einsen Zählen und um diese Menge einen Zähler erhöhen. Bei FFh dann Alarm und den Zähler nullen.
Also vermutlich 8er Schleife. Ganz grob: Bit x vom Port in C JNC ADD CP FFh JNC Alarm DJNZ Die Sprungmarken muss ers chon selber machen.
Dennis schrieb: > Hier die Origianle Aufgabenstellung. Bei dieser Beschreibung ist mir vieles unklar, z.B. - was ist mit "Anzahl der Einsen" gemeint oder ist es einfach nur der Wert des Bytes? z.B. 00101110 hat 5 Einsen oder den Wert 46 dezimal - was heißt "Adresse (Zähler) wird erhöht"? Ist die oben ermittelte Zahl direkt die Adresse? Oder soll bei jedem Einlesen die Adresse erhöht weden? Wenn ja: wie schnell soll gelesen werden? Fragen über Fragen...
Stephan schrieb: > Peter, eben nicht. Siehe Aufgabenstellung, GEILES Deustch: Das ist nicht geil, sondern völlig widersprüchlich. Man kann nur mutmaßen, was damit gemeint sein könnte. Das ist einem Lehrer unwürdig, Aufgaben müssen klar und eindeutig formuliert sein.
Dennis schrieb: > Originaltext der Hausaufgabe... Wenn das der echte Originaltext ist, dann würde ich die Schule wechseln. Denn diese "Aufgabe" an sich ist unsinnig, weil der Zähler einfach schnellstmöglich hochgezählt wird. Aber beim Erreichen des Endwertes soll da nicht im µC ein Interrupt ausgelöst werden, sondern der "Interrupt" soll nach aussen hin signalisiert und auf dessen "Quittierung" gewartet werden. Denn ein "Sofwareinterrupt" geht auch beim 8051 gar nicht so einfach, weil der keine Infrastruktur für sowas hat. Und wie man aus dem Signal eine "Periode" bestimmen soll ist auch völlig unklar. Irgendwie trollig, das Ganze...
:
Bearbeitet durch Moderator
Die Anzahl der Einsen in einem Byte kann maximal 8 betragen. Der Vergleich mit 255 muss daher immer false liefern. De Alarm wird daher niemals ausgelöst werden können. Dadurch ist auch die Quittierung überflüssig. Ein Compiler würde die komplette Aufgabe wegoptimieren. Vielleicht ist es das, was der Prof von seinen Studenten sehen will? Viele Grüße, Stefan
Es soll die Anzahl der EINSEN gezählt werden. ..wird eine Adresse erhöht, ist die Anzahl 255.... Alarm. Timer starten und die Zeit messen bis quitiert wurde. Mein Lösung. Ohne Frage ist die Aufgabe SEHR merkwürdig beschrieben.
Stefan K. schrieb: > Die Anzahl der Einsen in einem Byte kann maximal 8 betragen. Und wieviel macht das ?
Stephan schrieb: > Und wieviel macht das ? Wenn ich ein einziges Mal die Anzahl der Einsen in einem Byte zähle und alle 8 Bits des Bytes '1' sind, dann ist das Ergebnis 8. Ergo muss ich diese "fortwährende Zählung der Einsen" 32 mal durchlaufen, bis der Zähler dann auf 255 hochgezählt hat.
:
Bearbeitet durch Moderator
Stephan schrieb: > Und wieviel macht das ? Nach meinem Verständnis eben 8. Es soll ja nicht der Wert sondern die Anzahl der Einsen gezählt werden. Port in Variable lesen, 8x Bitshift in Carry, Zähler bei jedem Carry=1 hochsetzen... Die Aufgabenstellung ist nur wirr, es soll so oft wie möglich geprüft werden - wenn ich alle 20µs den Port lese, ist der Bitzähler schnell voll...
Dass die Anzahl der Einsen mehrerer Durchläufe addiert werden sollen, steht nirgends in der Aufgabe. Falls das gewünscht wäre, fehlen so wichtige Angaben wie Durchlauffrequenz und ein Löschkriterium des Zählers. Ansonsten wird bei nur einem Portpin auf logisch 1 innerhalb weniger us der Wert 255 erreicht und ein Alarm ausgelöst. Das ist ziemlich sinnfrei. Wahrscheinlicher ist, dass der Autor dieser Aufgabe den Port auf den Wert 255 bzw 0FFh testen lassen will und in diesem Fall ein Alarm ausgegeben werden soll. Dabei von "Zählen der Einsen" zu reden ist aber schlichtweg ein Fehler. Die ehrliche Konsequenz wäre, wie oben genannt die komplette Aufgabe wegzuoptimieren und damit den Prof mit seiner unterirdischen Aufgabenstellung zu konfrontieren. Ich gebe aber gerne zu, dass ich mich das als Student waohl auch nicht getraut hätte. Viele Grüße, Stefan
Die Frage wieviel es macht war ja nicht ganz ernst gemeint :-) "ist die Anzahl 255" Meinen die wirklich die Anzahl? Oder doch den Wert? Kommen wir doch wieder zur Fuzzi Logik zurück :-o
Stephan schrieb: > Meinen die wirklich die Anzahl? Oder doch den Wert? Ich glaube genau das ist das Problem. Nachdem der 8051 ja mittlerweile schon das ein oder andere Jahr auf dem Markt ist, steht zu befürchten, dass diese Aufgabe in all seiner Widersprüchlichkeit nicht erst seit gestern den Studenten vorgeworfen wird... Viele Grüße, Stefan
Stefan K. schrieb: > Wahrscheinlicher ist, dass der Autor dieser Aufgabe den Port auf den > Wert 255 bzw 0FFh testen lassen will und in diesem Fall ein Alarm > ausgegeben werden soll. Oder auch bei FFh vom Port einen Zähler incrementieren und bei FFh im Zähler dann Alarm. Sonst erfüllst Du die Bedingung: "Ist in Abhängigkeit von der Anzahl wir eine Adresse erhöht" NICHT. Stefan K. schrieb: > Durchlauffrequenz und ein Löschkriterium Interessiert hier nicht. Das die Aufgabe einen Sinn erfüllt wurde auch nicht geofrdert. Sie darf also sinnfrei sein. :-))))
Stefan K. schrieb: > Nachdem der 8051 ja mittlerweile schon das ein oder andere Jahr auf dem > Markt ist, steht zu befürchten, dass diese Aufgabe in all seiner > Widersprüchlichkeit nicht erst seit gestern den Studenten vorgeworfen > wird... Jetzt kommts, die wollen einfach nur sehen wer auf den ersten Blick erkennt das es Schwachsinn ist. Wie damals bei der Unix Prüfung. Löschen sie Datei XY. Wie lautet der Befehl ? Meine Antwort, die Frage ist nicht eindeutig da es 2 Lösungen gibt!
Dennis schrieb: > Originaltext der Hausaufgabe... > Hier die Origianle Aufgabenstellung Wurde das mit Google aus Soumi übers Janpanische ins Französiche nach Deutsch übersetzt? Dennis schrieb: >> Wie erkennst du, dass das Byte "gültig" und "noch nicht ausgewertet" ist? > Damit habe ich auch ein Problem. Frag den Aufgabensteller, was das soll. Er wartet darauf. Und frag ihn auch, auf was denn die eingelesenen Bytes "überprüft" werden sollen. Und was mit dem Ergebnis dieser Prüfung gesehen soll.
Lothar M. schrieb: > Wurde das mit Google aus Soumi übers Janpanische ins Französiche nach > Deutsch übersetzt? Diese Vermutung drängt sich geradezu auf.
Wenn Du wirklich auf 0xFF (also alle Pins Hi) reagieren willst, dann nimm eine Ladung UND Gatter und damit gehst Du auf den Interrupt Pin. Mehr wirst Du bei einem original 8051 nicht machen können. Eventuell kannst Du noch über die INT Richtung was absichern. Etwas langsammer wäre die Abfrage mit den Pollen vom Port, wurde hier ja auch schon gesagt.
Dennis schrieb: > fortwährend von einem Port ein Byte einlesen Damit ist wohl gemeint dass über einen Port Bytes parallel empfangen werden sollen. Das muss aber synchronisiert werden damit ein Byte nicht doppelt ausgewertet oder übersprungen wird. Dafür kommt vom Sender Gerät üblicherweise eine Clock auf einen 8051 Timer Pin oder ein Interrupt auf einen 8051 Interrupt Pin. Das Byte kann dann in der Interrupt Funktion gelesen und die Anzahl der 1 gezählt werden. Lothar M. schrieb: > "Sofwareinterrupt" geht auch beim 8051 gar nicht so einfach Geht ganz einfach mit einem beliebigen freien Timer: SETB TFx bewirkt Sprung in die "Sofwareinterrupt" Funktion genau wie beim ARM das SWI macht.
Was passiert, wenn ich die 255 nicht treffe? Die "Einser" Addition kann darüber sringen. ;-)
Welch Narr schrieb: > Was passiert, wenn ich die 255 nicht treffe? Jeder Zähler braucht einen Überlaufschutz ...
Welch Narr schrieb: > Was passiert, wenn ich die 255 nicht treffe? Die "Einser" Addition kann > darüber sringen. ;-) Nicht, wenn du nach jedem Increment des Zählers auf diesen Wert prüfst... Lothar schrieb: > Lothar M. schrieb: >> "Sofwareinterrupt" geht auch beim 8051 gar nicht so einfach > Geht ganz einfach Ginge auf diese Art auch mit einem externen Interrupt. Aber das ist eben auch ein ziemlich böser Workaround.
Lothar M. schrieb: > Ginge auf diese Art auch mit einem externen Interrupt. Aber das ist eben > auch ein ziemlich böser Workaround. "Sofwareinterrupt" per Timer ist auf den EFM8 8051 üblich - die haben reichlich Timer. Da werden auch noch ganz andere tolle Sachen gemacht wie Autostacking bei Interrupts und DMA ins XRAM ... Und Konstrukte mit Timer Ausgang Pin intern per Switch Matrix auf nicht rausgeführten Interrupt Pin ist bei den LPC ARM mit State Configurable Timer üblich :-) https://community.nxp.com/docs/DOC-332742
Lothar schrieb: > Geht ganz einfach mit einem beliebigen freien Timer: SETB TFx bewirkt > Sprung in die "Sofwareinterrupt" Funktion SW-Interrupt auf nem 8051 ist einfach nur großer Quatsch. Ein SW-Interrupt dient dazu, OS-Funktionen aufzurufen, ohne deren Adresse kennen zu müssen. Auf nem MC läuft aber kein OS, man kennt schon zur Linkzeit alle Adressen, d.h. man kann alles direkt callen. Da muß man nicht von hinten durch die Brust ins Auge umständlich einen Interrupt setzen.
Peter D. schrieb: > Auf nem MC läuft aber kein OS, man kennt schon zur Linkzeit alle > Adressen, d.h. man kann alles direkt callen Auf einem LPC ARM werden die Daten der Library Funktionen meist durch die MPU geschützt. Daher kann man die nicht im User Mode callen. Auf einem EFM8 8051 sind wegen der Pipeline die Anzahl der Clock Cycles von ACALL abhängig von CPU Takt vs. Flash Takt. Wenn es also ganz genau sein muss ... Aber ich denke damit kommen wir weit weg von der Frage :-)
Hi Zuerst einmal, in der Aufgabe seht nix von Interrupt. Es sollen Bits aus einem Port gezählt werden, die auf den Status "1" gewechselt haben. Dazu muß eine Flankenerfassung programmiert werden. Es wird en Referenzbyte auf Null initialisiert. Im Programm wird der Port eingelesen und mit dem Referenzbyte über eine Exclusiv-Oder Verknüpfung eine Statusänderung erfaßt.. Das Ergebnis muss nun noch mit dem aktuellen Portbyte ver-und-en werden, um den Wechsel von "0" nach "1" zu erfassen. Das Ergebnis wird gespeichert. Dann wird der aktuelle Status vom Port in das Referenzbyte kopiert und dient bei der nächsten Portabfrage als Referenz. Nun können die Bits mit dem Status "1" gezählt werden und beim Erreichen des Zählerstandes von 255 der Alarm ausgelöst werden. Jetzt noch einen quittierbaren Speicher für den Alarm programmieren, fertig. Wichtig zur Lösung einer Aufgabe ist, das man sie versteht. Aufgrund der vielen Deutungen und Vermutungen kann man dem Aufgabensteller mal locker ein "mangelhaft" verpassen. Auch ich bin mir nicht so sicher, das mein Lösungsansatz richtig ist. Gruß oldmax
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.