Forum: Mikrocontroller und Digitale Elektronik Schreibweisen


von Sven W. (sickone4)


Lesenswert?

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

von STK500-Besitzer (Gast)


Lesenswert?

Was steckt hinter  "outPorts"? Wo kommt der Ausdruck her?
Arduino?

von Sven W. (sickone4)


Lesenswert?

outPorts ist eine Portbezeichung in meinem Script

die outports sind auf eienr TWI port expander platine und so spricht man 
sie scheinbar an^^

von Lehrmann M. (ubimbo)


Lesenswert?

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.

von STK500-Besitzer (Gast)


Lesenswert?

Sven Weinmann schrieb:
> outPorts ist eine Portbezeichung in meinem Script

Dann sollte die richtige Verwendund dort auch beschrieben sein. 
Ansonsten hast du da Altpapier...

von Sven W. (sickone4)


Lesenswert?

ich würde halt gern an:

outPorts

die obere mir bekannte form anknüpfen, ich weiß nur nicht, wo ich die 1 
oder die 0 hinmachen soll....

von Sven W. (sickone4)


Lesenswert?

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.

von Lukas K. (carrotindustries)


Lesenswert?

Wenn du uns die Deklaration von outPorts verrätst (steht in den Headern 
drin), dann wird dir auch geholfen.

von Sven W. (sickone4)


Lesenswert?

mal kurz zur info:

das habe ich eingebunden
1
#define  F_CPU 3686400                            // CPU Takt, externer Quarz
2
#include <avr/io.h>                              // Einbinden der Bib io.h
3
#define  BAUD 9600                              // Baudrate = 9600
4
#include <util/delay.h>                            // Einbinden der Bib delay.h
5
#include <string.h>
6
7
//------------------------------------------------------------------------------------------------------------------
8
// TWI-Funktionssammlung
9
#ifndef TWI_CLOCK
10
#define TWI_CLOCK 100000                          // Geschwindigkeit des TWI-Busses
11
#endif
12
13
// TWCR - Control-Register-Bits
14
#define _TWINT 0b10000000
15
#define _TWEA  0b01000000
16
#define _TWSTA 0b00100000
17
#define _TWSTO 0b00010000
18
#define _TWWC  0b00001000
19
#define _TWEN  0b00000100
20
#define _TWIE  0b00000001
21
22
void    twiInitMaster(uint8_t twiAdr);
23
void    twiStart();
24
void    twiStop();
25
void    twiWriteByte(uint8_t data, uint8_t ackn);
26
uint8_t twiReadByte(uint8_t ackn);
27
void    twiInitPCA();
28
void    outPorts(uint8_t portNr, uint8_t data);
29
uint8_t readPorts(uint8_t portNr);

ich hab keine lib benutzt die ich nicht kenne....

von STK500-Besitzer (Gast)


Lesenswert?

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.

von STK500-Besitzer (Gast)


Lesenswert?

Ist das alles an Information?

von Peter D. (peda)


Lesenswert?

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

von Sven W. (sickone4)


Lesenswert?

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!

von STK500-Besitzer (Gast)


Lesenswert?

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
void    outPorts(uint8_t portNr, uint8_t data);

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".

von Sven W. (sickone4)


Lesenswert?

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);

von Peter D. (peda)


Lesenswert?

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

von STK500-Besitzer (Gast)


Lesenswert?

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.

von Sven W. (sickone4)


Lesenswert?

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);

?

von STK500-Besitzer (Gast)


Lesenswert?

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

von Sven W. (sickone4)


Lesenswert?

ja das funktioniert! supier. wieder was gelernt

von STK500-Besitzer (Gast)


Lesenswert?

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.

von Sven W. (sickone4)


Lesenswert?

hm naja ich glaub manchmal wär das sinnvoller....

od sinnfreier

von MaWin (Gast)


Lesenswert?

> 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.

von Lukas K. (carrotindustries)


Lesenswert?

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.

von J.-u. G. (juwe)


Lesenswert?

Lukas K. schrieb:
> Was spricht gegen outPort(0, (1<<0));

Dann würden Pins, die gesetzt sind und gesetzt bleiben sollen, gelöscht 
werden.

von Karl H. (kbuchegg)


Lesenswert?

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.

von STK500-Besitzer (Gast)


Lesenswert?

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.

von Sven W. (sickone4)


Lesenswert?

richtig

das war mein problem :)

sonst kann ich auch die ganze bitmaske hinschreiben

das wäre der gleiche effekt

von STK500-Besitzer (Gast)


Lesenswert?

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?

von Lukas K. (carrotindustries)


Lesenswert?

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.

von Sven W. (sickone4)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von STK500-Besitzer (Gast)


Lesenswert?

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.

von Sven W. (sickone4)


Lesenswert?

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)

von Sven W. (sickone4)


Lesenswert?

@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

von Karl H. (kbuchegg)


Lesenswert?

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.

von STK500-Besitzer (Gast)


Lesenswert?

Sven Weinmann schrieb:
> @STK500-Besitzer
>
> das hab ich verstanden.

ich dich dieses Mal wieder nicht.

von Lukas K. (carrotindustries)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Sven W. (sickone4)


Lesenswert?

:D

also

so sieht mein code aus:
1
char s_Effekt[8];
2
    
3
       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

von Karl H. (kbuchegg)


Lesenswert?

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.

von STK500-Besitzer (Gast)


Lesenswert?

1
outPort(0, s_Effekt[i-]);

ist das so schwer?

von Sven W. (sickone4)


Lesenswert?

ich hatte die zeile nun rausgelassen,
aber was tut das hier denn sonst??
1
#define eff_Port PORTB

von Sven W. (sickone4)


Lesenswert?

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!

von Karl H. (kbuchegg)


Lesenswert?

Sven Weinmann schrieb:
> ich hatte die zeile nun rausgelassen,
> aber was tut das hier denn sonst??
>
>
1
#define eff_Port PORTB


Siehe hier
Beitrag "Re: Schreibweisen"

von Karl H. (kbuchegg)


Lesenswert?

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
int main()
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
int main()
2
{
3
  ....
4
5
  PORTB = s_Effekt[i-];
6
  ....
7
}

und ein anderes mal ersetzt er diesen Text zu
1
int main()
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.

von Werner (Gast)


Lesenswert?

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.

von Sven W. (sickone4)


Lesenswert?

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"....

von J.-u. G. (juwe)


Lesenswert?

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.

von Sven W. (sickone4)


Lesenswert?

ich weiß garnicht wie was wo ich all die infos finden soll.

ich nehm man an es geht hier drum:
1
// twiInitPCA-------------------------------------------------------------------------------------------------------
2
//------------------------------------------------------------------------------------------------------------------
3
4
void twiInitPCA()
5
{
6
  // I/O Definition (A Eingang, B Ausgang)
7
  twiStart();
8
  twiWriteByte(0b01000000,0);             // TWI-Adresse
9
  twiWriteByte(0b00000110,0);             // Adressierung des Kommandoregister = Config 0
10
  twiWriteByte(0b00000000,0);             // ConfigDaten A = Ausgang
11
  twiWriteByte(0b00000000,0);             // ConfigDaten B = Ausgang
12
  twiStop();
13
}
14
15
// readPorts--------------------------------------------------------------------------------------------------------
16
//------------------------------------------------------------------------------------------------------------------
17
uint8_t readPorts(uint8_t port)
18
{
19
  twiStart();
20
  twiWriteByte(0b01000000,1);             // TWI-Adresse
21
  twiWriteByte(port,1);                 // Kommandoregister 0/1 -> Input P0/P1
22
  twiStart();
23
  twiWriteByte(0b01000001,1);             // TWI-Adresse und Read
24
  return twiReadByte(0);
25
}
26
27
// outPorts---------------------------------------------------------------------------------------------------------
28
//------------------------------------------------------------------------------------------------------------------
29
30
void outPorts(uint8_t port, uint8_t data)
31
{
32
  twiStart();
33
  twiWriteByte(0b01000000,1);             // TWI-Adresse
34
  twiWriteByte(0b00000010+port,1);           // Kommandoregister 2/3 -> Output P0/P1
35
  twiWriteByte(data,0);                 //
36
}
37
38
//------------------------------------------------------------------------------------------------------------------

von Karl H. (kbuchegg)


Lesenswert?

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.

von marcus6100 (Gast)


Lesenswert?

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!

von Sven W. (sickone4)


Lesenswert?

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.....

von Ralph (Gast)


Lesenswert?

Hier hilft nur der gute alte Ansatz RMW
Read - Modify - Write

also:

temp = readPorts(xx)

temp |= (1<<5);

temp &=~(1<<5);

outPorts(xx, temp)

von STK500-Besitzer (Gast)


Lesenswert?

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?

von Sven (Gast)


Lesenswert?

jap :)

von Karl H. (kbuchegg)


Lesenswert?

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.

von Sven (Gast)


Lesenswert?

gefällt mir :D

von Sven W. (sickone4)


Lesenswert?

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?

von STK500-Besitzer (Gast)


Lesenswert?

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"

von marcus6100 (Gast)


Lesenswert?

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]);
}

von STK500-Besitzer (Gast)


Lesenswert?

noch umständlich geht's wohl nicht, oder?

von marcus6100 (Gast)


Lesenswert?

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.

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
Noch kein Account? Hier anmelden.