Forum: Mikrocontroller und Digitale Elektronik PIC: Zusammenfassen von Portbits


von Vancouver (Gast)


Lesenswert?

Hallo,

vielleicht ist die Frage dumm und ich stehe einfach nur auf der Leitung. 
(Konkret geht es um einen PIC18F2550 und SDCC, aber ich vermute das 
spielt keine Rolle).

Man kann in C einen 8-Bit-Wert einfach auf einen PIC-Port schreiben, 
z.B. PORTb=42. Nun liegen aber auf B1 und B0 die SPI-Signale, und da 
SPI verwendet wird, müssen die unteren beiden Bits auf einem anderen 
Port ausgeben werden, z.B. C1 und C0.

Gibt es eine Möglichkeit, die Portbits B7...B2, C1 und C0 logisch zu 
einem Port zusammenzufassen, sodass man einfach z.B. mit MYPORT=42 den 
Wert rausschreiben kann? Sonst müsste man die Bits einzeln 
rausschreiben, das wäre wahrscheinlich recht mühsam.

Ich habe überlegt, die Bits in einer union zusammenzufassen, wie es in 
den PIC-Headerfiles gemacht wird. Aber die sind ja byteweise auf feste 
Portadressen gemappt, das hilft mir also nicht weiter.

Vielleicht habe ich es einfach übersehen, aber beim Drübergooglen habe 
ich keine Lösung gefunden.

von Frank K. (fchk)


Lesenswert?

Nein, eine solche Möglichkeit gibts nicht. Das sind immer zwei getrennte 
Zugriffe, bzw 4 (lesen, and, or, schreiben; und das zwei Mal)

Die eleganteste Lösung ist ein PIC mit PPS (Peripherial Port Select). Da 
kannst Du fast jede Peripherie auf fast jeden Pin legen. Das gibts aber 
hauptsächlich bei PIC24/dsPIC33.

fchk

von Stampede (Gast)


Lesenswert?

MYPORT als Inlinefunktion oder Macro schreiben, das das macht.

#define MYPORT(x) (LATA = (x & 0xFC), LATB = (x & 0x3))

oder so:

inline void MYPORT(BYTE x)
{
 LATA = (x & 0xFC);
 LATB = (x & 0x3);
}

Ist weder getestet noch weiß ich aus dem Kopf was man beim XC8 oder C18 
alsi inline Befehl nutzen muss.

von Noch einer (Gast)


Lesenswert?

>Ist weder getestet

Mal abgesehen vom shift, die Zuweisung setzt die restlichen Bits auf 0.

Ganz übel - anfangs klappt es, später nutzt man die anderen Bits für 
ganz andere Programmteile, und hat schon längst wieder vergessen, dass 
dieses Makro auch die anderen Pins verändert.

von fop (Gast)


Lesenswert?

Auch das geht. Wird halt ein wenig länger :
1
#define MYPORT(X) do{LATB = (LATB & 0x03) | (X & 0xFC); LATC = (LATC & 0xfc) | (X & 0x3);}while(0)

Also ich mag Makros ;-)

von Stampede (Gast)


Lesenswert?

>Mal abgesehen vom shift, die Zuweisung setzt die restlichen Bits auf 0.
>Ganz übel - anfangs klappt es, später nutzt man die anderen Bits für
>ganz andere Programmteile, und hat schon längst wieder vergessen, dass
>dieses Makro auch die anderen Pins verändert.
Es sollte ja nur prinzipiell verdeutlichem wie man das machen kann. Bei 
den SPI / I2C im PIC wäre das aber noch egal, da die Peripherie ohnehin 
die Kontrolle über die Ausgangsstufe übernimmt.
Nachdenken ist beim Schreiben der Makro immer notwendig, und das sollte 
man dem TE dann auch zumuten :)

von Noch einer (Gast)


Lesenswert?

Hab gehört, die neusten Compiler würden jetzt Inline-Funktionen 
unterstützen. Den Trick mit dem do/while würde man jetzt nur mehr für 
den obfuscated c contest brauchen :-)

von Vancouver (Gast)


Lesenswert?

Stampede schrieb:
> Nachdenken ist beim Schreiben der Makro immer notwendig, und das sollte
> man dem TE dann auch zumuten :)

Ich werde mich bemühen :-)

Der SDCC kann inlining, wenn man ihm --std-sdcc99 gibt, soweit ich weiß. 
Muss ich mal ausprobieren.

Das vollständige Schreiben aller 8 Bits auf Port C wären kein Problem, 
weil B1 und B0 als Eingänge konfiguriert werden. Bei Port C wird das 
schwieriger.

Jedenfalls Danke für Eure Antworten.

von Philipp Klaus K. (pkk)


Lesenswert?

Vancouver schrieb:

> Der SDCC kann inlining, wenn man ihm --std-sdcc99 gibt, soweit ich weiß.


Bis SDCC 3.4.0 war die Standardeinstellung --std-c89, in 3.5.0 war sie 
--std-c99, und in 3.6.0 wird sie --std-c11 sein.

Philipp

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.