Forum: Mikrocontroller und Digitale Elektronik Bitmanipulation einer unsingend int Variable


von Michael (Gast)


Lesenswert?

Hallo zusammen,

ich bin neu hier im Forum und Anfänger mit meinem PIC 18f458. Ich nutze 
den µC für meine Abschlussarbeit. Habe vorher durch meine Abendschule 
bedingt das ein oder andere in Assembler auf einem Atmel programmiert.

So nun nutze in, wie gesagt, einen PIC und programmiere in C. Nun habe 
ich folgendes Problem. Ich kommuniziere per SPI mit einem FPGA Board und 
übertrage Daten. Die SPI Routinen habe ich selbstgeschrieben, da ich mit 
dem implementierten Prog. nicht so ganz zurecht gekommen bin und ich 
ausserdem 16 Bit übertragen möchte.
So die 8 Bit übertragung läuft wunderbar. Ich habe eine spiOut 
Variable(unsigned int), die ich Bitweise auf einem Pin ausgebe (prüfe 
jedes Bit ob High oder Low und lege den entsprechenden Zustand auf einen 
Pin). Die spiIn Variable (unsigned int) weise ich den Zustand eines 
anderen Pins zu und schiffte diese. Wie gesagt mit 8 Bit läuft alles 
wunderbar. Sobald ich auf 16 Bit gehe funktioniert der Eingang immer 
noch, bloß mein Ausgang nicht mehr. Mit scheint es so, als ob meine 
"bit_test" Funktion bloß 8 Bit unterstützt und nicht 16 Bit. Im 
debugMode sehe ich das die Variable spiOut korrekt befüllt ist, aber 
eben nur bit 0 - 7 durch die bit_test Funktion "geprüft" werden.

Wie kann ich bei einer unsingend interger Zahl, die ja 2 Byte hat, die 
Bit 8 - 15 Ausgeben bzw. auf High oder Low prüfen. Für hilfe wäre ich 
dankbar...

Gruß
Michael

von Sven P. (Gast)


Lesenswert?

Michael schrieb:
> Wie kann ich bei einer unsingend interger Zahl, die ja 2 Byte hat,
Wo steht das geschrieben?

> die
> Bit 8 - 15 Ausgeben bzw. auf High oder Low prüfen. Für hilfe wäre ich
> dankbar...
Ohne Quelltext wird das leider nichts.

von R. W. (quakeman)


Lesenswert?

Michael schrieb:
> Wie kann ich bei einer unsingend interger Zahl, die ja 2 Byte hat, die
> Bit 8 - 15 Ausgeben bzw. auf High oder Low prüfen. Für hilfe wäre ich
> dankbar...

Also ohne Code ist es wirklich schwer dir zu sagen, was falsch läuft.
Aber wenn du die 16Bit einer Integer Variable ausgeben willst kannst du 
das Ganze problemlos mit einem Shift realisieren.

Beispiel welches mit dem LSB anfängt:

unsigned int input; // 16Bit Eingangsvariable
unsigned char i;    // Zähler
bit bt;             // Ausgabe Bit
for (i = 0; i < 16; i++) {
  // Prüfen ob niedrigstes Bit gesetzt oder nicht
  if (((input >> i) & 1) == 1)
    bt = 1;
  else
    bt = 0;
}

Je nach compiler kannst du die if-else Prüfung auch durch die einfachere 
Schreibweise "bt = (bit) (input >> i) & 1;" ersetzen.

von Michael (Gast)


Lesenswert?

Hallo,

hier ein Auszug aus meinem Quelltext:

int spiTxRx(int Output)            //meine spiRoutine
{
  unsigned int Input=0x0000;

loopSpi:
  if(!ss)                          //wenn SlaveSelect = 1
  {
    if(bit_test(Output,0)){spiOut=1;}else{spiOut=0;}  //spiOut = Bit 0 
von Output
    while(!spiClock);                  //warten bis Clock = 1
    Input = spiIn;                    //Inpit = spiIn
    Input = Input << 1;                  //Input 1 Bit nach links
    while(spiClock);                  //warten bis Clock = 0

    if(bit_test(Output,1)){spiOut=1;}else{spiOut=0;}
    while(!spiClock);
    Input = Input | spiIn;
    Input = Input << 1;
    while(spiClock);

    if(bit_test(Output,2)){spiOut=1;}else{spiOut=0;}
    while(!spiClock);
    Input = Input | spiIn;
    Input = Input << 1;
    while(spiClock);
.
.
.
Das ganze mach ich für 16 Bit. Ich nutze hier keine Schleife, da die 
Schleife (so denke ich, bitte korigiert mich wenn ich falsch liege) doch 
mehr Zeit in Anspruch nimmt???


Hier die Bitmanipulationsunktionen

#define bit_set(var,bitnr)     ((var) |= 1u << (bitnr))    //Bit setzen
#define bit_clr(var,bitnr)     ((var) &= ~(1u << (bitnr)))    //Bit 
löschen
#define bit_test(var,bitnr)    ((var) & (1u << (bitnr)))    //Bit 
Überprüfung


Ich nutze hier keine Schleife, da die Schleife (so denke ich, bitte 
korigiert mich wenn ich falsch liege) doch mehr Zeit in Anspruch 
nimmt???

von Michael (Gast)


Lesenswert?

Der letzte Satz sollte eigentlich gelöscht werden :)

Aber danke erstmal für eure Antworten...


Gruß
Michael

von Karl H. (kbuchegg)


Lesenswert?

Michael schrieb:
> Hallo,
>
> hier ein Auszug aus meinem Quelltext:

Und was ist jetzt deine Frage?


> Das ganze mach ich für 16 Bit. Ich nutze hier keine Schleife, da die
> Schleife (so denke ich, bitte korigiert mich wenn ich falsch liege) doch
> mehr Zeit in Anspruch nimmt???

Schau dir deinen Code genau an. An 2 Stellen wartest du, dass ein Pin 
seinen Zustand ändert. Warten! Und du machst dir Sorgen wegen dem 
bischen Overhead, den eine Schleife erzeugt?

von Michael (Gast)


Lesenswert?

Meine Frage besteht darin, dass nur die ersten 8 Bit übertragen werden 
(Output). Empfangen tu ich jedoch alle 16 Bit. So mit liegt mein 
verdacht darauf, dass die Bitmanipulationsfunktion nur 8 Bit 
unterstützen. Sobald ich das 9 Bit "teste" (sprich ob 0 oder 1) bekomme 
ich nur noch Lowsignale.

Das warten liegt im Sinne der Natur, da ich hier eine SPI Übertragun 
mache und ich auf den Clock angewiesen bin. Ich habe nur bedenken das 
durch die sprünge einer Schleife ich ein Clock verpasse und somit die 
ganze Übertragung ins stocken kommt...

Gruß
Michael

von Karl H. (kbuchegg)


Lesenswert?

Michael schrieb:
> Meine Frage besteht darin, dass nur die ersten 8 Bit übertragen werden
> (Output). Empfangen tu ich jedoch alle 16 Bit. So mit liegt mein
> verdacht darauf, dass die Bitmanipulationsfunktion nur 8 Bit
> unterstützen. Sobald ich das 9 Bit "teste" (sprich ob 0 oder 1) bekomme
> ich nur noch Lowsignale.

In dem gezeigten Code kann ich nichts derartiges erkennen.
Ev. gehen dir die oberen 8 Bit schon vor dem Aufruf der Funktion flöten?


> Das warten liegt im Sinne der Natur, da ich hier eine SPI Übertragun
> mache und ich auf den Clock angewiesen bin. Ich habe nur bedenken das
> durch die sprünge einer Schleife ich ein Clock verpasse und somit die
> ganze Übertragung ins stocken kommt...

Wenn du die Warterei anders rum einfügst, kannst du das Ganze so 
hindrehen, dass der komplette Schleifenoverhead dann gemacht wird, wenn 
sowieso gewartet werden muss. Ob dein µC jetzt in der Warteschleife 3 
Runden dreht oder ob er kurz eine Variable manipuliert und eine 
Endebedingung überprüft, wird ja wohl das Kraut nicht fett machen.
1
int spiTxRx(int Output)            //meine spiRoutine
2
{
3
  unsigned int Input=0x0000;
4
5
  if(!ss)                          //wenn SlaveSelect = 1
6
  {
7
    unsigned int mask;
8
9
    for( mask = 0x0001; mask; mask <<= 1 ) {
10
      while( spiClock );                  //warten bis Clock = 0
11
      spi_Out = ( ( Output & mask ) != 0 );
12
      while(!spiClock);                  //warten bis Clock = 1
13
      Input = spiIn;                     //Inpit = spiIn
14
      Input = Input << 1;                //Input 1 Bit nach links
15
    }
16
17
    ...

von Michael (Gast)


Lesenswert?

Laut dem debugMode ist die Variable korrekt bestückt, sprich es ist der 
richtige Wert hinterlegt. Hier meine komplette SPI Routine die ich im 
"main" aufrufe:
1
int spiTxRx(int Output)
2
{
3
  unsigned int Input=0x0000;
4
5
loopSpi:
6
  if(!ss)                          //wenn SlaveSelect = 1
7
  {      
8
    if(bit_test(Output,0)){spiOut=1;}else{spiOut=0;}  //spiOut = Bit 0 von Output
9
    while(!spiClock);                  //warten bis Clock = 1
10
    Input = spiIn;                    //Inpit = spiIn
11
    Input = Input << 1;                  //Input 1 Bit nach links
12
    while(spiClock);                  //warten bis Clock = 0
13
14
    if(bit_test(Output,1)){spiOut=1;}else{spiOut=0;}
15
    while(!spiClock);
16
    Input = Input | spiIn;
17
    Input = Input << 1;
18
    while(spiClock);
19
20
    if(bit_test(Output,2)){spiOut=1;}else{spiOut=0;}
21
    while(!spiClock);
22
    Input = Input | spiIn;
23
    Input = Input << 1;
24
    while(spiClock);
25
26
    if(bit_test(Output,3)){spiOut=1;}else{spiOut=0;}
27
    while(!spiClock);
28
    Input = Input | spiIn;
29
    Input = Input << 1;
30
    while(spiClock);
31
32
    if(bit_test(Output,4)){spiOut=1;}else{spiOut=0;}
33
    while(!spiClock);
34
    Input = Input | spiIn;
35
    Input = Input << 1;
36
    while(spiClock);
37
38
    if(bit_test(Output,5)){spiOut=1;}else{spiOut=0;}
39
    while(!spiClock);
40
    Input = Input | spiIn;
41
    Input = Input << 1;
42
    while(spiClock);
43
44
    if(bit_test(Output,6)){spiOut=1;}else{spiOut=0;}
45
    while(!spiClock);
46
    Input = Input | spiIn;
47
    Input = Input << 1;
48
    while(spiClock);
49
50
    if(bit_test(Output,7)){spiOut=1;}else{spiOut=0;}
51
    while(!spiClock);
52
    Input = Input | spiIn;
53
    Input = Input << 1;
54
    while(spiClock);
55
56
    if(bit_test(Output,8)){spiOut=1;}else{spiOut=0;}
57
    while(!spiClock);
58
    Input = Input | spiIn;
59
    Input = Input << 1;
60
    while(spiClock);
61
62
    if(bit_test(Output,9)){spiOut=1;}else{spiOut=0;}
63
    while(!spiClock);
64
    Input = Input | spiIn;
65
    Input = Input << 1;
66
    while(spiClock);
67
68
    if(bit_test(Output,10)){spiOut=1;}else{spiOut=0;}
69
    while(!spiClock);
70
    Input = Input | spiIn;
71
    Input = Input << 1;
72
    while(spiClock);
73
74
    if(bit_test(Output,11)){spiOut=1;}else{spiOut=0;}
75
    while(!spiClock);
76
    Input = Input | spiIn;
77
    Input = Input << 1;
78
    while(spiClock);
79
80
    if(bit_test(Output,12)){spiOut=1;}else{spiOut=0;}
81
    while(!spiClock);
82
    Input = Input | spiIn;
83
    Input = Input << 1;
84
    while(spiClock);
85
86
    if(bit_test(Output,13)){spiOut=1;}else{spiOut=0;}
87
    while(!spiClock);
88
    Input = Input | spiIn;
89
    Input = Input << 1;
90
    while(spiClock);
91
92
    if(bit_test(Output,14)){spiOut=1;}else{spiOut=0;}
93
    while(!spiClock);
94
    Input = Input | spiIn;
95
    Input = Input << 1;
96
    while(spiClock);
97
98
    if(bit_test(Output,15)){spiOut=1;}else{spiOut=0;}
99
    while(!spiClock);
100
    Input = Input | spiIn;
101
    while(spiClock);
102
  
103
    while(ss);                      //warten auf SS = 0
104
  }
105
  else
106
  {
107
  goto loopSpi;                      //ss = 0 goto loopSpi
108
  }  
109
    
110
  return(Input);
111
}

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.