Forum: Mikrocontroller und Digitale Elektronik Bitmanipulation


von P. F. (pfuhsy)


Lesenswert?

Hallo zusammen,

ich benutze zum RFM12 konfiguieren, als Beispiel, folgende Code-Zeile:
1
RFM_cmd_empf(0x8280);  //Power Management

Die dazugehörige Funktion sieht so aus:
1
unsigned int RFM_cmd_empf(uint16_t aCmd)//Software-Lösung für MOSI/MISO als Empänger
2
{
3
  unsigned char i;
4
  unsigned int temp;
5
  
6
  temp=0;
7
  Low_Sck();
8
  Low_Sel();
9
  
10
  for(i=0;i<16;i++)
11
  {
12
    if(aCmd&0x8000)
13
    {
14
      Hi_Sdi();
15
    }
16
    else
17
    {
18
      Low_Sdi();
19
    }
20
    
21
    Hi_Sck();
22
    temp<<=1;
23
    
24
    if(Sdo_ist_Hi())
25
    {
26
      temp|=0x0001;
27
    }
28
    
29
    Low_Sck();
30
    aCmd<<=1;
31
  };
32
  
33
  Hi_Sel();
34
  return(temp);
35
}

Soweit so gut.
Jetzt hab ich mir gedacht, da die o.g. Code-Zeile direkt das Ganze Byte 
anspricht, wäre es doch kleverer nur das Bit zu minpulieren, welches 
gerade auch wirklich notwenig ist. Also hab ich in der Header und 
C-Datei des RFM12 folgendes eingebaut.

rfm12.h:
1
//(Power Management 82xx) Einzelbit-Konfiguration / -Abfrage
2
extern uint16_t PWRM;  //Adressierbereich, in *.c deklaiert
3
#define ER      7  //enable receiver
4
#define EBB      6  //enable baseband
5
#define ET      5  //enable transmitter
6
#define ES      4  //enable synthesizer
7
#define EX      3  //enable xtal(Quarz)
8
#define EB      2  //enable brownout
9
#define EW      1  //enable wakeup
10
#define DC      0  //disable clock

rfm12.c:
1
//--------------------------Initialisierung-----------------------------
2
uint16_t PWRM     = 0x8200;    //Adresszuweisung (Power Management 82xx)
3
4
void RFM_Empf_Ein()          //Empfänger einschalten
5
{
6
  RFM_cmd_empf(PWRM |=  (1<<ER));  //Empfänger einschalten
7
  _delay_ms(1);          //Warten bis Empfänger an ist
8
  RFM_Fifo_Reset();        //Fifo reseten
9
}

Ersetzte ich jetzt die o.g. Zeile:
1
RFM_cmd_empf(0x8280);

durch den Funktionsaufruf:
1
RFM_Empf_Ein();

...funkioniert der ganze spass nicht mehr.
Wo ist mein Denkfehler, in der Simluation sieht das alles ganz gut aus ? 
Vorher "8280" und danach "8200" wie es sein soll.

von Tappo (Gast)


Lesenswert?

Peter F. schrieb:
> RFM_cmd_empf(PWRM |=  (1<<ER));

lass das | weg

RFM_cmd_empf(PWRM |  (1<<ER));

von Tappo (Gast)


Lesenswert?

natürlci = weg, sorry

von P. F. (pfuhsy)


Lesenswert?

Tappo schrieb:
> natürlci = weg, sorry

Warum denn ?
Bei der Bitmanipulation der Ports funktioniert das doch auch so.
Z.B.:
1
DDRB |= (1<<PB1);

von Sascha W. (sascha-w)


Lesenswert?

So wie du das geschieben hast wird die Funktion mit PWRM als Parameter 
aufgerufen, und anschließend das entsprechende Bit in PWRM gesetzt.
Vergleiche:
foo(var++)
ruft die Funktion mit var auf und erhöht selbige im Anschluss.

Sascha

von P. F. (pfuhsy)


Lesenswert?

Ich verstehe das nicht so recht. PWRM ist doch keine Funktion. PWRM ist 
eien Variable 16 Bits, ich versuche beispielsweise NUR Bit 7 zu 
verändern.

von Sascha W. (sascha-w)


Lesenswert?

ja, aber mit dem = weist du der Variable PWRM einen neuen Wert zu, das 
passiert aber erst nachdem deine Funktion RFM_cmd_empf zuvor mit dem 
alten Wert von PWRM aufgerufen wurde.

Sascha

von P. F. (pfuhsy)


Angehängte Dateien:

Lesenswert?

Sascha W. schrieb:
> ja, aber mit dem = weist du der Variable PWRM einen neuen Wert zu, das
> passiert aber erst nachdem deine Funktion RFM_cmd_empf zuvor mit dem
> alten Wert von PWRM aufgerufen wurde.
>
> Sascha

Ich kann das nciht so ganz nachvollziehen.
In der Simulation übernimmt er nur dann den Wert, wenn die Schreibweise 
die meinige ist. Er addiert genau den Bit dazu den ich manipulieren 
will. Steht dort vorher 8200, wird 8280 draus, Bild 1. Steht dort vorher 
8201, wird 8281 draus. Und den Wert übernimmt er beim Aufruf der 
Funktion auch korrekt, Bild2.

Wenn ich das "=" rauslasse passiert gar nichts, Bild3.

von vorher (Gast)


Lesenswert?

Sascha W. schrieb:
> passiert aber erst nachdem deine Funktion RFM_cmd_empf zuvor mit dem
> alten Wert von PWRM aufgerufen wurde.

Nein. Das passiert vor dem Funktionsaufruf.

von Walter S. (avatar)


Lesenswert?

warum nicht so:
PWRM |=  (1<<ER);
RFM_cmd_empf(PWRM);  //Empfänger einschalten

wenn du PWRM verändern willst oder wie empfohlen:
RFM_cmd_empf(PWRM |  (1<<ER));

: Bearbeitet durch User
von Tappo (Gast)


Lesenswert?

Dann schreibe einfach so und gut jetzt.

//--------------------------Initialisierung-----------------------------
uint16_t PWRM     = 0x8200;    //Adresszuweisung (Power Management 82xx)

void RFM_Empf_Ein()          //Empfänger einschalten
{
  PWRM |=  (1<<ER);
  RFM_cmd_empf(PWRM);  //Empfänger einschalten
  _delay_ms(1);          //Warten bis Empfänger an ist
  RFM_Fifo_Reset();        //Fifo reseten
}

von Walter S. (avatar)


Lesenswert?

Peter F. schrieb:
> Wenn ich das "=" rauslasse passiert gar nichts, Bild3.

steppe mal in die Funktion, dann  wirst du sehen dass der Parameter 
richtig ist

von P. F. (pfuhsy)


Lesenswert?

Walter S. schrieb:
> Peter F. schrieb:
>> Wenn ich das "=" rauslasse passiert gar nichts, Bild3.
>
> steppe mal in die Funktion, dann  wirst du sehen dass der Parameter
> richtig ist

Stimmt.

Tappo schrieb:
> void RFM_Empf_Ein()          //Empfänger einschalten
> {
>   PWRM |=  (1<<ER);
>   RFM_cmd_empf(PWRM);  //Empfänger einschalten
>   _delay_ms(1);          //Warten bis Empfänger an ist
>   RFM_Fifo_Reset();        //Fifo reseten
> }

Diese Variante auch funktioniert nicht.

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.