www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Bitmanipulation einer unsingend int Variable


Autor: Michael (Gast)
Datum:

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

Autor: Sven P. (haku) Benutzerseite
Datum:

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

Autor: R. W. (quakeman)
Datum:

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

Autor: Michael (Gast)
Datum:

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

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der letzte Satz sollte eigentlich gelöscht werden :)

Aber danke erstmal für eure Antworten...


Gruß
Michael

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Michael (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.
int spiTxRx(int Output)            //meine spiRoutine
{
  unsigned int Input=0x0000;

  if(!ss)                          //wenn SlaveSelect = 1
  {
    unsigned int mask;

    for( mask = 0x0001; mask; mask <<= 1 ) {
      while( spiClock );                  //warten bis Clock = 0
      spi_Out = ( ( Output & mask ) != 0 );
      while(!spiClock);                  //warten bis Clock = 1
      Input = spiIn;                     //Inpit = spiIn
      Input = Input << 1;                //Input 1 Bit nach links
    }

    ...

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
int spiTxRx(int Output)
{
  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);

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

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

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

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

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

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

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

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

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

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

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

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

    if(bit_test(Output,15)){spiOut=1;}else{spiOut=0;}
    while(!spiClock);
    Input = Input | spiIn;
    while(spiClock);
  
    while(ss);                      //warten auf SS = 0
  }
  else
  {
  goto loopSpi;                      //ss = 0 goto loopSpi
  }  
    
  return(Input);
}

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.