Hallo Leute,
ich hab eine kurze Frage,
ich bin auf der Suche nach den korrekten schreibweisen von:
Bitshifting:
PORTB |= (1<<5); <--- ist klar
PORTB &=~(1<<5); <--- auch klar
outPorts (1,0b00000000) <--- unklar! wie kann ich hier das bitshiftung
machen?
outPorts (0,0b00000000) <--- unklar! wie kann ich hier das bitshiftung
machen?
die 1, oder 0, für die pins sagen mir zwar wofür sie stehen, aber das:
outPorts0 |=...
outPorts1 &=...
funktioniert nicht.
vielleichtw eiß es ja jemand von euch.
danke
lg sven
Ganz ehrlich - lern halt vernünftig programmieren und greife nicht auf
Libraries zurück die du nichtmal bedienen kannst. Im Normalfall greift
man darauf zurück, wenn man die Library selbst programmieren kann. Alles
andere ist Gemurkse das keiner braucht.
Sven Weinmann schrieb:> outPorts ist eine Portbezeichung in meinem Script
Dann sollte die richtige Verwendund dort auch beschrieben sein.
Ansonsten hast du da Altpapier...
sry dass wird mir irgendwie zu bunt....
ich bestell mir ne port erweiterungs platine für mein myAVR board MK2.
dieses stecke ich an mein board und schaue auf deren homepage nach wie
man die ports anspricht.
finde ein beispielscript und versuche mich einzulesen.
sry dass ich zu doof bin zu sehen, dass das A aus einer lib stammt und B
ich nur mit altpapier hantiere.
Sven Weinmann schrieb:> sry dass wird mir irgendwie zu bunt....>> ich bestell mir ne port erweiterungs platine für mein myAVR board MK2.> dieses stecke ich an mein board und schaue auf deren homepage nach wie> man die ports anspricht.>> finde ein beispielscript und versuche mich einzulesen.>> sry dass ich zu doof bin zu sehen, dass das A aus einer lib stammt und B> ich nur mit altpapier hantiere.
Fällt dir was auf?
Bis zu diesem Zeitpunkt hast du kein Wort über deine Porterweiterung
fallen gelassen.
Es wäre hilfreich, wenn du uns darüber informieren würdest, um welche es
sich dabei handelt. Und wo man darüber Informationen findet.
Aber gleich die Flinte ins Korn werfen hat noch nie was gebracht.
Sven Weinmann schrieb:> outPorts (1,0b00000000) <--- unklar! wie kann ich hier das bitshiftung> machen?> outPorts (0,0b00000000) <--- unklar! wie kann ich hier das bitshiftung> machen?
Diese Funktion ist nicht standard C.
Also muß die jemand zur Verfügung stellen und derjenige muß sie auch
dokumentiert haben.
Wenn nicht, dann hat er seine Arbeit nicht gemacht, sondern nur Mist.
Peter
im dritten beitrag stehts drin.
ich habe folgende erweiterung:
http://shop.myavr.de/Add-Ons%20und%20Module/myTWI%20PortExpander.htm?sp=article.sp.php&artID=200000
und die hab ich sogar 2x... wobei ich derzeit nur eine zum laufen
bekommen habe, weil ich mich noch nicht mit der TWI addressierung
auskenne.
ich spreche in meinem script die ports derzeit so an:
outPorts(0,0b10000100);
ich möchte aber nicht immer das ganze bit ansprechen sondern nur einen
pin, daher die form der bitmanipulation.
warum ich nur den header eingebunden hab liegt daran, dass mein script
schon ultra lang ist...
dachte das du das wolltest
@peter: vor dem komma steht der angesprochene port auf der karte, nach
dem komma das bitmuster!
Peter Dannegger schrieb:> Sven Weinmann schrieb:>> outPorts (1,0b00000000) <--- unklar! wie kann ich hier das bitshiftung>> machen?>> outPorts (0,0b00000000) <--- unklar! wie kann ich hier das bitshiftung>> machen?>> Diese Funktion ist nicht standard C.>> Also muß die jemand zur Verfügung stellen und derjenige muß sie auch> dokumentiert haben.> Wenn nicht dann hat er seine Arbeit nicht gemacht, sondern nur Mist.>> Ich vermute mal, das erste Argument bedeutet setzen/löschen und das> zweite ist nicht die Bitnummer, sondern die Bitmaske. Man kann dann wohl> auch mehrere Bits beeinflussen.>>> Peter
1
voidoutPorts(uint8_tportNr,uint8_tdata);
Ich rate mal:
Mit "PortNr" wird einer der Ausgangsports (vermutlich 8 Bit breit)
adressiert.
Das mit "data" übergebene Byte wird dann an diesem Port "angezeigt".
ja das ist richtig.
nur wie gesagt ich will ja nicht immer das ganze bit ansprechen sondern
die einzelnen pins
simultan zu z.b. dieser form:
PORTB |= (1<<5);
Sven Weinmann schrieb:> @peter: vor dem komma steht der angesprochene port auf der karte, nach> dem komma das bitmuster!
Dann kannst Du nicht einzelne Bits setzen, sondern immer das komplette
Byte.
Leg Dir eine Schattenvariable an, manipuliere dort das Bit und sende
sie.
Peter
Sven Weinmann schrieb:> @peter: vor dem komma steht der angesprochene port auf der karte, nach> dem komma das bitmuster!
Du musst die Daten, die an den Port geschickt werden mit einer Variablen
Puffern:
1
outPort(0,var);
"var" ist eine bytebreite Variable (unsigned char).
Die kannst du bitweise verändern und musst sie dann als ganzes per
outPort an deine Erweiterungkarte schicken.
d.h.
char var = 00000000;
anweisung -> var |= (1<<0);
bedeutet das, dass nun das 1 bit in var auf 1 gesetzt wird
und gleichzeitig in der ausgabe outPort(0, var);
dies steht:
outPort(0, 0b00000001);
?
Sven Weinmann schrieb:> d.h.>> char var = 00000000;>> anweisung -> var |= (1<<0);>> bedeutet das, dass nun das 1 bit in var auf 1 gesetzt wird>> und gleichzeitig in der ausgabe outPort(0, var);>> dies steht:>> outPort(0, 0b00000001);>> ?
ja
Sven Weinmann schrieb:> ja das funktioniert! supier. wieder was gelernt
Und beim nächsten Mal bitte die Frage so stellen, dass auch jemand
darauf antworten kann, der weder im Besitz einer Kristallkugel ist, noch
in deinen Kopf gucken kann.
> PORTB |= (1<<5); <--- ist klar> PORTB &=~(1<<5); <--- auch klar> outPorts (1,0b00000000) <--- unklar!> wie kann ich hier das bitshiftung machen?
Gar nicht.
> outPorts (0,0b00000000) <--- unklar!> wie kann ich hier das bitshiftung machen?
gar nicht.
> outPorts0 |=...> outPorts1 &=...> funktioniert nicht.
Natürlich nicht, outPorts liefert keinen L-value.
Du musst mit diesen missglückten I/O-Funktionen schon
outPorts (1, readPorts(1) | (1<<5) );
outPorts (1, readPorts(1) & ~(1<<5) );
schreiben, mit dem Nachteil, daß die Operation damit
nicht-atomar ist und erheblich (ca. 20x) länger dauert.
STK500-Besitzer schrieb:> Du musst die Daten, die an den Port geschickt werden mit einer Variablen> Puffern:
Was spricht gegen outPort(0, (1<<0));
Bei einem optimierenden Compiler wird wahrscheinlich ohnehin beides
denselben Code erzeugen.
Lukas K. schrieb:> STK500-Besitzer schrieb:>> Du musst die Daten, die an den Port geschickt werden mit einer Variablen>> Puffern:> Was spricht gegen outPort(0, (1<<0));
Das es nicht das tut, was der TO möchte.
Nämlich den Pin 0 und nur diesen einen Pin auf 1 setzen.
Lukas K. schrieb:> Was spricht gegen outPort(0, (1<<0));> Bei einem optimierenden Compiler wird wahrscheinlich ohnehin beides> denselben Code erzeugen.
Wenn man nur das eine Bit setzen will, dann sollte das so gehen.
Wenn allerdings schon andere Bits gesetzt sind, werden die durch diese
Aktion gelöscht.
Genau das war Svens Problem.
Lukas K. schrieb im Beitrag #2622337:
> Karl Heinz Buchegger schrieb:>> Das es nicht das tut, was der TO möchte.>> Nämlich den Pin 0 und nur diesen einen Pin auf 1 setzen.> Das macht das Beispiel vom STK500-Besitzer auch. Darum ging's mir.
Wo? Welches Beispiel?
STK500-Besitzer schrieb:> Lukas K. schrieb:>> Was spricht gegen outPort(0, (1<<0));>> Bei einem optimierenden Compiler wird wahrscheinlich ohnehin beides>> denselben Code erzeugen.>> Wenn man nur das eine Bit setzen will, dann sollte das so gehen.> Wenn allerdings schon andere Bits gesetzt sind, werden die durch diese> Aktion gelöscht.> Genau das war Svens Problem.
Dein Beispiel in
Beitrag "Re: Schreibweisen" löscht
auch alle anderen Bits.
ja aber
"var" kann ich ja manipulieren wie ich es will!
und danach übergebe ich das manipulierte an das byte
kann mir denn wer sagen, wie ich ein wort in eine variable schreibe?
irgendwie geht das garnicht....
ich würde gerne das wort PORTB nicht den PORTB in eine variable
schreiben.
da ich diesen ersetzen kann und werde gehts mir drum, dass es in ner
variablen steht.
Lukas K. schrieb im Beitrag #2622337:
> Karl Heinz Buchegger schrieb:>> Das es nicht das tut, was der TO möchte.>> Nämlich den Pin 0 und nur diesen einen Pin auf 1 setzen.> Das macht das Beispiel vom STK500-Besitzer auch. Darum ging's mir.
Dann redest du aber von etwas anderem.
Auf den Satz
> Du musst die Daten, die an den Port geschickt werden mit einer Variablen> Puffern:
ist die Frage
> Was spricht gegen outPort(0, (1<<0));
reichlich sinnfrei. Denn genau das soll und will er ja nicht tun.
Sven hat in seiner etwas ungeschickten Ausdrucksweise lediglich
nachgefragt, ob die Sequenz
var |= 1 << 0;
outport( 0, var );
(mit der Annahme, dass var ursprünglich 0 war) dann auch tatsächlich
eine 0x01 an den Port legen würde. Da gehts aber um etwas anderes, denn
var |= 1 << 0;
outport( 0, var );
var |= 1 << 1;
outport( 0, var );
sorgt dafür, dass beim 2.ten outport dann auch tatsächlich ein Bitmuster
ausgegeben wird, in dem beide Bits gesetzt sind.
Sven Weinmann schrieb:> ich würde gerne das wort PORTB nicht den PORTB in eine variable> schreiben.
PORTB ist durch die AVRlibC schon vorbesetzt.
Da es sich um ein Makro handelt, wird es groß geschrieben (eshat sich so
eingebürgert, dass Makronamen groß geschrieben werden).
Deine Variable kannst du "portB" oder so nennen.
also ich versteh das so:
outports kann ich nicht bitmanipulieren, ohne alle eventuell gesetzten
bits zu überscheiben.
var kann ich manipulieren und übergebe nach manipulation var an outports
als fertige bitmaske
ich muss vll anmerken, ich hab sozusagen 8 taster, die ich an ud
ausschalten kann wie ich will, es soll jeder schalter egal wann
geschaltet werden und nicht immer das vorige überschrieben werden (ich
mein natürlich taster)
@STK500-Besitzer
das hab ich verstanden.
aber ich will ja nicht eine variable so nennen, ich will eine variable
mit dem wort PORTB füllen.
bspl:
PORTB = 0xFF.
nun will ich aber den ganzen port umschalten können auf einen anderen,
wert ist schon vorgegeben.
PORTB = 0xFF ----> PORTC = 0xFF
nur als bspl
Sven Weinmann schrieb:> also ich versteh das so:>> outports kann ich nicht bitmanipulieren, ohne alle eventuell gesetzten> bits zu überscheiben.
richtig.
outport ist (scheinbar) eine Funktion, die immer alle Bits setzt. Das
kannst du erst mal nicht beeinflussen. Maximal könnte man sich die
Funktion ansehen und überlegen, ob man da nicht was daraus machen kann.
Aber dazu müsstest du die Funktion zeigen.
> var kann ich manipulieren und übergebe nach manipulation var an outports> als fertige bitmaske
Genau. Das ist zb. ein möglicher Workaround um das Problem, dass du mit
outports nur den Port als ganzes ansprechen kannst.
Sven Weinmann schrieb:> da ich diesen ersetzen kann und werde gehts mir drum, dass es in ner> variablen steht.
Zeiger heißt Zauberwort.
1
uint8_t*ptr;
2
ptr=&PORTB;
3
ptr=123;//schreibt was auf PORTB
4
ptr=&PORTA;
5
ptr=137;//schreibt was auf PORTA
Sven Weinmann schrieb:> "var" kann ich ja manipulieren wie ich es will!
Ḱannst du bei MaWins Code auch.
Karl Heinz Buchegger schrieb:> reichlich sinnfrei. Denn genau das soll und will er ja nicht tun.
Ich nahm das Beispiel zu
Sven Weinmann schrieb:> char var = 00000000;> var |= (1<<0);> outPort(0, 0b00000001);
wörtlich, denn in dem Fehlte das Lesen mittels readPort.
Sven Weinmann schrieb:> aber ich will ja nicht eine variable so nennen, ich will eine variable> mit dem wort PORTB füllen.
PORTB ist kein 'Wort'.
PORTB ist schon direkt 'der Briefkasten' in den du Briefe einwerfen oder
aus dem du Briefe rausholen kannst.
> nun will ich aber den ganzen port umschalten können auf einen anderen,> wert ist schon vorgegeben.>> PORTB = 0xFF ----> PORTC = 0xFF
Was genau willst du da jetzt machen?
PORTB = PORTC;
PORTC = PORTB;
all das ist zulässig. Für dich ist PORTB oder auch PORTC
programmtechnisch wie eine 'Variable'. Weist du an die Variable Werte
zu, dann hat diese Variable diesen Wert. Nur eben greift ein Sonderfall,
dass nämlich diese 'Variable' für doch magisch mit ein paar nach aussen
führenden Leitungen verbunden ist. Aber als C-Programmierer verhält sich
PORTB im Grunde wie eine Variable.
Du hast ja auch keine Hemmungen zu schreiben
uint8_t i;
uint8_t j;
j = 5;
i = j;
ist genau dasselbe, nur mit dem UNterschied, dass es die 'Variable'
PORTB schon gibt ohne dass du sie erzeugen musst.
s_Effekt[0]=0b00111111;// gespeicherte Effekte Kanal 1
4
s_Effekt[1]=0b00010100;// gespeicherte Effekte Kanal 2
5
s_Effekt[2]=0b00010000;// gespeicherte Effekte Kanal 3
6
s_Effekt[3]=0b00001100;// gespeicherte Effekte Kanal 4
7
s_Effekt[4]=0b00011100;// gespeicherte Effekte Kanal 5
8
s_Effekt[5]=0b00000100;// gespeicherte Effekte Kanal 6
9
s_Effekt[6]=0b00001100;// gespeicherte Effekte Kanal 7
10
s_Effekt[7]=0b00010100;// gespeicherte Effekte Kanal 8
11
12
eff_Port=s_Effekt[i-1];// Zuweisung Kanal und Effektbänke
das ist natürlich nur ein auszug.
die variable mit dem namen eff_port ist derzeit durch define mit PORTB
"gefüllt"
aber ich will da z.b. nun meine outports ansprechen
aber define nimmt outports natürlich nicht als name, weil die lib das
nicht kennt!
daher dachte ich an eine ganz normale variable, die man mit buchstaben
füllen kann, ohne dass der µC direkt an eine funktion o.ä. denkt
Sven Weinmann schrieb:> die variable mit dem namen eff_port ist derzeit durch define mit PORTB> "gefüllt"
Das ist sie ganz sicher nicht.
Bitte erfinde nicht deine eigenen Begriffe. Sonst kennt sich nämlich
kein Mensch mehr aus.
Ein #define macht etwas ganz anderes. Mit einem #define hast du nur eine
Textersetzung vereinbart.
Du schreibst
eff_Port = s_Effekt[i-1];
und durch das #define
#define eff_Port PORTB
wird der Präprozessor angewiesen enie Textersetzung zu machen, so wie du
das auch in deinem Editor mit Suchen&Ersetzen machen könntest.
Der Präprozessor ersetzt den Text "eff_Port" durch den Text "PORTB".
Damit steht dann da
PORTB = s_Effekt[i-1];
und erst dieses modifizierte Programm wird an den eigentlichen Compiler
zur Bearbeitung übergeben.
ok ganz langsam....
ja STK500-Besitzer klar hast du recht!
aber
-->outPort<-- (0, s_Effekt[i-]);
soll z.b. auch mal durch PORTB erstz werden und zwar nicht hardcoded!
Sven Weinmann schrieb:> ok ganz langsam....>> ja STK500-Besitzer klar hast du recht!>> aber>> -->outPort<-- (0, s_Effekt[i-]);>> soll z.b. auch mal durch PORTB erstz werden und zwar nicht hardcoded!
Das geht so erst mal nicht.
Aber: Wo ein Wille da auch ein Weg. Mit etwas Makro-Magie ist auch das
möglich.
1
#define OUTPUT_BYTE(x) ......
anstelle der ...... muss jetzt was stehen, damit x eben an PORTB
ausgegeben wird
1
#define OUTPUT_BYTE(x) PORTB = x
und wenn stattdessen die Erweiterung benutzt werden soll, dann gestaltet
sich das Makro eben so
1
#define OUTPUT_BYTE(x) outPort( 0, x )
In der Verwendung ist es dann tatsächlich immer gleich.
1
intmain()
2
{
3
....
4
5
OUTPUT_BYTE(s_Effekt[i-]);
6
....
7
}
und nur dadurch, welches Makro aktiv ist, ersetzt der Präprozessor
diesen Text einmal zu
1
intmain()
2
{
3
....
4
5
PORTB=s_Effekt[i-];
6
....
7
}
und ein anderes mal ersetzt er diesen Text zu
1
intmain()
2
{
3
....
4
5
outPort(0,s_Effekt[i-]);
6
....
7
}
genau wie gewünscht.
Aber: Das sind alles nur Textersetzungen. Nicht mehr. Da steckt keine
Magie dahinter oder das irgendwas an irgendetwas anderes gebunden wird
oder wie auch immer. Einfache Textersetzungen, so wie du sie in deinem
Editor auch machst. Text "A" wird durch Text "B" ersetzt.
#define A B
PS: Du brauchst ganz dringend ein C-Buch. Du hast du ein paar fiese
Denkfehler in ganz einfachen Basisgrundlagen.
Karl Heinz Buchegger schrieb:> outport ist (scheinbar) eine Funktion, die immer alle Bits setzt. Das
wieso scheinbar?
Sven Weinmann schrieb:> void outPorts(uint8_t portNr, uint8_t data);
---
Sven Weinmann schrieb:> aber ich will da z.b. nun meine outports ansprechen
OutPorts kannst du nicht ansprechen!
Das ist eine Funktion, die etwas tut, und zwar das als data übergebene
Byte auf das mit portNr beschriebene I/O-Register befördern. Nicht mehr
und nicht weniger. Wie du portNr und data bereitstellst, bleibt dir
überlassen.
ok thx leute^^ ich geb mein bestes... aber wie sagte mein toller
lehrer... "wir landen erstmal mittendrin und dann könnt ihr euch das
selbst beibringen"....
Werner schrieb:> wieso scheinbar?
Weil es mit den gegebenen Infos keine endgültige Gewissheit darüber
gibt, was die Funktion mit "portNr" und "data" anstellt. Auch wenn es
höchstwahrscheinlich so ist, wie vermutet:
> Das ist eine Funktion, die etwas tut, und zwar das als data übergebene> Byte auf das mit portNr beschriebene I/O-Register befördern.
Sven Weinmann schrieb:> ich weiß garnicht wie was wo ich all die infos finden soll.
Spielt keine Rolle mehr.
> void outPorts(uint8_t port, uint8_t data)> {> twiStart();> twiWriteByte(0b01000000,1); // TWI-Adresse> twiWriteByte(0b00000010+port,1); // Kommandoregister 2/3 ->> Output P0/P1> twiWriteByte(data,0); //> }
die Zusatzports sind über TWI angebunden und damit fällt ein
Einzelbitzugriff flach.
Oder anders ausgedrückt: Diese Erweiterungsports werden vollkommen
anders angesprochen als die Ports, die der µC bereits On-Board mit hat.
Karl Heinz Buchegger schrieb:> die Zusatzports sind über TWI angebunden und damit fällt ein> Einzelbitzugriff flach.
Das muss nicht. Da schreibt man eine kleine Wrapper Funktion zum bit
Setzen oder Löschen und cached den Zustand in einer globalen Variable.
Aber der ganze thread hier tut so weh... AUA!
tut mir echt leid wenn hier dem ein oder anderen die augen ausfallen :(
das was ich kann ist denke mal verglichen recht wenig.
ich kann mein board programmieren:
ich kann mit ADC umgehen, kenne mit mit PWM´s aus und kann den EEprom
beschreiben und lesen.
für viel mehr war bisher wenig zeit.
dummerweise stand da nirgends was von TWI, weil ja auch alles über mein
board lief.
dann gingen mir die ports aus und ich hab die zusatzkarten gekauft. dort
versprach man mir es ginge alles so einfach...
naja dem ist garnicht so.
twi ist wieder ein fall für sich (zumindest für mich) und so entstehen
neue probleme.
ich lerne kein C in der schule, was ich gerne täte, ich lerne wie man
dem lehrer über die schulter sieht, wie er HIER im forum nach antworten
sucht.....
Ralph schrieb:> Hier hilft nur der gute alte Ansatz RMW> Read - Modify - Write>> also:>> temp = readPorts(xx)>> temp |= (1<<5);>> temp &=~(1<<5);>> outPorts(xx, temp)
Und mit readPort ist mit Sicherheit ein Auslesen des AUSGANGSZUSTANDES
gemeint?
Alleine schon der Kommentar im Programmcode lässt darauf schließen, dass
es sich dabei um eine Einlesefunktion der Portpins handelt, also das
einlesen eines EINGANGSZUSTANDES des Ports.
marcus6100 schrieb:> Karl Heinz Buchegger schrieb:>>> die Zusatzports sind über TWI angebunden und damit fällt ein>> Einzelbitzugriff flach.>> Das muss nicht. Da schreibt man eine kleine Wrapper Funktion zum bit> Setzen oder Löschen und cached den Zustand in einer globalen Variable.>> Aber der ganze thread hier tut so weh... AUA!
Die Wrapperfunktion wäre gar nicht so falsch, erfüllt aber auch nicht
den Zweck, dass man einfach den auszugebenen Wert einer Variablen
zuweist, wie oben "gefordert".
Die Geschichte ist doch soweit abgeschlossen, oder?
Sven Weinmann schrieb:> tut mir echt leid wenn hier dem ein oder anderen die augen ausfallen :(>> das was ich kann ist denke mal verglichen recht wenig.>> ich kann mein board programmieren:> ich kann mit ADC umgehen, kenne mit mit PWM´s aus und kann den EEprom> beschreiben und lesen.>> für viel mehr war bisher wenig zeit.>> dummerweise stand da nirgends was von TWI, weil ja auch alles über mein> board lief.> dann gingen mir die ports aus und ich hab die zusatzkarten gekauft. dort> versprach man mir es ginge alles so einfach...> naja dem ist garnicht so.
Da hast das leidige Problem aller, die mit Computerprogrammierung
anfangen. Du sollst gleichzeitig
* eine Programmiersprache lernen
* Algorithmen lernen
* die Möglichkeiten deiner Hardware lernen
* grundsätzliche Lösungsstrategien lernen
* In C dann auch noch den Gebrauch des Präprozessors lernen
* Auf µC in Binäre und Hex-Schreibweisen reinkommen und auch verstehen
wie eigentlich Zahlensysteme generell funktionieren.
* Speziell hier die im Alltag oft falsch benutzten 'Operationen'
UND und ODER korrekt anwenden.
Wir verstehen schon, dass das alles etwas viel auf einmal ist. Das war
es für uns auch. Da heißt es nur: drannbleiben, viel üben, viel lesen.
> ich lerne kein C in der schule, was ich gerne täte, ich lerne wie man> dem lehrer über die schulter sieht, wie er HIER im forum nach antworten> sucht.....
Kauf dir ein C-Buch. Das ist aus meiner Sicht einer der wichtigsten
Punkte. Die Programmiersprache ist dein Handwerkszeug, so wie Hammer und
Meißel die Handwerkszeuge eines Bildhauers sind. Der perfekte Umgang mit
seinem Handwerkszeug ist Grundvoraussetzung für alles Weitere.
Unsystematisches Lernen einer Programmiersprache dauert nicht nur
länger, man lernt sich auch oft falsche Dinge ein, die man dann später
mühsam (in der Denkweise) korrigieren muss. Abgesehen davon, kannst du
dir in Foren bestenfalls anlassbezogenes Viertelwissen
zusammenschnorren. Und das ist nicht sehr hilfreich. Besser und auch
einfacher ist es, wenn dich ein Lehrbuch systematisch durch die
einzelnen Themenkreise führt. So ein Buch ist in erster Linie für dich
nicht Nachschlagwerk (irgendwann wird es dazu), sondern Lehrer.
gibt es denn irgendwelche empfehlungen diesbezüglich?
ich hab schon so einige rezessionen gelesen und da spalten sich ja die
köppe gewaltig....
gibts irgendwas wie ne eierlegende wollmilchsau?
Sven Weinmann schrieb:> ich hab schon so einige rezessionen gelesen und da spalten sich ja die> köppe gewaltig....
Kernighan und Ritchie "Programmieren in C: Mit dem C-Reference Manual in
deutscher Sprache"
Inzwischen sollte die deutsche Ausgabe lesbar und richtig sein.
"C für Dummies"
STK500-Besitzer schrieb:> Und mit readPort ist mit Sicherheit ein Auslesen des AUSGANGSZUSTANDES> gemeint?> Alleine schon der Kommentar im Programmcode lässt darauf schließen, dass> es sich dabei um eine Einlesefunktion der Portpins handelt, also das> einlesen eines EINGANGSZUSTANDES des Ports.
Ich denke da hast du recht. RMW ist nicht brauchbar.
> Die Wrapperfunktion wäre gar nicht so falsch, erfüllt aber auch nicht> den Zweck, dass man einfach den auszugebenen Wert einer Variablen> zuweist, wie oben "gefordert".
ganz so schön wie oben gefordert kann man es auch mit einer Wrapper
funktion nicht machen, aber man kommt nahe dran. Beispiel:
void writePort(uint8_t portNr, uint8_t bitsToSet, uint8_t bitsToClear);
writePort(0, (1 << 7), 0); // port 0, bit 7 setzen
writePort(0, 0, (1 << 3)); // port 0, bit 3 löschen
writePort(0, (1 << 5), (1 << 6)); // port 0, bit 5 setzen, bit 6
löschen
Achtung der allererste Schreibzugriff initialisiert mit Nullen in alle
nicht explizit gesetzten bits.
#define MAX_PORTS 2
static uint8_t gPortState[MAX_PORTS];
void
writePort(uint8_t portNr, uint8_t bitsToSet, uint8_t bitsToClear)
{
gPortState[portNr] &= (uint8_t)~bitsToClear;
gPortState[portNr] |= bitsToSet;
outPorts(portNr, gPortState[portNr]);
}
STK500-Besitzer schrieb:> noch umständlich geht's wohl nicht, oder?
Umständlich? Bei einer Wrapper Funktion mit 3 Zeilen und einer einzigen
statischen Variable?
Das macht die Benutzung der zusätlichen ports extrem simpel, ohne das
man sich im Programm immer um alle Bits gleichzeitig kümmern muss.
z.B.
#define LED_ROT (1 << 7)
#define LED_BLAU (1 << 6)
writePort(0, LED_ROT, 0); // port 0, rote LED an
writePort(0, 0, LED_BLAU); // port 0, blaue LED aus
Mach doch mal einen besseren Vorschlag.