Forum: Mikrocontroller und Digitale Elektronik 8051 Portabfrage und Interrupt auslösen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Dennis (Gast)


Bewertung
-3 lesenswert
nicht lesenswert
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!

von Peter D. (peda)


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

von Dennis (Gast)


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

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
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
von Dennis (Gast)


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

von Dennis (Gast)


Angehängte Dateien:

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

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Das ist nicht die Anzahl, sondern der Wert an dem Port, d.h. Du mußt den 
Wert vergleichen:
  if (P0 == 255)
    mache_was();
Bzw. in Assembler
  mov a, #255
  cjne a, p0, weiter
  call mache_was
weiter:

Einen Interrupt kann man dafür nicht verwenden.

: Bearbeitet durch User
von Stephan (Gast)


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

von Stephan (Gast)


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

von Dietrich L. (dietrichl)


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

von Peter D. (peda)


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

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
1 lesenswert
nicht lesenswert
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
von Stefan K. (stefan64)


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

von Stephan (Gast)


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

von Stephan (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Stefan K. schrieb:
> Die Anzahl der Einsen in einem Byte kann maximal 8 betragen.

Und wieviel macht das ?

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
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
von Wolfgang R. (Firma: www.wolfgangrobel.de) (mikemcbike)


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

von Stefan K. (stefan64)


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

von Stephan (Gast)


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

von Stefan K. (stefan64)


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

von Stephan (Gast)


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

von Stephan (Gast)


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

von Lothar M. (lkmiller) (Moderator) Benutzerseite


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

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Lothar M. schrieb:
> Wurde das mit Google aus Soumi übers Janpanische ins Französiche nach
> Deutsch übersetzt?

Diese Vermutung drängt sich geradezu auf.

von Peter (Gast)


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

von Lothar (Gast)


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

von Welch Narr (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Was passiert, wenn ich die 255 nicht treffe? Die "Einser" Addition kann 
darüber sringen. ;-)

von Lothar (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Welch Narr schrieb:
> Was passiert, wenn ich die 255 nicht treffe?

Jeder Zähler braucht einen Überlaufschutz ...

von Lothar M. (lkmiller) (Moderator) Benutzerseite


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

von Lothar (Gast)


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

von Peter D. (peda)


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

von Lothar (Gast)


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

von Oldmax (Gast)


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

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.