mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Verwirrung beim Bitschreiben


Autor: C. We. (htbl)
Datum:

Bewertung
0 lesenswert
nicht 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:
//Das Unterprogramm:
void bit_write(int *var, int bit, int1 val) {
  if(val) var|=(1<<bit);
  else var&=~(1<<bit);
}

//Hauptprogramm:
void main() {
byte varible=0;
bit vke=TRUE;
byte select=0;

bit_write(variable,select,val);
printf("%x\r\n",variable); //Ausgabe: 00 (sollte jedoch 01 sein)
}

So funtioniert das UP jedoch:
//Das Unterprogramm:
int bit_write(int *var, int bit, int1 val) {
  if(val) var|=(1<<bit);
  else var&=~(1<<bit);
  return var;
}

//Hauptprogramm:
void main() {
byte varible=0;
bit vke=TRUE;
byte select=0;

variable=bit_write(variable,select,val);
printf("%x\r\n",variable); //Ausgabe: 01
}

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

Autor: Michael W. (noice)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: C. We. (htbl)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Michael W. (noice)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: C. We. (htbl)
Datum:

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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Michael W. (noice)
Datum:

Bewertung
0 lesenswert
nicht 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 = ...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.