Hallo,
ich möchte gerne den Zustand bestimmter PINs meines µControllers
(ATmega8) abfragen. Die Eingänge sind Hardwareseitig durch Pull-Up
Widerstände auf Vcc gezogen. Also ich möchte gerne wissen wann ein 0 an
den jeweiligen PINs anliegt!
kann ich das so machen?
Andreas schrieb:> kann ich das so machen?
Nein. Erstmal nicht PORTB sondern PINB. Und wenn ich das richtig
verstehe, willst du die Zahl vom Port einlesen. Mit deiner Methode
fragst du aber genau 2 Zustände ab: true oder false.
Dadurch daß die Ports nebeneinander liegen kannst du das ganz einfach
machen:
zahl = PINB & 0x07;
Wäre das jetzt nicht so, müsstest du noch ein bischen Bitgefriggel
veranstalten.
mfg.
> Andreas schrieb:> Nein. Erstmal nicht PORTB sondern PINB.
Also so:
1
if(PINB&(1<<PB0)&(1<<PB1)&(1<<PB2))
2
Zahl=0;
Das Problem ist folgendes: Ich möchte aus 4 nebeneinander stehenden PINs
eines PORTes mittels BCD-Codierung einen Zahl zwischen 0 und 9
generieren!
Bin für jede Hilfe Dankbar!
PINB gibt dir den Zustand des kompletten Ports, also 8 bit.
PINB & (1<<PB0 | 1<<PB1 | 1<<PB2 | 1<<PB3) erzeugt eine Maske (die
oder-Verknüpfungen). Wenn man nun PINB mit dieser Maske und-Verknüpft,
dann bleiben nur noch die bits übrig, die den 4 Pins entsprechen. Alle
anderen bits sind garantiert auf 0.
Nun musst Du nur noch bitweise negieren, da ja deine Eingänge Low-Aktiv
sind. D.H. aus 0000 wird 1111 = 0, 1110 wird 0001 = 1 .... Mit anderen
Worten diese 4 bit entsprechen genau dem Wert, den du umständlich mit
if-Anweisungen ermitteln wolltest.
Zahl = ~PINB & (1<<PB0 | 1<<PB1 | 1<<PB2 | 1<<PB3)
Jetzt hast Du als Ergebnis direkt die Zahl zwischen 0 und 15. Wenn Du
nur 0-9 brauchst, dann musst Du Dir halt weiter überlegen:
* kann ein solcher Wert überhaupt anliegen? 0101 - 0000
* wenn ja, was soll dann passieren? Fehlerbehandlung?
Andreas schrieb:> if (PINB & (1<<PB0) & (1<<PB1) & (1<<PB2))> Zahl = 0;
Nein, so wird das nichts. So wird zahl auf 0 gesetzt, wenn alle Pins
high sind. Ist irgendeiner low, passiert gar nichts.
Wenn du 4 Pins hast und Zahlen von 0 bis 9 erhalten willst, ist das egal
ob BCD oder binär. BCD wird erst bei mehreren Stellen interessant.
Allerdings kannst du mit 4 Bit von 0 bis 15 zählen. Bei >9 brauchst du 2
BCD-Stellen.
zahl = PINB & 0x0F;
char bcd0, bcd1;
bcd0 = zahl % 10;
bcd1 = zahl / 10;
mfg.
Richtiger ist natürlich :o)
D.H. aus 1111 wird 0000 = 0, 1110 wird 0001 = 1 ....
Was legt denn diese BCD-Zahl an dem Port an?
Ein Logik-Gatter mit BCD-Ausgang? Ein BCD Encoder?
BCD bedeutet 4 bit ergeben eine Ziffer. Wieviele Ziffern? Wenn die
oberen 4 bit des Ports die Zehner-Stelle einer BCD enthalten, dann geht
man genauso vor, wie bei der Einer-Stelle, muss nur das Ergebnis nochmal
schieben und multiplizieren:
Zahl = ~PINB & (1<<PB0 | 1<<PB1 | 1<<PB2 | 1<<PB3)
oder
Zahl = ~PINB & 0x0f
das ist das selbe!
Zahl += (~PINB & 0xf0)>>4 * 10
~PINB & 0xf0 maskiert die bits aus, die für die zehner-stelle gebraucht
werden.
>>4 schiebt diese 4 bits dann in den Bereich, wo sie den Wert 0-15 haben
*10 macht dann aus den Werten 0-9 eine 0-90 - eben eine Zehner-Stelle.
War mir nur so in den Kopf gekommen ... vielleicht interessiert es ja
jemanden ;o)
MagIO schrieb:> Was legt denn diese BCD-Zahl an dem Port an?> Ein Logik-Gatter mit BCD-Ausgang? Ein BCD Encoder?
Also ich habe 3 BCD-Kodierschaltern mit denen ich den Zahlenbereich 0 -
512 abdecken soll!
1. BCD-Kodierschalter >> Einer Stelle
2. BCD-Kodierschalter >> Zehner Stelle
3. BCD-Kodierschalter >> Hunderter Stelle
Zur Verfügung stehen folgende Ports:
PORT-D >> 3 bis 7
PORT-B >> 0 bis 5
Das reicht gerade so, weil ich
4 Pins für BCD-Kodierschalter 1 brauche (Zahlenbereich 0 - 9)
4 Pins für BCD-Kodierschalter 2 brauche (Zahlenbereich 0 - 9)
3 Pins für BCD-Kodierschalter 3 brauche (Zahlenbereich 0 - 5)
Aus der 3 Schaltern muss eine Ziffer zustande kommen. Am besten ein
Ziffer der Datentyp Integer.
MagIO schrieb:> Zahl += (~PINB & 0xf0)>>4 * 10
Was sagt mit das += ?
vielen vielen Dank für euer Hilfe :)
Na im ersten Statement wurde die Einerstelle 'berechnet' und mit = der
Variablen Zahl zugewiesen. Die Zeile mit += addiert dann die
Zehnerstelle dazu.
Musst halt in Deinem Falle die Einer-Stelle auf PORTB Pins 0-3 legen,
die Zehner-Stelle auf PORTD Pins 4-7 legen und die Zeile entsprechend
ändern in:
Zahl += (~PIND & 0xf0)>>4 * 10
Und dann brauchst Du noch ne weitere Zeile für die 100er Stelle.
Aber die bekommst Du ja sicher selbst hin. Das Muster ist das gleiche:
invertieren, maskieren, bits hinschieben, wo sie hin müssen und
malnehmen mit der Wertigkeit der entsprechenden Stelle.
Wobei es bei der 3. Stelle schon Sinn macht, den Wert erst mal zu
überprüfen, sonst kann man hier durchaus auch ne 7 eingeben.
Andreas schrieb:> MagIO schrieb:>> Zahl += (~PINB & 0xf0)>>4 * 10>> Was sagt mit das += ?
Vor allen Dingen sagt es uns, dass du ein C-Buch brauchst!
a += b;
ist dasselbe wie
a = a + ( b );
@Karl Heinz Buchegger:
"Vor allen Dingen sagt es uns, dass du ein C-Buch brauchst!"
Wieso müssen diese Seitenhiebe immer sein? Der Rest in dem Post hätte es
auch getan!
@MagIO
Antworte du so wie du das für richtig hältst und ich mach meine Linie
weiter. OK?
Hast du das Problem mit Jan schon gelöst?
So wie ich das sehe und verfolgt habe: eher nicht.
Und das liegt nicht daran, dass es unmöglich zu lösen ist, sondern
daran, dass ihr nicht wahrhaben wollt, dass erst mal einen Gang
zurückschalten und mit den Basics anzufangen die sinnvollere Alternative
ist.
Wer zur Tour de France mit Stützrädern am Fahrrad antritt, wird vom
Veranstalter zu Recht nach Hause geschickt um erst mal seine
Hausaufgaben (aka. lerne Fahrradfahren) zu machen.
@ MagIO: Sehr nett! vielen vielen Dank! :)
Karl Heinz Buchegger schrieb:> Vor allen Dingen sagt es uns, dass du ein C-Buch brauchst!
Schreibt mal bitte ganz oben neben "www.mikrocontroller.net"
Diese Seite ist nur für "Profis"... Anfänger sind hier unerwünscht!
Andreas schrieb:> Diese Seite ist nur für "Profis"... Anfänger sind hier unerwünscht!
Profis wissen, wie man BCD-Zahlen dekodiert.
Aber von einem Anfänger kann man zumindest erwarten, daß er eine klare
Frage stellt bzw. sein Problem erläutert. Und nicht scheibchenweise
damit rüberkommt. Im ersten Post waren es 3 Eingänge, die abgefragt
werden sollten, im zweiten waren es dann 4 Eingänge und es sollte
BCD-kodiert werden. Jetzt sind es 11 Eingänge und es soll dekodiert
werden.
Hättest du das gleich geschrieben, hättest du heute vormittag noch deine
Lösung gehabt.
Aber jetzt habe ich da keine Lust mehr zu.
mfg.
Irgendwie hab ich den Eindruck ich bin im falschen Film.
Was erwartet ihr von einem Forum?
In einem Forum geht es nicht darum, jemandem die absoluten Grundlagen
beginnend bei 0 beizubringen. Dazu gibt es Bücher! Ist es wirklich so
viel verlangt, die 20 oder 30 Euro zu investieren und sich in einer
Buchhandlung ein Buch zu kaufen, welches dir den Stoff in geordneter
sinnvoller Folge beibringt, anstatt in einem Forum, dass aufgrund von
Platz und Darstellungsproblemen schon mal überhaupt nicht in der Lage
ist, dir das, was du in einem Buch auf 15 Seiten erklärt bekommst in 3
Sätzen beizubringen?
Die Regulars sehen hier jeden Tag wohin es führt, wenn sich Leute ihr
Viertelwissen (denn Halbwissen kann man das alles noch nicht mal nennen)
in Foren zusammenschnorren, anstatt dass sie die 20 Abende aufbringen
und sich in ihrem Buch einfach mal die ersten paar Kapitel reinziehen.
Im Endeffekt dauert dann alles x-mal so lange, als wenn derjenige
einfach mal seine Hausaufgaben gemacht hätte. Und hinten nach kommt nix
gscheites raus, wenn überhaupt etwas rauskommt (siehe: Jan)
> Diese Seite ist nur für "Profis"... Anfänger sind hier unerwünscht!
Das Forum heißt aber auch nicht: Grundschule für C-Programmierer. Macht
euch keine Sorgen, hier werden sie geholfen. Sie brauchen nix wissen,
wir erledigen alles für sie.
Auch einem Anfänger ist zuzumuten, dass er sich erst mal auf eigene
Faust mit Grundlagenwissen versorgt! Wenn er dann Fragen dazu hat,
gerne, immer her damit. Aber erst mal muss er in die Vorleistung gehen
und lernen.
Die Profis sind Profis geworden, weil Literatur lesen zu ihrem Alltag
gehört hat! Durch Fragen in einem Forum ist noch nie jemand zu einem
Profi geworden. Dazu reicht deine Lebenszeit nämlich nicht aus.
Und selbst wenn das gar nicht angestrebt wird (was ok ist), gehört
ausreichende Grundlagenliteratur selbst für einen Amateur mit dazu.
Kaufst du dir halt an 3 Freitagen jeweils 1 Bier in der Diso weniger und
du hast die Kosten für ein Buch herinnen. Und am Anfang bist du mit
einem Buch völlig ausreichend versorgt, in dem man auch mal etwas
nachschlagen kann.
Andreas schrieb:> Schreibt mal bitte ganz oben neben "www.mikrocontroller.net"> Diese Seite ist nur für "Profis"... Anfänger sind hier unerwünscht!
Das hier ist das Forum
>Für alle Fragen rund um Mikrocontroller und Elektronik.
Die allereinfachsten Grundlagen der Syntax irgend einer
Programmiersprache gehören wohl nicht dazu. Dafür gibt es a) Bücher oder
b) andere Foren.
Oliver
@Karl Heinz:
ich kann Dir teilweise zustimmen. Allerdings war die Frage nach dem +=
so in etwa "bin zu faul, google anzuwerfen". Das ist es, was mich
persönlich an solchen Fragen stört.
Klar ist ein Buch optimal, aber auch im Internet gibt es ja zahlreiche
Quellen für die C-Grundlagen.
High Performer schrieb:> @Karl Heinz:>> ich kann Dir teilweise zustimmen. Allerdings war die Frage nach dem +=> so in etwa "bin zu faul, google anzuwerfen". Das ist es, was mich> persönlich an solchen Fragen stört.>> Klar ist ein Buch optimal, aber auch im Internet gibt es ja zahlreiche> Quellen für die C-Grundlagen.
Ich bin ja auf das += auch nur angesprungen, weil noch jeder der in
einem Kurs oder in der Literatur rausgefunden hat, dass es das gibt,
sofort darauf anspringt und ab sofort immer und überall auf Biegen und
Brechen ein += einsetzen will. Das war zu meiner Lernzeit auch nicht
anders :-)
Von daher kann man davon ausgehen, dass jeder der unter Anleitung lernt
+= kennt. Bzw. im Umkehrschluss: wer += nicht kennt, versucht sich auf
eigene Faust irgendwie durchzuschlagen. Und das geht zu99% in die Hose.
Wie auch immer.
Hast du jetzt verstanden, wo das Problem bei
1
if(PINB&(1<<PB0)&(1<<PB1)&(1<<PB2))
liegt?
(Denn das ist eine völlig legitime Anfängerfrage, gegen die nichts
einzuwenden ist. Bitverknüpfungen sind in den üblichen Büchern eher
stiefmütterlich behandelt)
Das Problem bei der ganze Sache ist, dass in meiner Schaltung der 2. BCD
Codierer auf Port-D und Port-B verteilt ist!
1 Kontakt geht auf PB7 und 3 Kontakte gehen auf PB0, PB1, PB2
kann man das so machen:
Andreas schrieb:> kann man das so machen:
Das kann man schon. Es kommt aber nichts Sinnvolles dabei raus...
Das kommt ja nicht mal der Compiler ohne Fehler durch!
Andreas schrieb:> kann man das so machen:
Mach das doch einfach mal selber im Simulator oder auf einem Blatt
Papier durch. So hätte ich das (habe ich das) seinerzeit gemacht. Diesen
(durchaus zeit- und nervenaufreibenden) Prozess nennt man Lernen...
Lothar Miller schrieb:> Mach das doch einfach mal selber im Simulator oder auf einem Blatt> Papier durch. So hätte ich das (habe ich das) seinerzeit gemacht. Diesen> (durchaus zeit- und nervenaufreibenden) Prozess nennt man Lernen...
Ich unterstütze diesen Vorschlag aufs wärmste.
Einfach mal ein Bitmuster für PIND und PINB annehmen (es ist vernünftig,
wenn du dir im Vorfeld überlegst, was das bedeutet und was dein Programm
damit herausbekommen müsste) und dann den Code durchspielen. Mein
Favorit ist dabei immer: Auf dem Papier durchspielen. Überlegt man
selbst, was da passiert und macht man die Verknüpfungen selber im Kopf,
dann bleibt da oft viel mehr Wissen und Verständnis hängen, als wie wenn
man nur irgendwelchen Anzeigen beim Wechseln zusieht.
Du wirst dazu das hier
http://www.swansontec.com/sopc.html
brauchen (C Operator Precedence Table).
Darin ist festgehalten, wie die Reihung der Operatoren ist. Also im
Grunde das, was du aus der Mathematik als Punkt vor Strich Regel kennst
und was regelt wie 2 * 3 + 5 auszuwerten ist. Die oberen Gruppen in
dieser Tabelle haben höhere Priorität. Innerhalb einer Gruppe wird von
links nach rechts ausgewertet.
Die Tabelle ist zb wichtig, weil irgendwie geregelt werden muss, welche
Argumente zb in
zusammengehören. So wie 2 * 3 + 5 als (2 * 3) + 5 oder als 2 * (3 + 5)
angesehen werden kann und die Punkt vor Strich Regel da eine klare
Auswahl aus den beiden Möglichkeiten trifft.
Man muss nicht alle Einträge dieser Operator Precedence auswendig
kennen. Aber ein paar wichtige sollten es schon sein und den Rest macht
man dann mit expliziten Klammern.
Karl Heinz Buchegger schrieb im Beitrag
> Man muss nicht alle Einträge dieser Operator Precedence auswendig> kennen. Aber ein paar wichtige sollten es schon sein und den Rest macht> man dann mit expliziten Klammern.
Und wenn man dann immer noch nicht durchblickt, dann kann man schon mal
so eine einzelne Zeile in 4 oder 5 Zeilen aufteilen. Der Compiler muss
das sowieso tun, da läuft nicht zwingend 1 Zeile 4 mal so schnell ab wie
4 Zeilen...
Und Andreas:
Weil du da oben so schön 'sinnlos' gesagt hast als Antwort auf den
Vorschlag sich ein C-Buch zuzulegen.
Ja, auch eine Operator-Precedence-Table samt zugehöriger Erklärung (und
noch viele hundert andere Dinge, die du als C-Programmierer wissen
musst) findet sich in jedem noch so grindigem C-Buch.
Die Betonung liegt dabei auf "noch viele andere hundert Dinge, die du
als C-Programmierer wissen musst". Du kannst dir viel Zeit und Nerven
sparen, wenn du den Prozess abkürzst, einfach in die Vorleistung gehst
und zu lesen anfängst.