Forum: Mikrocontroller und Digitale Elektronik Verwirrung beim Bitschreiben


von C. W. (htbl)


Lesenswert?

Hallo!

Ich hab ein kleines Problem beim Schreiben eines Bits mit einem 
Unterprogramm, welches ich mir nicht erklären kann.

Ich wollte mir ein UP schreiben, welches mir in einer Variable ein 
bestimmtes Bit entweder auf 0 oder 1 setzt.
So sah dieses Prog. aus:
1
//Das Unterprogramm:
2
void bit_write(int *var, int bit, int1 val) {
3
  if(val) var|=(1<<bit);
4
  else var&=~(1<<bit);
5
}
6
7
//Hauptprogramm:
8
void main() {
9
byte varible=0;
10
bit vke=TRUE;
11
byte select=0;
12
13
bit_write(variable,select,val);
14
printf("%x\r\n",variable); //Ausgabe: 00 (sollte jedoch 01 sein)
15
}

So funtioniert das UP jedoch:
1
//Das Unterprogramm:
2
int bit_write(int *var, int bit, int1 val) {
3
  if(val) var|=(1<<bit);
4
  else var&=~(1<<bit);
5
  return var;
6
}
7
8
//Hauptprogramm:
9
void main() {
10
byte varible=0;
11
bit vke=TRUE;
12
byte select=0;
13
14
variable=bit_write(variable,select,val);
15
printf("%x\r\n",variable); //Ausgabe: 01
16
}

Könnt ihr mir das erklären?
(Achja, ich benutze den CCS-Compiler und den PIC18F8722.)

von Michael W. (noice)


Lesenswert?

Das obere Programm würde schon funktionieren, wenn Du die "variable" als 
Zeiger übergeben würdest, wie es bit_write() erwartet:

bit_write(&variable,select,val);

Das obere Programm macht im Augenblick, was du ihm sagst: schreibe den 
Wert in Speicherzelle 0 (da variable=0). Abgesehen davon, daß sowas ins 
Auge gehen kann, liest du im weiteren Verlauf des Programms gar nicht 
mehr aus dieser Speicherzelle.

von C. W. (htbl)


Lesenswert?

Stimmt ja.
Im HP muss ich die Adresse übergeben und im UP mit *var arbeiten.

Der CCS-Compiler ist ein wenig verwirren. Mit Feldern funktioniert das 
so wie im oberen Programm.

von Stefan E. (sternst)


Lesenswert?

> Das obere Programm würde schon funktionieren, wenn Du die "variable" als
> Zeiger übergeben würdest, wie es bit_write() erwartet:

Nein, würde auch nicht funktionieren.
Das grundlegende Problem ist, dass er in bit_write das Bit im Zeiger 
verändert, und nicht im Wert, auf den er zeigt.

von Michael W. (noice)


Lesenswert?

Das hat mit dem konkreten Compiler nichts zu tun; mit einem Array 
funktioniert es, weil der Variablenwert eines Feldes bereits ein Zeiger 
(auf den ersten Wert des Feldes) ist.

von C. W. (htbl)


Lesenswert?

Warum muss man dann bei schon vom Kompiler vordefinierten Funktionen, 
wie z.B. BIT_SET(var,bit), diese Funktionen nicht mit &var aufrufen?

von Stefan E. (sternst)


Lesenswert?

C. We. wrote:
> Warum muss man dann bei schon vom Kompiler vordefinierten Funktionen,
> wie z.B. BIT_SET(var,bit), diese Funktionen nicht mit &var aufrufen?

Weil das keine Funktionen sind, sondern Makros.
Und sie werden auch nicht vom Compiler definiert, sondern von der libc.

von Michael W. (noice)


Lesenswert?

Das ist schätzungsweise keine Funktion, sondern ein Makro. Makros werden 
durch Code ersetzt, also z.B.

#define ADD(var1,var2) ( var1 += var2 )
ADD(x,5);
ADD(x,7);

Vor der Übersetzung macht der Compiler daraus:

(x += 5);
(x += 7);

Es ist also nicht nötig, eine Referenz zu übergeben und dennoch wird der 
Wert der Variablen verändert. Auch wenn es so ausschaut wie ein 
Funktionsaufruf. Wäre es eine Funktion:

void ADD(int var1, int var2)
{
   var1 += var2;
}
...
ADD(x,5);

So würde das nicht wie gewollt funktionieren, da nur var1 verändert 
wird, aber nicht x.


Der Einwurf von Stefan ist natürlich korrekt: in bit_write muss man var 
erst dereferenzieren: *var = ...

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.